mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 03:23:01 +02:00
[SCEV] Handle and/or in applyLoopGuards()
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 recursing into either `and` or `or`, depending on the direction of the branch. Differential Revision: https://reviews.llvm.org/D101692
This commit is contained in:
parent
b739e40444
commit
b57784b03b
@ -13485,16 +13485,30 @@ const SCEV *ScalarEvolution::applyLoopGuards(const SCEV *Expr, const Loop *L) {
|
||||
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)
|
||||
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);
|
||||
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.
|
||||
|
@ -489,14 +489,14 @@ define void @test_guard_if_and_enter(i32* nocapture readonly %data, i64 %count)
|
||||
; 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
|
||||
@ -563,14 +563,14 @@ define void @test_guard_if_and_and(i32* nocapture readonly %data, i64 %count, i1
|
||||
; CHECK-NEXT: %cmp.and = and i1 %cmp.ult, %cmp.and1
|
||||
; 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_and
|
||||
; 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
|
||||
@ -639,14 +639,14 @@ define void @test_guard_if_or_skip(i32* nocapture readonly %data, i64 %count) {
|
||||
; 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
|
||||
@ -713,14 +713,14 @@ define void @test_guard_if_or_or(i32* nocapture readonly %data, i64 %count, i1 %
|
||||
; CHECK-NEXT: %cmp.or = or i1 %cmp.uge, %cmp.or1
|
||||
; 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_or
|
||||
; 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
|
||||
|
Loading…
Reference in New Issue
Block a user