[PATCH] D101692: [SCEV] Handle and/or in applyLoopGuards()
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat May 1 08:15:25 PDT 2021
nikic created this revision.
nikic added reviewers: fhahn, reames.
Herald added a subscriber: hiraditya.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
applyLoopGuards() already combines conditions from multiple nested guards. However, it cannot use multiple conditions on the same guard, combined using and/or. Add support for this by recursion into either `and` or `or`, depending on the direction of the branch.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D101692
Files:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
Index: llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
===================================================================
--- llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
+++ llvm/test/Analysis/ScalarEvolution/max-backedge-taken-count-guard-info.ll
@@ -489,14 +489,14 @@
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.ne
; CHECK-NEXT: --> %cmp.and U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,-1) S: [0,-1) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
-; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_and_enter
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
-; CHECK-NEXT: Loop %loop: max backedge-taken count is -2
+; CHECK-NEXT: Loop %loop: max backedge-taken count is 3
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
@@ -561,14 +561,14 @@
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.eq
; CHECK-NEXT: --> %cmp.or U: full-set S: full-set
; CHECK-NEXT: %iv = phi i64 [ %iv.next, %loop ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,-1) S: [0,-1) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: [0,4) S: [0,4) Exits: (-1 + %count) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx = getelementptr inbounds i32, i32* %data, i64 %iv
-; CHECK-NEXT: --> {%data,+,4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {%data,+,4}<nuw><%loop> U: full-set S: full-set Exits: (-4 + (4 * %count) + %data) LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.next = add nuw i64 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %count LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,5) S: [1,5) Exits: %count LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test_guard_if_or_skip
; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %count)
-; CHECK-NEXT: Loop %loop: max backedge-taken count is -2
+; CHECK-NEXT: Loop %loop: max backedge-taken count is 3
; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %count)
; CHECK-NEXT: Predicates:
; CHECK: Loop %loop: Trip multiple is 1
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -13501,16 +13501,30 @@
if (!LoopEntryPredicate || LoopEntryPredicate->isUnconditional())
continue;
- // TODO: use information from more complex conditions, e.g. AND expressions.
- auto *Cmp = dyn_cast<ICmpInst>(LoopEntryPredicate->getCondition());
- if (!Cmp)
- continue;
+ bool EnterIfTrue = LoopEntryPredicate->getSuccessor(0) == Pair.second;
+ SmallVector<Value *, 8> Worklist;
+ SmallPtrSet<Value *, 8> Visited;
+ Worklist.push_back(LoopEntryPredicate->getCondition());
+ while (!Worklist.empty()) {
+ Value *Cond = Worklist.pop_back_val();
+ if (!Visited.insert(Cond).second)
+ continue;
- auto Predicate = Cmp->getPredicate();
- if (LoopEntryPredicate->getSuccessor(1) == Pair.second)
- Predicate = CmpInst::getInversePredicate(Predicate);
- CollectCondition(Predicate, getSCEV(Cmp->getOperand(0)),
- getSCEV(Cmp->getOperand(1)), RewriteMap);
+ if (auto *Cmp = dyn_cast<ICmpInst>(Cond)) {
+ auto Predicate =
+ EnterIfTrue ? Cmp->getPredicate() : Cmp->getInversePredicate();
+ CollectCondition(Predicate, getSCEV(Cmp->getOperand(0)),
+ getSCEV(Cmp->getOperand(1)), RewriteMap);
+ continue;
+ }
+
+ Value *L, *R;
+ if (EnterIfTrue ? match(Cond, m_LogicalAnd(m_Value(L), m_Value(R)))
+ : match(Cond, m_LogicalOr(m_Value(L), m_Value(R)))) {
+ Worklist.push_back(L);
+ Worklist.push_back(R);
+ }
+ }
}
// Also collect information from assumptions dominating the loop.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101692.342153.patch
Type: text/x-patch
Size: 5076 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210501/63f81f42/attachment.bin>
More information about the llvm-commits
mailing list