Merge pull request #856 from jbrodman/master
Fix issue where break stmts would in executing with mask all off.
This commit is contained in:
13
ctx.cpp
13
ctx.cpp
@@ -741,6 +741,7 @@ FunctionEmitContext::Break(bool doCoherenceCheck) {
|
|||||||
// that have executed a 'break' statement:
|
// that have executed a 'break' statement:
|
||||||
// breakLanes = breakLanes | mask
|
// breakLanes = breakLanes | mask
|
||||||
AssertPos(currentPos, breakLanesPtr != NULL);
|
AssertPos(currentPos, breakLanesPtr != NULL);
|
||||||
|
|
||||||
llvm::Value *mask = GetInternalMask();
|
llvm::Value *mask = GetInternalMask();
|
||||||
llvm::Value *breakMask = LoadInst(breakLanesPtr,
|
llvm::Value *breakMask = LoadInst(breakLanesPtr,
|
||||||
"break_mask");
|
"break_mask");
|
||||||
@@ -879,7 +880,7 @@ FunctionEmitContext::jumpIfAllLoopLanesAreDone(llvm::BasicBlock *target) {
|
|||||||
finishedLanes = BinaryOperator(llvm::Instruction::Or, finishedLanes,
|
finishedLanes = BinaryOperator(llvm::Instruction::Or, finishedLanes,
|
||||||
continued, "returned|breaked|continued");
|
continued, "returned|breaked|continued");
|
||||||
}
|
}
|
||||||
|
|
||||||
finishedLanes = BinaryOperator(llvm::Instruction::And,
|
finishedLanes = BinaryOperator(llvm::Instruction::And,
|
||||||
finishedLanes, GetFunctionMask(),
|
finishedLanes, GetFunctionMask(),
|
||||||
"finished&func");
|
"finished&func");
|
||||||
@@ -923,6 +924,16 @@ FunctionEmitContext::RestoreContinuedLanes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FunctionEmitContext::ClearBreakLanes() {
|
||||||
|
if (breakLanesPtr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// breakLanes = 0
|
||||||
|
StoreInst(LLVMMaskAllOff, breakLanesPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FunctionEmitContext::StartSwitch(bool cfIsUniform, llvm::BasicBlock *bbBreak) {
|
FunctionEmitContext::StartSwitch(bool cfIsUniform, llvm::BasicBlock *bbBreak) {
|
||||||
llvm::Value *oldMask = GetInternalMask();
|
llvm::Value *oldMask = GetInternalMask();
|
||||||
|
|||||||
7
ctx.h
7
ctx.h
@@ -195,6 +195,13 @@ public:
|
|||||||
'continue' statement when going through the loop body in the
|
'continue' statement when going through the loop body in the
|
||||||
previous iteration. */
|
previous iteration. */
|
||||||
void RestoreContinuedLanes();
|
void RestoreContinuedLanes();
|
||||||
|
|
||||||
|
/** This method is called by code emitting IR for a loop. It clears
|
||||||
|
any lanes that contained a break since the mask has been updated to take
|
||||||
|
them into account. This is necessary as all the bail out checks for
|
||||||
|
breaks are meant to only deal with lanes breaking on the current iteration.
|
||||||
|
*/
|
||||||
|
void ClearBreakLanes();
|
||||||
|
|
||||||
/** Indicates that code generation for a "switch" statement is about to
|
/** Indicates that code generation for a "switch" statement is about to
|
||||||
start. isUniform indicates whether the "switch" value is uniform,
|
start. isUniform indicates whether the "switch" value is uniform,
|
||||||
|
|||||||
7
stmt.cpp
7
stmt.cpp
@@ -532,7 +532,6 @@ IfStmt::emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Emit code for an if test that checks the mask and the test values and
|
/** Emit code for an if test that checks the mask and the test values and
|
||||||
tries to be smart about jumping over code that doesn't need to be run.
|
tries to be smart about jumping over code that doesn't need to be run.
|
||||||
*/
|
*/
|
||||||
@@ -902,8 +901,10 @@ void DoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// the code for the test. This is only necessary for varying loops;
|
// the code for the test. This is only necessary for varying loops;
|
||||||
// 'uniform' loops just jump when they hit a continue statement and
|
// 'uniform' loops just jump when they hit a continue statement and
|
||||||
// don't mess with the mask.
|
// don't mess with the mask.
|
||||||
if (!uniformTest)
|
if (!uniformTest) {
|
||||||
ctx->RestoreContinuedLanes();
|
ctx->RestoreContinuedLanes();
|
||||||
|
ctx->ClearBreakLanes();
|
||||||
|
}
|
||||||
llvm::Value *testValue = testExpr->GetValue(ctx);
|
llvm::Value *testValue = testExpr->GetValue(ctx);
|
||||||
if (!testValue)
|
if (!testValue)
|
||||||
return;
|
return;
|
||||||
@@ -1111,6 +1112,8 @@ ForStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
// test code.
|
// test code.
|
||||||
ctx->SetCurrentBasicBlock(bstep);
|
ctx->SetCurrentBasicBlock(bstep);
|
||||||
ctx->RestoreContinuedLanes();
|
ctx->RestoreContinuedLanes();
|
||||||
|
ctx->ClearBreakLanes();
|
||||||
|
|
||||||
if (step)
|
if (step)
|
||||||
step->EmitCode(ctx);
|
step->EmitCode(ctx);
|
||||||
ctx->BranchInst(btest);
|
ctx->BranchInst(btest);
|
||||||
|
|||||||
Reference in New Issue
Block a user