aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-03-18 20:37:11 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-03-18 20:37:11 +0000
commit74af78e3b00b6b56c279fd33f8c31b8096f10aab (patch)
tree664c10ce547a09196917eb9414ecceb596839591 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parent60fb899f28c7cde25341ea87f32f3be9f440983a (diff)
downloadllvm-74af78e3b00b6b56c279fd33f8c31b8096f10aab.zip
llvm-74af78e3b00b6b56c279fd33f8c31b8096f10aab.tar.gz
llvm-74af78e3b00b6b56c279fd33f8c31b8096f10aab.tar.bz2
[IndVars] Make the fix for PR26973 more obvious; NFCI
llvm-svn: 263828
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp45
1 files changed, 42 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index fe5d8e4..c95f10e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -200,9 +200,48 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
NewRHS =
ICmp->getOperand(S == InvariantRHS ? IVOperIdx : (1 - IVOperIdx));
- for (Value *Incoming : cast<PHINode>(IVOperand)->incoming_values()) {
- if (NewLHS && NewRHS)
- break;
+ auto *PN = cast<PHINode>(IVOperand);
+ for (unsigned i = 0, e = PN->getNumIncomingValues();
+ i != e && (!NewLHS || !NewRHS);
+ ++i) {
+
+ // If this is a value incoming from the backedge, then it cannot be a loop
+ // invariant value (since we know that IVOperand is an induction variable).
+ if (L->contains(PN->getIncomingBlock(i)))
+ continue;
+
+ // NB! This following assert does not fundamentally have to be true, but
+ // it is true today given how SCEV analyzes induction variables.
+ // Specifically, today SCEV will *not* recognize %iv as an induction
+ // variable in the following case:
+ //
+ // define void @f(i32 %k) {
+ // entry:
+ // br i1 undef, label %r, label %l
+ //
+ // l:
+ // %k.inc.l = add i32 %k, 1
+ // br label %loop
+ //
+ // r:
+ // %k.inc.r = add i32 %k, 1
+ // br label %loop
+ //
+ // loop:
+ // %iv = phi i32 [ %k.inc.l, %l ], [ %k.inc.r, %r ], [ %iv.inc, %loop ]
+ // %iv.inc = add i32 %iv, 1
+ // br label %loop
+ // }
+ //
+ // but if it starts to, at some point, then the assertion below will have
+ // to be changed to a runtime check.
+
+ Value *Incoming = PN->getIncomingValue(i);
+
+#ifndef NDEBUG
+ if (auto *I = dyn_cast<Instruction>(Incoming))
+ assert(DT->dominates(I, ICmp) && "Should be a unique loop dominating value!");
+#endif
const SCEV *IncomingS = SE->getSCEV(Incoming);