[llvm] r251938 - Fix PR25372 - teach replaceCongruentPHIs to handle cases where SE evaluates a PHI to a SCEVConstant
Silviu Baranga via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 3 08:27:05 PST 2015
Author: sbaranga
Date: Tue Nov 3 10:27:04 2015
New Revision: 251938
URL: http://llvm.org/viewvc/llvm-project?rev=251938&view=rev
Log:
Fix PR25372 - teach replaceCongruentPHIs to handle cases where SE evaluates a PHI to a SCEVConstant
Summary:
Since now Scalar Evolution can create non-add rec expressions for PHI
nodes, it can also create SCEVConstant expressions. This will confuse
replaceCongruentPHIs, which previously relied on the fact that SCEV
could not produce constants in this case.
We will now replace the node with a constant in these cases - or avoid
processing the Phi in case of a type mismatch.
Reviewers: sanjoy
Subscribers: llvm-commits, majnemer
Differential Revision: http://reviews.llvm.org/D14230
Added:
llvm/trunk/test/Transforms/IndVarSimplify/const_phi.ll
Modified:
llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=251938&r1=251937&r2=251938&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Tue Nov 3 10:27:04 2015
@@ -1735,9 +1735,22 @@ unsigned SCEVExpander::replaceCongruentI
PEnd = Phis.end(); PIter != PEnd; ++PIter) {
PHINode *Phi = *PIter;
+ auto SimplifyPHINode = [&](PHINode *PN) -> Value * {
+ if (Value *V = SimplifyInstruction(PN, DL, &SE.TLI, &SE.DT, &SE.AC))
+ return V;
+ if (!SE.isSCEVable(PN->getType()))
+ return nullptr;
+ auto *Const = dyn_cast<SCEVConstant>(SE.getSCEV(PN));
+ if (!Const)
+ return nullptr;
+ return Const->getValue();
+ };
+
// Fold constant phis. They may be congruent to other constant phis and
// would confuse the logic below that expects proper IVs.
- if (Value *V = SimplifyInstruction(Phi, DL, &SE.TLI, &SE.DT, &SE.AC)) {
+ if (Value *V = SimplifyPHINode(Phi)) {
+ if (V->getType() != Phi->getType())
+ continue;
Phi->replaceAllUsesWith(V);
DeadInsts.emplace_back(Phi);
++NumElim;
Added: llvm/trunk/test/Transforms/IndVarSimplify/const_phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/const_phi.ll?rev=251938&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/const_phi.ll (added)
+++ llvm/trunk/test/Transforms/IndVarSimplify/const_phi.ll Tue Nov 3 10:27:04 2015
@@ -0,0 +1,33 @@
+; RUN: opt < %s -indvars -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+; PR25372
+; We can compute the expression of %phi0 and that is a SCEV
+; constant. However, instcombine can't deduce this, so we can
+; potentially end up trying to handle a constant when replacing
+; congruent IVs.
+
+; CHECK-LABEL: crash
+define void @crash() {
+entry:
+ br i1 false, label %not_taken, label %pre
+
+not_taken:
+ br label %pre
+
+pre:
+; %phi0.pre and %phi1.pre are evaluated by SCEV to constant 0.
+ %phi0.pre = phi i32 [ 0, %entry ], [ 2, %not_taken ]
+ %phi1.pre = phi i32 [ 0, %entry ], [ 1, %not_taken ]
+ br label %loop
+
+loop:
+; %phi0 and %phi1 are evaluated by SCEV to constant 0.
+ %phi0 = phi i32 [ 0, %loop ], [ %phi0.pre, %pre ]
+ %phi1 = phi i32 [ 0, %loop ], [ %phi1.pre, %pre ]
+ br i1 undef, label %exit, label %loop
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list