Skip to content

Commit f62b50e

Browse files
dianqktstellar
authored andcommitted
[ValueTracking] Skip incoming values that are the same as the phi in isGuaranteedNotToBeUndefOrPoison (llvm#130111)
Fixes (keep it open) llvm#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 50343e5 commit f62b50e

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
@@ -7777,6 +7777,8 @@ static bool isGuaranteedNotToBeUndefOrPoison(
77777777
unsigned Num = PN->getNumIncomingValues();
77787778
bool IsWellDefined = true;
77797779
for (unsigned i = 0; i < Num; ++i) {
7780+
if (PN == PN->getIncomingValue(i))
7781+
continue;
77807782
auto *TI = PN->getIncomingBlock(i)->getTerminator();
77817783
if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
77827784
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)