Skip to content

Commit cc5208b

Browse files
committed
[ValueTracking] Handle recursive PHI's in computeKnownBits
Finish porting llvm#114008 to `KnownBits` (Follow up to llvm#113707).
1 parent 3a16873 commit cc5208b

File tree

5 files changed

+27
-24
lines changed

5 files changed

+27
-24
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,14 +1564,16 @@ static void computeKnownBitsFromOperator(const Operator *I,
15641564
for (unsigned u = 0, e = P->getNumIncomingValues(); u < e; ++u) {
15651565
Value *IncValue = P->getIncomingValue(u);
15661566
// Skip direct self references.
1567-
if (IncValue == P) continue;
1567+
if (IncValue == P)
1568+
continue;
15681569

15691570
// Recurse, but cap the recursion to one level, because we don't
15701571
// want to waste time spinning around in loops.
15711572
// TODO: See if we can base recursion limiter on number of incoming phi
15721573
// edges so we don't overly clamp analysis.
15731574
unsigned IncDepth = MaxAnalysisRecursionDepth - 1;
15741575

1576+
Instruction *CxtI = P->getIncomingBlock(u)->getTerminator();
15751577
// If the Use is a select of this phi, use the knownbit of the other
15761578
// operand to break the recursion.
15771579
if (auto *SI = dyn_cast<SelectInst>(IncValue)) {
@@ -1580,14 +1582,22 @@ static void computeKnownBitsFromOperator(const Operator *I,
15801582
: SI->getTrueValue();
15811583
IncDepth = Depth + 1;
15821584
}
1585+
} else if (auto *IncPhi = dyn_cast<PHINode>(IncValue);
1586+
IncPhi && IncPhi->getNumIncomingValues() == 2) {
1587+
for (int Idx = 0; Idx < 2; ++Idx) {
1588+
if (IncPhi->getIncomingValue(Idx) == P) {
1589+
IncValue = IncPhi->getIncomingValue(1 - Idx);
1590+
CxtI = IncPhi->getIncomingBlock(1 - Idx)->getTerminator();
1591+
break;
1592+
}
1593+
}
15831594
}
15841595

15851596
// Change the context instruction to the "edge" that flows into the
15861597
// phi. This is important because that is where the value is actually
15871598
// "evaluated" even though it is used later somewhere else. (see also
15881599
// D69571).
1589-
SimplifyQuery RecQ = Q.getWithoutCondContext();
1590-
RecQ.CxtI = P->getIncomingBlock(u)->getTerminator();
1600+
SimplifyQuery RecQ = Q.getWithoutCondContext().getWithInstruction(CxtI);
15911601

15921602
Known2 = KnownBits(BitWidth);
15931603
computeKnownBits(IncValue, DemandedElts, Known2, IncDepth, RecQ);

llvm/test/Analysis/ScalarEvolution/cycled_phis.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ define void @test_01() {
88
; CHECK-LABEL: 'test_01'
99
; CHECK-NEXT: Classifying expressions for: @test_01
1010
; CHECK-NEXT: %phi_1 = phi i32 [ 10, %entry ], [ %phi_2, %loop ]
11-
; CHECK-NEXT: --> %phi_1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
11+
; CHECK-NEXT: --> %phi_1 U: [0,31) S: [0,31) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
1212
; CHECK-NEXT: %phi_2 = phi i32 [ 20, %entry ], [ %phi_1, %loop ]
13-
; CHECK-NEXT: --> %phi_2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
13+
; CHECK-NEXT: --> %phi_2 U: [0,31) S: [0,31) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
1414
; CHECK-NEXT: %cond = call i1 @cond()
1515
; CHECK-NEXT: --> %cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
1616
; CHECK-NEXT: Determining loop execution counts for: @test_01

llvm/test/Analysis/ScalarEvolution/unknown_phis.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ define void @merge_values_with_ranges_looped(ptr %a_len_ptr, ptr %b_len_ptr) {
3939
; CHECK-NEXT: %len_b = load i32, ptr %b_len_ptr, align 4, !range !0
4040
; CHECK-NEXT: --> %len_b U: [0,2147483647) S: [0,2147483647)
4141
; CHECK-NEXT: %p1 = phi i32 [ %len_a, %entry ], [ %p2, %loop ]
42-
; CHECK-NEXT: --> %p1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
42+
; CHECK-NEXT: --> %p1 U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
4343
; CHECK-NEXT: %p2 = phi i32 [ %len_b, %entry ], [ %p1, %loop ]
44-
; CHECK-NEXT: --> %p2 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
44+
; CHECK-NEXT: --> %p2 U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
4545
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
4646
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,100) S: [0,100) Exits: 99 LoopDispositions: { %loop: Computable }
4747
; CHECK-NEXT: %iv.next = add i32 %iv, 1

llvm/test/Transforms/InstCombine/known-phi-recurse.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,7 @@ define i8 @knownbits_phi_phi_test() {
272272
; CHECK-NEXT: [[COND1:%.*]] = call i1 @cond()
273273
; CHECK-NEXT: br i1 [[COND1]], label [[EXIT:%.*]], label [[LOOP]]
274274
; CHECK: exit:
275-
; CHECK-NEXT: [[BOOL:%.*]] = and i8 [[CONTAIN]], 1
276-
; CHECK-NEXT: ret i8 [[BOOL]]
275+
; CHECK-NEXT: ret i8 [[CONTAIN]]
277276
;
278277
entry:
279278
br label %loop

llvm/test/Transforms/SimplifyCFG/switch-branch-fold-indirectbr-102351.ll

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,23 @@ define dso_local noundef i32 @main() {
88
; CHECK-LABEL: define dso_local noundef i32 @main() {
99
; CHECK-NEXT: [[BB:.*]]:
1010
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x ptr], align 16
11-
; CHECK-NEXT: store ptr blockaddress(@main, %[[BB4:.*]]), ptr [[ALLOCA]], align 16, !tbaa [[TBAA0:![0-9]+]]
11+
; CHECK-NEXT: store ptr blockaddress(@main, %[[BB1:.*]]), ptr [[ALLOCA]], align 16, !tbaa [[TBAA0:![0-9]+]]
1212
; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ALLOCA]], i64 0, i64 1
1313
; CHECK-NEXT: store ptr blockaddress(@main, %[[BB10:.*]]), ptr [[GETELEMENTPTR]], align 8, !tbaa [[TBAA0]]
14-
; CHECK-NEXT: br label %[[BB1:.*]]
14+
; CHECK-NEXT: br label %[[BB1]]
1515
; CHECK: [[BB1]]:
16-
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[PHI8:%.*]], %[[BB7:.*]] ]
17-
; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[PHI9:%.*]], %[[BB7]] ]
18-
; CHECK-NEXT: switch i32 [[PHI]], label %[[BB7]] [
19-
; CHECK-NEXT: i32 0, label %[[BB12:.*]]
20-
; CHECK-NEXT: i32 1, label %[[BB4]]
16+
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, %[[BB]] ], [ 2, %[[BB12:.*]] ]
17+
; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[PHI13:%.*]], %[[BB12]] ]
18+
; CHECK-NEXT: switch i32 [[PHI]], label %[[BB1_UNREACHABLEDEFAULT:.*]] [
19+
; CHECK-NEXT: i32 0, label %[[BB12]]
2120
; CHECK-NEXT: i32 2, label %[[BB6:.*]]
2221
; CHECK-NEXT: ]
23-
; CHECK: [[BB4]]:
24-
; CHECK-NEXT: [[PHI5:%.*]] = phi i32 [ [[PHI13:%.*]], %[[BB12]] ], [ [[PHI2]], %[[BB1]] ]
25-
; CHECK-NEXT: br label %[[BB7]]
2622
; CHECK: [[BB6]]:
2723
; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo(i32 noundef [[PHI2]])
2824
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[PHI2]], 1
2925
; CHECK-NEXT: br label %[[BB12]]
30-
; CHECK: [[BB7]]:
31-
; CHECK-NEXT: [[PHI8]] = phi i32 [ [[PHI]], %[[BB1]] ], [ 2, %[[BB4]] ]
32-
; CHECK-NEXT: [[PHI9]] = phi i32 [ [[PHI2]], %[[BB1]] ], [ [[PHI5]], %[[BB4]] ]
33-
; CHECK-NEXT: br label %[[BB1]], !llvm.loop [[LOOP4:![0-9]+]]
26+
; CHECK: [[BB1_UNREACHABLEDEFAULT]]:
27+
; CHECK-NEXT: unreachable
3428
; CHECK: [[BB10]]:
3529
; CHECK-NEXT: [[CALL11:%.*]] = call i32 @foo(i32 noundef [[PHI13]])
3630
; CHECK-NEXT: ret i32 0
@@ -39,7 +33,7 @@ define dso_local noundef i32 @main() {
3933
; CHECK-NEXT: [[SEXT:%.*]] = sext i32 [[PHI13]] to i64
4034
; CHECK-NEXT: [[GETELEMENTPTR14:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ALLOCA]], i64 0, i64 [[SEXT]]
4135
; CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr [[GETELEMENTPTR14]], align 8, !tbaa [[TBAA0]]
42-
; CHECK-NEXT: indirectbr ptr [[LOAD]], [label %[[BB4]], label %bb10]
36+
; CHECK-NEXT: indirectbr ptr [[LOAD]], [label %[[BB1]], label %bb10], !llvm.loop [[LOOP4:![0-9]+]]
4337
;
4438
bb:
4539
%alloca = alloca [2 x ptr], align 16

0 commit comments

Comments
 (0)