Skip to content

Commit 462eb7e

Browse files
authored
[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.
1 parent 3492245 commit 462eb7e

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

llvm/lib/Analysis/ValueTracking.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -7849,6 +7849,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
78497849
unsigned Num = PN->getNumIncomingValues();
78507850
bool IsWellDefined = true;
78517851
for (unsigned i = 0; i < Num; ++i) {
7852+
if (PN == PN->getIncomingValue(i))
7853+
continue;
78527854
auto *TI = PN->getIncomingBlock(i)->getTerminator();
78537855
if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
78547856
DT, Depth + 1, Kind)) {
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)