aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp21
-rw-r--r--test/Transforms/SimplifyCFG/SpeculativeExec.ll22
2 files changed, 36 insertions, 7 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 0e382874dc..7ec31657ec 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1433,21 +1433,28 @@ static bool SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB) {
continue;
HaveRewritablePHIs = true;
-
- // Check for safety.
ConstantExpr *CE = dyn_cast<ConstantExpr>(ThenV);
if (!CE)
- continue; // Known safe.
+ continue; // Known safe and cheap.
+
+ if (!isSafeToSpeculativelyExecute(CE))
+ return false;
+
+ // Don't speculate into a select with a constant select expression operand.
+ // FIXME: This should really be a cost metric, but our cost model doesn't
+ // accurately model the expense of select.
+ if (Operator::getOpcode(CE) == Instruction::Select)
+ return false;
// An unfolded ConstantExpr could end up getting expanded into
// Instructions. Don't speculate this and another instruction at
// the same time.
+ // FIXME: This is strange because provided we haven't already hit the cost
+ // of 1, this code will speculate an arbitrary number of complex constant
+ // expression PHI nodes. Also, this doesn't account for how complex the
+ // constant expression is.
if (SpeculationCost > 0)
return false;
- if (!isSafeToSpeculativelyExecute(CE))
- return false;
- if (ComputeSpeculationCost(CE) > PHINodeFoldingThreshold)
- return false;
}
// If there are no PHIs to process, bail early. This helps ensure idempotence
diff --git a/test/Transforms/SimplifyCFG/SpeculativeExec.ll b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
index a61867fe89..c66d3ec67b 100644
--- a/test/Transforms/SimplifyCFG/SpeculativeExec.ll
+++ b/test/Transforms/SimplifyCFG/SpeculativeExec.ll
@@ -44,3 +44,25 @@ join:
ret i8 %c
}
+define i8* @test3(i1* %dummy, i8* %a, i8* %b) {
+; Test that a weird, unfolded constant cast in the PHI don't block speculation.
+; CHECK: @test3
+
+entry:
+ %cond1 = load volatile i1* %dummy
+ br i1 %cond1, label %if, label %end
+
+if:
+ %cond2 = load volatile i1* %dummy
+ br i1 %cond2, label %then, label %end
+
+then:
+ br label %end
+
+end:
+ %x = phi i8* [ %a, %entry ], [ %b, %if ], [ inttoptr (i64 42 to i8*), %then ]
+; CHECK-NOT: phi
+; CHECK: select i1 %cond2, i8* inttoptr
+
+ ret i8* %x
+}