From d74cc6397b4d019662f5e42b88776a4d381c32e3 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Mon, 19 Mar 2012 15:06:35 -0700 Subject: [PATCH] Fix significant bug in mask management in code generated for 'foreach'. In particular, we 1. weren't setting the function mask to 'all on', such that any mixed function mask would in turn apply inside the foreach loop, and 2. weren't always setting the internal mask to 'all on' before doing any additional masking based on the iteration variables. --- stmt.cpp | 6 ++++++ tests/foreach-mask-1.ispc | 21 +++++++++++++++++++++ tests/foreach-mask.ispc | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 tests/foreach-mask-1.ispc create mode 100644 tests/foreach-mask.ispc diff --git a/stmt.cpp b/stmt.cpp index c8293b5c..a9905096 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -1336,10 +1336,14 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const { llvm::BasicBlock *bbExit = ctx->CreateBasicBlock("foreach_exit"); llvm::Value *oldMask = ctx->GetInternalMask(); + llvm::Value *oldFunctionMask = ctx->GetFunctionMask(); ctx->SetDebugPos(pos); ctx->StartScope(); + ctx->SetInternalMask(LLVMMaskAllOn); + ctx->SetFunctionMask(LLVMMaskAllOn); + // This should be caught during typechecking Assert(startExprs.size() == dimVariables.size() && endExprs.size() == dimVariables.size()); @@ -1765,7 +1769,9 @@ ForeachStmt::EmitCode(FunctionEmitContext *ctx) const { /////////////////////////////////////////////////////////////////////////// // foreach_exit: All done. Restore the old mask and clean up ctx->SetCurrentBasicBlock(bbExit); + ctx->SetInternalMask(oldMask); + ctx->SetFunctionMask(oldFunctionMask); ctx->EndForeach(); ctx->EndScope(); diff --git a/tests/foreach-mask-1.ispc b/tests/foreach-mask-1.ispc new file mode 100644 index 00000000..2f462b48 --- /dev/null +++ b/tests/foreach-mask-1.ispc @@ -0,0 +1,21 @@ + +export uniform int width() { return programCount; } + + + +export void f_f(uniform float RET[], uniform float aFOO[]) { + uniform float val[programCount+3]; + for (uniform int i = 0; i < programCount+3; ++i) + val[i] = 0; + + // make sure we reset the func mask in the foreach loop... + if ((int)aFOO[programIndex] & 1) + foreach (i = 0 ... programCount+3) + val[i] += aFOO[i] - 1; + + RET[programIndex] = val[3+programIndex]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = programIndex+3; +} diff --git a/tests/foreach-mask.ispc b/tests/foreach-mask.ispc new file mode 100644 index 00000000..0d01b16a --- /dev/null +++ b/tests/foreach-mask.ispc @@ -0,0 +1,25 @@ + +export uniform int width() { return programCount; } + + +// make sure we reset the func mask in the foreach loop... + +void update(uniform float val[], const uniform float a[]) { + foreach (i = 0 ... programCount+3) + val[i] += a[i] - 1; +} + +export void f_f(uniform float RET[], uniform float aFOO[]) { + uniform float val[programCount+3]; + for (uniform int i = 0; i < programCount+3; ++i) + val[i] = 0; + + if ((int)aFOO[programIndex] & 1) + update(val, aFOO); + + RET[programIndex] = val[3+programIndex]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = programIndex+3; +}