[llvm] r316976 - [IndVarSimplify] Simplify code using preheader assumption
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 30 22:16:46 PDT 2017
Author: reames
Date: Mon Oct 30 22:16:46 2017
New Revision: 316976
URL: http://llvm.org/viewvc/llvm-project?rev=316976&view=rev
Log:
[IndVarSimplify] Simplify code using preheader assumption
As noted in the nice block comment, the previous code didn't actually handle multi-entry loops correctly, it just assumed SCEV didn't analyze such loops. Given SCEV has comments to the contrary, that seems a bit suspect. More importantly, the pass actually requires loopsimplify form which ensures a loop-preheader is available. Remove the excessive generaility and shorten the code greatly.
Note that we do successfully analyze many multi-entry loops, but we do so by converting them to single entry loops. See the added test case.
Modified:
llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp?rev=316976&r1=316975&r2=316976&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyIndVar.cpp Mon Oct 30 22:16:46 2017
@@ -182,7 +182,8 @@ bool SimplifyIndvar::makeIVComparisonInv
ICmpInst::Predicate InvariantPredicate;
const SCEV *InvariantLHS, *InvariantRHS;
- if (!isa<PHINode>(IVOperand))
+ auto *PN = dyn_cast<PHINode>(IVOperand);
+ if (!PN)
return false;
if (!SE->isLoopInvariantPredicate(Pred, S, X, L, InvariantPredicate,
InvariantLHS, InvariantRHS))
@@ -202,49 +203,10 @@ bool SimplifyIndvar::makeIVComparisonInv
NewRHS =
ICmp->getOperand(S == InvariantRHS ? IVOperIdx : (1 - IVOperIdx));
- 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
-
+ // TODO: Support multiple entry loops? (We currently bail out of these in
+ // the IndVarSimplify pass)
+ if (auto *BB = L->getLoopPredecessor()) {
+ Value *Incoming = PN->getIncomingValue(PN->getBasicBlockIndex(BB));
const SCEV *IncomingS = SE->getSCEV(Incoming);
if (!NewLHS && IncomingS == InvariantLHS)
Modified: llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll?rev=316976&r1=316975&r2=316976&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/loop-invariant-conditions.ll Mon Oct 30 22:16:46 2017
@@ -273,6 +273,28 @@ for.end:
ret void
}
+; check to handle loops without preheaders, but invariant operands
+; (we handle this today by inserting a preheader)
+define void @test9(i1 %cnd, i64 %start) {
+; CHECK-LABEL: @test9
+; CHECK-LABEL: loop.preheader:
+entry:
+ br i1 %cnd, label %entry1, label %entry2
+entry1:
+ br label %loop
+entry2:
+ br label %loop
+loop:
+ %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
+ %indvars.iv.next = add nsw i64 %indvars.iv, 1
+; CHECK: %cmp1 = icmp slt i64 %start, -1
+ %cmp1 = icmp slt i64 %indvars.iv, -1
+ br i1 %cmp1, label %for.end, label %loop
+
+for.end: ; preds = %if.end, %entry
+ ret void
+}
+
!1 = !{i64 -1, i64 100}
More information about the llvm-commits
mailing list