Fix bugs with handling of 'continue' statements in foreach_* loops.

This commit is contained in:
Matt Pharr
2012-09-05 10:16:58 -07:00
parent 63b8fac852
commit ddcd0a49ec
3 changed files with 27 additions and 6 deletions

View File

@@ -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

View File

@@ -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);

View 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;
}