xref: /aosp_15_r20/external/llvm/test/Transforms/GuardWidening/basic.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -guard-widening < %s        | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -passes=guard-widening < %s | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.experimental.guard(i1,...)
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker; Basic test case: we wide the first check to check both the
7*9880d681SAndroid Build Coastguard Worker; conditions.
8*9880d681SAndroid Build Coastguard Workerdefine void @f_0(i1 %cond_0, i1 %cond_1) {
9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_0(
10*9880d681SAndroid Build Coastguard Workerentry:
11*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_0, %cond_1
12*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
13*9880d681SAndroid Build Coastguard Worker; CHECK:  ret void
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
16*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
17*9880d681SAndroid Build Coastguard Worker  ret void
18*9880d681SAndroid Build Coastguard Worker}
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker; Same as @f_0, but with using a more general notion of postdominance.
21*9880d681SAndroid Build Coastguard Workerdefine void @f_1(i1 %cond_0, i1 %cond_1) {
22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_1(
23*9880d681SAndroid Build Coastguard Workerentry:
24*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_0, %cond_1
25*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
26*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
29*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workerleft:
32*9880d681SAndroid Build Coastguard Worker  br label %merge
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Workerright:
35*9880d681SAndroid Build Coastguard Worker  br label %merge
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Workermerge:
38*9880d681SAndroid Build Coastguard Worker; CHECK: merge:
39*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: call void (i1, ...) @llvm.experimental.guard(
40*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
41*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
42*9880d681SAndroid Build Coastguard Worker  ret void
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; Like @f_1, but we have some code we need to hoist before we can
46*9880d681SAndroid Build Coastguard Worker; widen a dominanting check.
47*9880d681SAndroid Build Coastguard Workerdefine void @f_2(i32 %a, i32 %b) {
48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_2(
49*9880d681SAndroid Build Coastguard Workerentry:
50*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_0 = icmp ult i32 %a, 10
51*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_1 = icmp ult i32 %b, 10
52*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_0, %cond_1
53*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
54*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ult i32 %a, 10
57*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
58*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerleft:
61*9880d681SAndroid Build Coastguard Worker  br label %merge
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Workerright:
64*9880d681SAndroid Build Coastguard Worker  br label %merge
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Workermerge:
67*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp ult i32 %b, 10
68*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
69*9880d681SAndroid Build Coastguard Worker  ret void
70*9880d681SAndroid Build Coastguard Worker}
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker; Negative test: don't hoist stuff out of control flow
73*9880d681SAndroid Build Coastguard Worker; indiscriminately, since that can make us do more work than needed.
74*9880d681SAndroid Build Coastguard Workerdefine void @f_3(i32 %a, i32 %b) {
75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_3(
76*9880d681SAndroid Build Coastguard Workerentry:
77*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_0 = icmp ult i32 %a, 10
78*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
79*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ult i32 %a, 10
82*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
83*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Workerleft:
86*9880d681SAndroid Build Coastguard Worker; CHECK: left:
87*9880d681SAndroid Build Coastguard Worker; CHECK:   %cond_1 = icmp ult i32 %b, 10
88*9880d681SAndroid Build Coastguard Worker; CHECK:   call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
89*9880d681SAndroid Build Coastguard Worker; CHECK:   ret void
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp ult i32 %b, 10
92*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
93*9880d681SAndroid Build Coastguard Worker  ret void
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workerright:
96*9880d681SAndroid Build Coastguard Worker  ret void
97*9880d681SAndroid Build Coastguard Worker}
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker; But hoisting out of control flow is fine if it makes a loop computed
100*9880d681SAndroid Build Coastguard Worker; condition loop invariant.  This behavior may require some tuning in
101*9880d681SAndroid Build Coastguard Worker; the future.
102*9880d681SAndroid Build Coastguard Workerdefine void @f_4(i32 %a, i32 %b) {
103*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_4(
104*9880d681SAndroid Build Coastguard Workerentry:
105*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_0 = icmp ult i32 %a, 10
106*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_1 = icmp ult i32 %b, 10
107*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_0, %cond_1
108*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
109*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %loop, label %leave
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ult i32 %a, 10
112*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
113*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %leave
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Workerloop:
116*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp ult i32 %b, 10
117*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
118*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %leave
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerleave:
121*9880d681SAndroid Build Coastguard Worker  ret void
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker; Hoisting out of control flow is also fine if we can widen the
125*9880d681SAndroid Build Coastguard Worker; dominating check without doing any extra work.
126*9880d681SAndroid Build Coastguard Workerdefine void @f_5(i32 %a) {
127*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_5(
128*9880d681SAndroid Build Coastguard Workerentry:
129*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = icmp uge i32 %a, 11
130*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
131*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ugt i32 %a, 7
134*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
135*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Workerleft:
138*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp ugt i32 %a, 10
139*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Workerright:
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; Negative test: the load from %a can be safely speculated to before
147*9880d681SAndroid Build Coastguard Worker; the first guard, but there is no guarantee that it will produce the
148*9880d681SAndroid Build Coastguard Worker; same value.
149*9880d681SAndroid Build Coastguard Workerdefine void @f_6(i1* dereferenceable(32) %a, i1* %b, i1 %unknown) {
150*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_6(
151*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(
152*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(
153*9880d681SAndroid Build Coastguard Worker; CHECK: ret void
154*9880d681SAndroid Build Coastguard Workerentry:
155*9880d681SAndroid Build Coastguard Worker  %cond_0 = load i1, i1* %a
156*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
157*9880d681SAndroid Build Coastguard Worker  store i1 %unknown, i1* %b
158*9880d681SAndroid Build Coastguard Worker  %cond_1 = load i1, i1* %a
159*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
160*9880d681SAndroid Build Coastguard Worker  ret void
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker; All else equal, we try to widen the earliest guard we can.  This
164*9880d681SAndroid Build Coastguard Worker; heuristic can use some tuning.
165*9880d681SAndroid Build Coastguard Workerdefine void @f_7(i32 %a, i1* %cond_buf) {
166*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_7(
167*9880d681SAndroid Build Coastguard Workerentry:
168*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_1 = load volatile i1, i1* %cond_buf
169*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_3 = icmp ult i32 %a, 7
170*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_1, %cond_3
171*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
172*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_2 = load volatile i1, i1* %cond_buf
173*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ]
174*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker  %cond_1 = load volatile i1, i1* %cond_buf
177*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
178*9880d681SAndroid Build Coastguard Worker  %cond_2 = load volatile i1, i1* %cond_buf
179*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ]
180*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerleft:
183*9880d681SAndroid Build Coastguard Worker  %cond_3 = icmp ult i32 %a, 7
184*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ]
185*9880d681SAndroid Build Coastguard Worker  br label %left
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Workerright:
188*9880d681SAndroid Build Coastguard Worker  ret void
189*9880d681SAndroid Build Coastguard Worker}
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker; In this case the earliest dominating guard is in a loop, and we
192*9880d681SAndroid Build Coastguard Worker; don't want to put extra work in there.  This heuristic can use some
193*9880d681SAndroid Build Coastguard Worker; tuning.
194*9880d681SAndroid Build Coastguard Workerdefine void @f_8(i32 %a, i1 %cond_1, i1 %cond_2) {
195*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_8(
196*9880d681SAndroid Build Coastguard Workerentry:
197*9880d681SAndroid Build Coastguard Worker  br label %loop
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workerloop:
200*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
201*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %leave
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workerleave:
204*9880d681SAndroid Build Coastguard Worker; CHECK: leave:
205*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_3 = icmp ult i32 %a, 7
206*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_2, %cond_3
207*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
208*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %loop2, label %leave2
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"() ]
211*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop2, label %leave2
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Workerloop2:
214*9880d681SAndroid Build Coastguard Worker  %cond_3 = icmp ult i32 %a, 7
215*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_3) [ "deopt"() ]
216*9880d681SAndroid Build Coastguard Worker  br label %loop2
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Workerleave2:
219*9880d681SAndroid Build Coastguard Worker  ret void
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker; In cases like these where there isn't any "obviously profitable"
223*9880d681SAndroid Build Coastguard Worker; widening sites, we refuse to do anything.
224*9880d681SAndroid Build Coastguard Workerdefine void @f_9(i32 %a, i1 %cond_0, i1 %cond_1) {
225*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_9(
226*9880d681SAndroid Build Coastguard Workerentry:
227*9880d681SAndroid Build Coastguard Worker  br label %first_loop
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Workerfirst_loop:
230*9880d681SAndroid Build Coastguard Worker; CHECK: first_loop:
231*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
232*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %first_loop, label %second_loop
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
235*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %first_loop, label %second_loop
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workersecond_loop:
238*9880d681SAndroid Build Coastguard Worker; CHECK: second_loop:
239*9880d681SAndroid Build Coastguard Worker; CHECK:   call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
240*9880d681SAndroid Build Coastguard Worker; CHECK:   br label %second_loop
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
243*9880d681SAndroid Build Coastguard Worker  br label %second_loop
244*9880d681SAndroid Build Coastguard Worker}
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker; Same situation as in @f_9: no "obviously profitable" widening sites,
247*9880d681SAndroid Build Coastguard Worker; so we refuse to do anything.
248*9880d681SAndroid Build Coastguard Workerdefine void @f_10(i32 %a, i1 %cond_0, i1 %cond_1) {
249*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_10(
250*9880d681SAndroid Build Coastguard Workerentry:
251*9880d681SAndroid Build Coastguard Worker  br label %loop
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Workerloop:
254*9880d681SAndroid Build Coastguard Worker; CHECK: loop:
255*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
256*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %loop, label %no_loop
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
259*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop, label %no_loop
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Workerno_loop:
262*9880d681SAndroid Build Coastguard Worker; CHECK: no_loop:
263*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
264*9880d681SAndroid Build Coastguard Worker; CHECK:  ret void
265*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
266*9880d681SAndroid Build Coastguard Worker  ret void
267*9880d681SAndroid Build Coastguard Worker}
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker; With guards in loops, we're okay hoisting out the guard into the
270*9880d681SAndroid Build Coastguard Worker; containing loop.
271*9880d681SAndroid Build Coastguard Workerdefine void @f_11(i32 %a, i1 %cond_0, i1 %cond_1) {
272*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_11(
273*9880d681SAndroid Build Coastguard Workerentry:
274*9880d681SAndroid Build Coastguard Worker  br label %inner
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Workerinner:
277*9880d681SAndroid Build Coastguard Worker; CHECK: inner:
278*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = and i1 %cond_0, %cond_1
279*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
280*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %inner, label %outer
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
283*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %inner, label %outer
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Workerouter:
286*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
287*9880d681SAndroid Build Coastguard Worker  br label %inner
288*9880d681SAndroid Build Coastguard Worker}
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker; Checks that we are adequately guarded against exponential-time
291*9880d681SAndroid Build Coastguard Worker; behavior when hoisting code.
292*9880d681SAndroid Build Coastguard Workerdefine void @f_12(i32 %a0) {
293*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_12
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker; Eliding the earlier 29 multiplications for brevity
296*9880d681SAndroid Build Coastguard Worker; CHECK:  %a30 = mul i32 %a29, %a29
297*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %cond = trunc i32 %a30 to i1
298*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  %wide.chk = and i1 true, %cond
299*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
300*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:  ret void
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Workerentry:
303*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
304*9880d681SAndroid Build Coastguard Worker  %a1 = mul i32 %a0, %a0
305*9880d681SAndroid Build Coastguard Worker  %a2 = mul i32 %a1, %a1
306*9880d681SAndroid Build Coastguard Worker  %a3 = mul i32 %a2, %a2
307*9880d681SAndroid Build Coastguard Worker  %a4 = mul i32 %a3, %a3
308*9880d681SAndroid Build Coastguard Worker  %a5 = mul i32 %a4, %a4
309*9880d681SAndroid Build Coastguard Worker  %a6 = mul i32 %a5, %a5
310*9880d681SAndroid Build Coastguard Worker  %a7 = mul i32 %a6, %a6
311*9880d681SAndroid Build Coastguard Worker  %a8 = mul i32 %a7, %a7
312*9880d681SAndroid Build Coastguard Worker  %a9 = mul i32 %a8, %a8
313*9880d681SAndroid Build Coastguard Worker  %a10 = mul i32 %a9, %a9
314*9880d681SAndroid Build Coastguard Worker  %a11 = mul i32 %a10, %a10
315*9880d681SAndroid Build Coastguard Worker  %a12 = mul i32 %a11, %a11
316*9880d681SAndroid Build Coastguard Worker  %a13 = mul i32 %a12, %a12
317*9880d681SAndroid Build Coastguard Worker  %a14 = mul i32 %a13, %a13
318*9880d681SAndroid Build Coastguard Worker  %a15 = mul i32 %a14, %a14
319*9880d681SAndroid Build Coastguard Worker  %a16 = mul i32 %a15, %a15
320*9880d681SAndroid Build Coastguard Worker  %a17 = mul i32 %a16, %a16
321*9880d681SAndroid Build Coastguard Worker  %a18 = mul i32 %a17, %a17
322*9880d681SAndroid Build Coastguard Worker  %a19 = mul i32 %a18, %a18
323*9880d681SAndroid Build Coastguard Worker  %a20 = mul i32 %a19, %a19
324*9880d681SAndroid Build Coastguard Worker  %a21 = mul i32 %a20, %a20
325*9880d681SAndroid Build Coastguard Worker  %a22 = mul i32 %a21, %a21
326*9880d681SAndroid Build Coastguard Worker  %a23 = mul i32 %a22, %a22
327*9880d681SAndroid Build Coastguard Worker  %a24 = mul i32 %a23, %a23
328*9880d681SAndroid Build Coastguard Worker  %a25 = mul i32 %a24, %a24
329*9880d681SAndroid Build Coastguard Worker  %a26 = mul i32 %a25, %a25
330*9880d681SAndroid Build Coastguard Worker  %a27 = mul i32 %a26, %a26
331*9880d681SAndroid Build Coastguard Worker  %a28 = mul i32 %a27, %a27
332*9880d681SAndroid Build Coastguard Worker  %a29 = mul i32 %a28, %a28
333*9880d681SAndroid Build Coastguard Worker  %a30 = mul i32 %a29, %a29
334*9880d681SAndroid Build Coastguard Worker  %cond = trunc i32 %a30 to i1
335*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
336*9880d681SAndroid Build Coastguard Worker  ret void
337*9880d681SAndroid Build Coastguard Worker}
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Workerdefine void @f_13(i32 %a) {
340*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_13(
341*9880d681SAndroid Build Coastguard Workerentry:
342*9880d681SAndroid Build Coastguard Worker; CHECK:  %wide.chk = icmp ult i32 %a, 10
343*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
344*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ult i32 %a, 14
347*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
348*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Workerleft:
351*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp slt i32 %a, 10
352*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
353*9880d681SAndroid Build Coastguard Worker  ret void
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Workerright:
356*9880d681SAndroid Build Coastguard Worker  ret void
357*9880d681SAndroid Build Coastguard Worker}
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Workerdefine void @f_14(i32 %a) {
360*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @f_14(
361*9880d681SAndroid Build Coastguard Workerentry:
362*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_0 = icmp ult i32 %a, 14
363*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
364*9880d681SAndroid Build Coastguard Worker; CHECK:  br i1 undef, label %left, label %right
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker  %cond_0 = icmp ult i32 %a, 14
367*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
368*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %left, label %right
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Workerleft:
371*9880d681SAndroid Build Coastguard Worker; CHECK: left:
372*9880d681SAndroid Build Coastguard Worker; CHECK:  %cond_1 = icmp sgt i32 %a, 10
373*9880d681SAndroid Build Coastguard Worker; CHECK:  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker  %cond_1 = icmp sgt i32 %a, 10
376*9880d681SAndroid Build Coastguard Worker  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
377*9880d681SAndroid Build Coastguard Worker  ret void
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Workerright:
380*9880d681SAndroid Build Coastguard Worker  ret void
381*9880d681SAndroid Build Coastguard Worker}
382