Skip to content

Commit 9d6d24c

Browse files
committed
[JumpThreading][VectorUtils] avoid infinite loop on unreachable IR
https://llvm.org/PR48362 It's possible that we could stub this out sooner somewhere within JumpThreading, but I'm not sure how to do that, and then we would still have potential danger in other callers. I can't find a way to trigger this using 'instsimplify', however, because that already has a bailout on unreachable blocks.
1 parent 1f525ec commit 9d6d24c

File tree

2 files changed

+92
-6
lines changed

2 files changed

+92
-6
lines changed

llvm/lib/Analysis/VectorUtils.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ Value *llvm::findScalarElement(Value *V, unsigned EltNo) {
290290
if (EltNo == IIElt)
291291
return III->getOperand(1);
292292

293+
// Guard against infinite loop on malformed, unreachable IR.
294+
if (III == III->getOperand(0))
295+
return nullptr;
296+
293297
// Otherwise, the insertelement doesn't modify the value, recurse on its
294298
// vector input.
295299
return findScalarElement(III->getOperand(0), EltNo);

llvm/test/Transforms/JumpThreading/unreachable-loops.ll

Lines changed: 88 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
; RUN: opt -jump-threading -S < %s | FileCheck %s
22
; RUN: opt -passes=jump-threading -S < %s | FileCheck %s
3+
34
; Check the unreachable loop won't cause infinite loop
45
; in jump-threading when it tries to update the predecessors'
56
; profile metadata from a phi node.
67

78
define void @unreachable_single_bb_loop() {
8-
; CHECK-LABEL: @unreachable_single_bb_loop()
9+
; CHECK-LABEL: @unreachable_single_bb_loop(
910
bb:
1011
%tmp = call i32 @a()
1112
%tmp1 = icmp eq i32 %tmp, 1
@@ -15,8 +16,8 @@ bb:
1516
bb2: ; preds = %bb2
1617
%tmp4 = icmp ne i32 %tmp, 1
1718
switch i1 %tmp4, label %bb2 [
18-
i1 0, label %bb5
19-
i1 1, label %bb8
19+
i1 0, label %bb5
20+
i1 1, label %bb8
2021
]
2122

2223
bb5: ; preds = %bb2, %bb
@@ -31,7 +32,7 @@ bb8: ; preds = %bb8, %bb7, %bb5, %b
3132
}
3233

3334
define void @unreachable_multi_bbs_loop() {
34-
; CHECK-LABEL: @unreachable_multi_bbs_loop()
35+
; CHECK-LABEL: @unreachable_multi_bbs_loop(
3536
bb:
3637
%tmp = call i32 @a()
3738
%tmp1 = icmp eq i32 %tmp, 1
@@ -44,8 +45,8 @@ bb3: ; preds = %bb2
4445
bb2: ; preds = %bb3
4546
%tmp4 = icmp ne i32 %tmp, 1
4647
switch i1 %tmp4, label %bb3 [
47-
i1 0, label %bb5
48-
i1 1, label %bb8
48+
i1 0, label %bb5
49+
i1 1, label %bb8
4950
]
5051

5152
bb5: ; preds = %bb2, %bb
@@ -60,4 +61,85 @@ bb8: ; preds = %bb8, %bb7, %bb5, %b
6061
}
6162
declare i32 @a()
6263

64+
; This gets into a state that could cause instruction simplify
65+
; to hang - an insertelement instruction has itself as an operand.
66+
67+
define void @PR48362() {
68+
; CHECK-LABEL: @PR48362(
69+
cleanup1491: ; preds = %for.body1140
70+
switch i32 0, label %cleanup2343.loopexit4 [
71+
i32 0, label %cleanup.cont1500
72+
i32 128, label %lbl_555.loopexit
73+
]
74+
75+
cleanup.cont1500: ; preds = %cleanup1491
76+
unreachable
77+
78+
lbl_555.loopexit: ; preds = %cleanup1491
79+
br label %for.body1509
80+
81+
for.body1509: ; preds = %for.inc2340, %lbl_555.loopexit
82+
%l_580.sroa.0.0 = phi <4 x i32> [ <i32 1684658741, i32 1684658741, i32 1684658741, i32 1684658741>, %lbl_555.loopexit ], [ %l_580.sroa.0.2, %for.inc2340 ]
83+
%p_55.addr.10 = phi i16 [ 0, %lbl_555.loopexit ], [ %p_55.addr.11, %for.inc2340 ]
84+
%i82 = load i32, i32* undef, align 1
85+
%tobool1731.not = icmp eq i32 %i82, 0
86+
br i1 %tobool1731.not, label %if.end1733, label %if.then1732
87+
88+
if.then1732: ; preds = %for.body1509
89+
br label %cleanup2329
90+
91+
if.end1733: ; preds = %for.body1509
92+
%tobool1735.not = icmp eq i16 %p_55.addr.10, 0
93+
br i1 %tobool1735.not, label %if.then1736, label %if.else1904
94+
95+
if.then1736: ; preds = %if.end1733
96+
br label %cleanup2329
97+
98+
if.else1904: ; preds = %if.end1733
99+
br label %for.body1911
100+
101+
for.body1911: ; preds = %if.else1904
102+
%l_580.sroa.0.4.vec.extract683 = extractelement <4 x i32> %l_580.sroa.0.0, i32 2
103+
%xor2107 = xor i32 undef, %l_580.sroa.0.4.vec.extract683
104+
br label %land.end2173
105+
106+
land.end2173: ; preds = %for.body1911
107+
br i1 undef, label %if.end2178, label %cleanup2297
108+
109+
if.end2178: ; preds = %land.end2173
110+
%l_580.sroa.0.2.vec.insert = insertelement <4 x i32> %l_580.sroa.0.0, i32 undef, i32 1
111+
br label %cleanup2297
112+
113+
cleanup2297: ; preds = %if.end2178, %land.end2173
114+
%l_580.sroa.0.1 = phi <4 x i32> [ %l_580.sroa.0.2.vec.insert, %if.end2178 ], [ %l_580.sroa.0.0, %land.end2173 ]
115+
br label %cleanup2329
116+
117+
cleanup2329: ; preds = %cleanup2297, %if.then1736, %if.then1732
118+
%l_580.sroa.0.2 = phi <4 x i32> [ %l_580.sroa.0.0, %if.then1736 ], [ %l_580.sroa.0.1, %cleanup2297 ], [ %l_580.sroa.0.0, %if.then1732 ]
119+
%cleanup.dest.slot.11 = phi i32 [ 0, %if.then1736 ], [ undef, %cleanup2297 ], [ 129, %if.then1732 ]
120+
%p_55.addr.11 = phi i16 [ %p_55.addr.10, %if.then1736 ], [ undef, %cleanup2297 ], [ %p_55.addr.10, %if.then1732 ]
121+
switch i32 %cleanup.dest.slot.11, label %cleanup2343.loopexit [
122+
i32 0, label %cleanup.cont2339
123+
i32 129, label %crit_edge114
124+
]
125+
126+
cleanup.cont2339: ; preds = %cleanup2329
127+
br label %for.inc2340
128+
129+
for.inc2340: ; preds = %cleanup.cont2339
130+
br i1 undef, label %for.body1509, label %crit_edge115
131+
132+
crit_edge114: ; preds = %cleanup2329
133+
unreachable
134+
135+
crit_edge115: ; preds = %for.inc2340
136+
unreachable
137+
138+
cleanup2343.loopexit: ; preds = %cleanup2329
139+
unreachable
140+
141+
cleanup2343.loopexit4: ; preds = %cleanup1491
142+
unreachable
143+
}
144+
63145
!0 = !{!"branch_weights", i32 2146410443, i32 1073205}

0 commit comments

Comments
 (0)