Implement support for For loops.
Bug swiftshader:13
Change-Id: I054d0521ecbb1959c5c19b6fa54f76707f4e49c9
Reviewed-on: https://swiftshader-review.googlesource.com/7358
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/Main.cpp b/src/Reactor/Main.cpp
index 0e2e739..ff26a1a 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -30,6 +30,11 @@
Int y = function.Arg<1>();
Int z = 4;
+ For(Int i = 0, i < 10, i++)
+ {
+ z += 2;
+ }
+
Int sum = x + y + z;
Return(sum);
@@ -42,7 +47,7 @@
int (*add)(int*, int) = (int(*)(int*,int))routine->getEntry();
int one = 1;
int result = add(&one, 2);
- assert(result == 7);
+ assert(result == 27);
}
}
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 594f748..7a427d1 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -76,6 +76,11 @@
return reinterpret_cast<Constant*>(c);
}
+ BasicBlock *B(Ice::CfgNode *b)
+ {
+ return reinterpret_cast<BasicBlock*>(b);
+ }
+
Optimization optimization[10] = {InstructionCombining, Disabled};
void *loadImage(uint8_t *const elfImage)
@@ -273,18 +278,18 @@
BasicBlock *Nucleus::createBasicBlock()
{
- assert(false && "UNIMPLEMENTED"); return nullptr;
+ return B(::function->makeNode());
}
BasicBlock *Nucleus::getInsertBlock()
{
- assert(false && "UNIMPLEMENTED"); return nullptr;
+ return B(::basicBlock);
}
void Nucleus::setInsertBlock(BasicBlock *basicBlock)
{
- assert(!basicBlock->getInsts().back().getTerminatorEdges().empty() && "Previous basic block must have a terminator");
- assert(false && "UNIMPLEMENTED"); return;
+ assert(::basicBlock->getInsts().back().getTerminatorEdges().size() >= 0 && "Previous basic block must have a terminator");
+ ::basicBlock = basicBlock;
}
BasicBlock *Nucleus::getPredecessor(BasicBlock *basicBlock)
@@ -326,12 +331,14 @@
void Nucleus::createBr(BasicBlock *dest)
{
- assert(false && "UNIMPLEMENTED");
+ auto br = Ice::InstBr::create(::function, dest);
+ ::basicBlock->appendInst(br);
}
void Nucleus::createCondBr(Value *cond, BasicBlock *ifTrue, BasicBlock *ifFalse)
{
- assert(false && "UNIMPLEMENTED");
+ auto br = Ice::InstBr::create(::function, cond, ifTrue, ifFalse);
+ ::basicBlock->appendInst(br);
}
Value *Nucleus::createAdd(Value *lhs, Value *rhs)
@@ -585,7 +592,13 @@
Value *Nucleus::createICmpSLT(Value *lhs, Value *rhs)
{
- assert(false && "UNIMPLEMENTED"); return nullptr;
+ assert(lhs->getType() == rhs->getType());
+
+ auto result = ::function->makeVariable(Ice::IceType_i1);
+ auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Slt, result, lhs, rhs);
+ ::basicBlock->appendInst(cmp);
+
+ return V(result);
}
Value *Nucleus::createICmpSLE(Value *lhs, Value *rhs)
@@ -3406,7 +3419,13 @@
RValue<Int> operator++(const Int &val, int) // Post-increment
{
- assert(false && "UNIMPLEMENTED"); return RValue<Int>(V(nullptr));
+ auto oldValue = val.loadValue();
+ auto newValue = ::function->makeVariable(Ice::IceType_i32);
+ auto inc = Ice::InstArithmetic::create(::function, Ice::InstArithmetic::Add, newValue, oldValue, ::context->getConstantInt32(1));
+ ::basicBlock->appendInst(inc);
+ val.storeValue(V(newValue));
+
+ return RValue<Int>(oldValue);
}
const Int &operator++(const Int &val) // Pre-increment