Limit loop init scope to till end of loop.
Bug swiftshader:13
Change-Id: I03cdbb3e5ea28643eb941e162125da68d183d1c6
Reviewed-on: https://swiftshader-review.googlesource.com/7810
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-on: https://swiftshader-review.googlesource.com/8144
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 8204697..7900063 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -6718,16 +6718,6 @@
Nucleus::createUnreachable();
}
- BasicBlock *beginLoop()
- {
- BasicBlock *loopBB = Nucleus::createBasicBlock();
-
- Nucleus::createBr(loopBB);
- Nucleus::setInsertBlock(loopBB);
-
- return loopBB;
- }
-
bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
{
Nucleus::createCondBr(cmp.value, bodyBB, endBB);
diff --git a/src/Reactor/Main.cpp b/src/Reactor/Main.cpp
index 092bf9e..e4e884e 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -290,11 +290,18 @@
x += 10000;
}
- For(Int j = 0, j < 2, j++)
- If(x == 402222)
- {
- If(x != 402222)
+ For(Int i = 0, i < 10, i++)
+ for(int i = 0; i < 10; i++)
+ For(Int i = 0, i < 10, i++)
+ {
x += 1000000;
+ }
+
+ For(Int i = 0, i < 2, i++)
+ If(x == 1000402222)
+ {
+ If(x != 1000402222)
+ x += 1000000000;
}
Else
x = -5;
@@ -309,7 +316,7 @@
int(*callable)() = (int(*)())routine->getEntry();
int result = callable();
- EXPECT_EQ(result, 402222);
+ EXPECT_EQ(result, 1000402222);
}
}
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 7239e47..30bd0f0 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -2225,7 +2225,60 @@
// RValue<Array<T>> operator--(const Array<T> &val, int); // Post-decrement
// const Array<T> &operator--(const Array<T> &val); // Pre-decrement
- BasicBlock *beginLoop();
+ struct Loop
+ {
+ Loop(bool init) : loopOnce(init)
+ {
+ }
+
+ operator bool()
+ {
+ return loopOnce;
+ }
+
+ bool operator=(bool value)
+ {
+ return loopOnce = value;
+ }
+
+ bool setup()
+ {
+ if(Nucleus::getInsertBlock() != endBB)
+ {
+ testBB = Nucleus::createBasicBlock();
+
+ Nucleus::createBr(testBB);
+ Nucleus::setInsertBlock(testBB);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool test(RValue<Bool> cmp)
+ {
+ BasicBlock *bodyBB = Nucleus::createBasicBlock();
+ endBB = Nucleus::createBasicBlock();
+
+ Nucleus::createCondBr(cmp.value, bodyBB, endBB);
+ Nucleus::setInsertBlock(bodyBB);
+
+ return true;
+ }
+
+ void end()
+ {
+ Nucleus::createBr(testBB);
+ Nucleus::setInsertBlock(endBB);
+ }
+
+ private:
+ BasicBlock *testBB = nullptr;
+ BasicBlock *endBB = nullptr;
+ bool loopOnce = true;
+ };
+
bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB);
void endIf(BasicBlock *falseBB);
bool elseBlock(BasicBlock *falseBB);
@@ -2817,27 +2870,24 @@
return ReinterpretCast<T>(val);
}
- #define For(init, cond, inc) \
- init; \
- for(BasicBlock *loopBB__ = beginLoop(), \
- *bodyBB__ = Nucleus::createBasicBlock(), \
- *endBB__ = Nucleus::createBasicBlock(), \
- *onceBB__ = endBB__; \
- onceBB__ && branch(cond, bodyBB__, endBB__); \
- inc, onceBB__ = 0, Nucleus::createBr(loopBB__), Nucleus::setInsertBlock(endBB__))
+ extern BasicBlock *falseBB__;
- #define While(cond) For(((void*)0), cond, ((void*)0))
+ #define For(init, cond, inc) \
+ for(Loop loop__ = true; loop__; loop__ = false) \
+ for(init; loop__.setup() && loop__.test(cond); inc, loop__.end())
- #define Do \
- { \
- BasicBlock *body = Nucleus::createBasicBlock(); \
- Nucleus::createBr(body); \
- Nucleus::setInsertBlock(body);
+ #define While(cond) For((void)0, cond, (void)0)
- #define Until(cond) \
- BasicBlock *end = Nucleus::createBasicBlock(); \
- Nucleus::createCondBr((cond).value, end, body); \
- Nucleus::setInsertBlock(end); \
+ #define Do \
+ { \
+ BasicBlock *body__ = Nucleus::createBasicBlock(); \
+ Nucleus::createBr(body__); \
+ Nucleus::setInsertBlock(body__);
+
+ #define Until(cond) \
+ BasicBlock *end__ = Nucleus::createBasicBlock(); \
+ Nucleus::createCondBr((cond).value, end__, body__); \
+ Nucleus::setInsertBlock(end__); \
}
#define If(cond) \
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 4ae6dfa..48ee54d 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -6147,16 +6147,6 @@
Nucleus::createUnreachable();
}
- BasicBlock *beginLoop()
- {
- BasicBlock *loopBB = Nucleus::createBasicBlock();
-
- Nucleus::createBr(loopBB);
- Nucleus::setInsertBlock(loopBB);
-
- return loopBB;
- }
-
bool branch(RValue<Bool> cmp, BasicBlock *bodyBB, BasicBlock *endBB)
{
Nucleus::createCondBr(cmp.value, bodyBB, endBB);