Fix bug that caused unterminated basic blocks.

Issue #339.
This commit is contained in:
Matt Pharr
2012-07-23 08:23:53 -07:00
parent e9fe9f5043
commit ae89a65dad

View File

@@ -675,39 +675,38 @@ IfStmt::emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask,
llvm::Value *ltest, llvm::BasicBlock *bDone) const { llvm::Value *ltest, llvm::BasicBlock *bDone) const {
ctx->StartVaryingIf(oldMask); ctx->StartVaryingIf(oldMask);
llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true"); llvm::BasicBlock *bNext = ctx->CreateBasicBlock("safe_if_after_true");
if (trueStmts != NULL) {
llvm::BasicBlock *bRunTrue = ctx->CreateBasicBlock("safe_if_run_true"); llvm::BasicBlock *bRunTrue = ctx->CreateBasicBlock("safe_if_run_true");
ctx->SetInternalMaskAnd(oldMask, ltest); ctx->SetInternalMaskAnd(oldMask, ltest);
// Do any of the program instances want to run the 'true' // Do any of the program instances want to run the 'true'
// block? If not, jump ahead to bNext. // block? If not, jump ahead to bNext.
llvm::Value *maskAnyQ = ctx->Any(ctx->GetFullMask()); llvm::Value *maskAnyTrueQ = ctx->Any(ctx->GetFullMask());
ctx->BranchInst(bRunTrue, bNext, maskAnyQ); ctx->BranchInst(bRunTrue, bNext, maskAnyTrueQ);
// Emit statements for true // Emit statements for true
ctx->SetCurrentBasicBlock(bRunTrue); ctx->SetCurrentBasicBlock(bRunTrue);
if (trueStmts != NULL)
lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements"); lEmitIfStatements(ctx, trueStmts, "if: expr mixed, true statements");
AssertPos(pos, ctx->GetCurrentBasicBlock()); AssertPos(pos, ctx->GetCurrentBasicBlock());
ctx->BranchInst(bNext); ctx->BranchInst(bNext);
ctx->SetCurrentBasicBlock(bNext); ctx->SetCurrentBasicBlock(bNext);
}
if (falseStmts != NULL) { // False...
llvm::BasicBlock *bRunFalse = ctx->CreateBasicBlock("safe_if_run_false"); llvm::BasicBlock *bRunFalse = ctx->CreateBasicBlock("safe_if_run_false");
bNext = ctx->CreateBasicBlock("safe_if_after_false");
ctx->SetInternalMaskAndNot(oldMask, ltest); ctx->SetInternalMaskAndNot(oldMask, ltest);
// Similarly, check to see if any of the instances want to // Similarly, check to see if any of the instances want to
// run the 'false' block... // run the 'false' block...
llvm::Value *maskAnyQ = ctx->Any(ctx->GetFullMask()); llvm::Value *maskAnyFalseQ = ctx->Any(ctx->GetFullMask());
ctx->BranchInst(bRunFalse, bNext, maskAnyQ); ctx->BranchInst(bRunFalse, bDone, maskAnyFalseQ);
// Emit code for false // Emit code for false
ctx->SetCurrentBasicBlock(bRunFalse); ctx->SetCurrentBasicBlock(bRunFalse);
if (falseStmts)
lEmitIfStatements(ctx, falseStmts, "if: expr mixed, false statements"); lEmitIfStatements(ctx, falseStmts, "if: expr mixed, false statements");
AssertPos(pos, ctx->GetCurrentBasicBlock()); AssertPos(pos, ctx->GetCurrentBasicBlock());
ctx->BranchInst(bNext);
ctx->SetCurrentBasicBlock(bNext);
}
ctx->BranchInst(bDone); ctx->BranchInst(bDone);
ctx->SetCurrentBasicBlock(bDone); ctx->SetCurrentBasicBlock(bDone);
ctx->EndIf(); ctx->EndIf();