Skip to content

Commit 92c9949

Browse files
dianqkllvmbot
authored andcommitted
[ValueTracking] Skip incoming values that are the same as the phi in isGuaranteedNotToBeUndefOrPoison (#130111)
Fixes (keep it open) #130110. If the incoming value is PHI itself, we can skip this. If we can guarantee that the other incoming values are neither undef nor poison, then we can also guarantee that the value isn't either. If we cannot guarantee that, it makes no sense in calculating it. (cherry picked from commit 462eb7e)
1 parent 24a30da commit 92c9949

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7776,6 +7776,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
77767776
unsigned Num = PN->getNumIncomingValues();
77777777
bool IsWellDefined = true;
77787778
for (unsigned i = 0; i < Num; ++i) {
7779+
if (PN == PN->getIncomingValue(i))
7780+
continue;
77797781
auto *TI = PN->getIncomingBlock(i)->getTerminator();
77807782
if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
77817783
DT, Depth + 1, Kind)) {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
3+
4+
; Test `%r` can be replaced by `%nonpoison`.
5+
6+
define i32 @other_noundef(i32 noundef %arg) {
7+
; CHECK-LABEL: define i32 @other_noundef(
8+
; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
9+
; CHECK-NEXT: [[START:.*]]:
10+
; CHECK-NEXT: br label %[[LOOP:.*]]
11+
; CHECK: [[LOOP]]:
12+
; CHECK-NEXT: [[NONPOISON:%.*]] = phi i32 [ 0, %[[START]] ], [ [[NONPOISON]], %[[BB0:.*]] ], [ [[ARG]], %[[BB1:.*]] ]
13+
; CHECK-NEXT: [[I:%.*]] = call i32 @opaque()
14+
; CHECK-NEXT: switch i32 [[I]], label %[[EXIT:.*]] [
15+
; CHECK-NEXT: i32 0, label %[[BB0]]
16+
; CHECK-NEXT: i32 1, label %[[BB1]]
17+
; CHECK-NEXT: ]
18+
; CHECK: [[EXIT]]:
19+
; CHECK-NEXT: ret i32 [[NONPOISON]]
20+
; CHECK: [[BB0]]:
21+
; CHECK-NEXT: br label %[[LOOP]]
22+
; CHECK: [[BB1]]:
23+
; CHECK-NEXT: br label %[[LOOP]]
24+
;
25+
start:
26+
br label %loop
27+
28+
loop:
29+
%nonpoison = phi i32 [ 0, %start ], [ %nonpoison, %bb0 ], [ %arg, %bb1 ]
30+
%i = call i32 @opaque()
31+
switch i32 %i, label %exit [
32+
i32 0, label %bb0
33+
i32 1, label %bb1
34+
]
35+
36+
exit:
37+
%r = freeze i32 %nonpoison
38+
ret i32 %r
39+
40+
bb0:
41+
br label %loop
42+
43+
bb1:
44+
br label %loop
45+
}
46+
47+
define i32 @other_poison(i32 %arg) {
48+
; CHECK-LABEL: define i32 @other_poison(
49+
; CHECK-SAME: i32 [[ARG:%.*]]) {
50+
; CHECK-NEXT: [[START:.*]]:
51+
; CHECK-NEXT: br label %[[LOOP:.*]]
52+
; CHECK: [[LOOP]]:
53+
; CHECK-NEXT: [[MAYPOISON:%.*]] = phi i32 [ 0, %[[START]] ], [ [[MAYPOISON]], %[[BB0:.*]] ], [ [[ARG]], %[[BB1:.*]] ]
54+
; CHECK-NEXT: [[I:%.*]] = call i32 @opaque()
55+
; CHECK-NEXT: switch i32 [[I]], label %[[EXIT:.*]] [
56+
; CHECK-NEXT: i32 0, label %[[BB0]]
57+
; CHECK-NEXT: i32 1, label %[[BB1]]
58+
; CHECK-NEXT: ]
59+
; CHECK: [[EXIT]]:
60+
; CHECK-NEXT: [[R:%.*]] = freeze i32 [[MAYPOISON]]
61+
; CHECK-NEXT: ret i32 [[R]]
62+
; CHECK: [[BB0]]:
63+
; CHECK-NEXT: br label %[[LOOP]]
64+
; CHECK: [[BB1]]:
65+
; CHECK-NEXT: br label %[[LOOP]]
66+
;
67+
start:
68+
br label %loop
69+
70+
loop:
71+
%maypoison = phi i32 [ 0, %start ], [ %maypoison, %bb0 ], [ %arg, %bb1 ]
72+
%i = call i32 @opaque()
73+
switch i32 %i, label %exit [
74+
i32 0, label %bb0
75+
i32 1, label %bb1
76+
]
77+
78+
exit:
79+
%r = freeze i32 %maypoison
80+
ret i32 %r
81+
82+
bb0:
83+
br label %loop
84+
85+
bb1:
86+
br label %loop
87+
}
88+
89+
declare i32 @opaque()

0 commit comments

Comments
 (0)