Fix bugs with handling of 'continue' statements in foreach_* loops.
This commit is contained in:
6
ctx.cpp
6
ctx.cpp
@@ -830,13 +830,9 @@ FunctionEmitContext::jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target) {
|
||||
llvm::Value *allDone = NULL;
|
||||
|
||||
if (breakLanesPtr == NULL) {
|
||||
// In a foreach loop, break and return are illegal, and
|
||||
// breakLanesPtr is NULL. In this case, the mask is guaranteed to
|
||||
// be all on at the start of each iteration, so we only need to
|
||||
// check if all lanes have continued..
|
||||
llvm::Value *continued = LoadInst(continueLanesPtr,
|
||||
"continue_lanes");
|
||||
allDone = All(continued);
|
||||
allDone = MasksAllEqual(continued, blockEntryMask);
|
||||
}
|
||||
else {
|
||||
// Check to see if (returned lanes | continued lanes | break lanes) is
|
||||
|
||||
11
stmt.cpp
11
stmt.cpp
@@ -1659,8 +1659,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
varyingCounter, smearEnd);
|
||||
emask = ctx->I1VecToBoolVec(emask);
|
||||
|
||||
if (nDims == 1)
|
||||
if (nDims == 1) {
|
||||
ctx->SetInternalMask(emask);
|
||||
}
|
||||
else {
|
||||
llvm::Value *oldMask = ctx->LoadInst(extrasMaskPtrs[nDims-2]);
|
||||
llvm::Value *newMask =
|
||||
@@ -1706,6 +1707,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->CreateBasicBlock("foreach_full_continue");
|
||||
ctx->SetCurrentBasicBlock(bbFullBody); {
|
||||
ctx->SetInternalMask(LLVMMaskAllOn);
|
||||
ctx->SetBlockEntryMask(LLVMMaskAllOn);
|
||||
lUpdateVaryingCounter(nDims-1, nDims, ctx, uniformCounterPtrs[nDims-1],
|
||||
dimVariables[nDims-1]->storagePtr, span);
|
||||
ctx->SetContinueTarget(bbFullBodyContinue);
|
||||
@@ -1753,6 +1755,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
varyingCounter, smearEnd);
|
||||
emask = ctx->I1VecToBoolVec(emask);
|
||||
ctx->SetInternalMask(emask);
|
||||
ctx->SetBlockEntryMask(emask);
|
||||
|
||||
ctx->StoreInst(LLVMFalse, stepIndexAfterMaskedBodyPtr);
|
||||
ctx->BranchInst(bbMaskedBody);
|
||||
@@ -1772,6 +1775,7 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
ctx->AddInstrumentationPoint("foreach loop body (masked)");
|
||||
ctx->SetContinueTarget(bbMaskedBodyContinue);
|
||||
ctx->DisableGatherScatterWarnings();
|
||||
ctx->SetBlockEntryMask(ctx->GetFullMask());
|
||||
stmts->EmitCode(ctx);
|
||||
ctx->EnableGatherScatterWarnings();
|
||||
ctx->BranchInst(bbMaskedBodyContinue);
|
||||
@@ -2014,6 +2018,9 @@ ForeachActiveStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
ctx->SetCurrentBasicBlock(bbBody); {
|
||||
ctx->RestoreContinuedLanes();
|
||||
ctx->SetBlockEntryMask(ctx->GetFullMask());
|
||||
|
||||
// Run the code in the body of the loop. This is easy now.
|
||||
if (stmts)
|
||||
stmts->EmitCode(ctx);
|
||||
@@ -2226,6 +2233,8 @@ ForeachUniqueStmt::EmitCode(FunctionEmitContext *ctx) const {
|
||||
}
|
||||
|
||||
ctx->SetCurrentBasicBlock(bbBody); {
|
||||
ctx->RestoreContinuedLanes();
|
||||
ctx->SetBlockEntryMask(ctx->GetFullMask());
|
||||
// Run the code in the body of the loop. This is easy now.
|
||||
if (stmts)
|
||||
stmts->EmitCode(ctx);
|
||||
|
||||
16
tests/foreach-unique-8.ispc
Normal file
16
tests/foreach-unique-8.ispc
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
export uniform int width() { return programCount; }
|
||||
|
||||
export void f_f(uniform float RET[], uniform float aFOO[]) {
|
||||
uniform int k = 0;
|
||||
int index = aFOO[programIndex/2];
|
||||
foreach_unique(j in index) {
|
||||
if (j & 1) continue;
|
||||
++k;
|
||||
}
|
||||
RET[programIndex] = k;
|
||||
}
|
||||
|
||||
export void result(uniform float RET[]) {
|
||||
RET[programIndex] = programCount / 4;
|
||||
}
|
||||
Reference in New Issue
Block a user