1; RUN: llc < %s -O1 -mtriple=aarch64-eabi -aarch64-enable-cond-br-tune=false | FileCheck %s
2
3declare void @t()
4
5define void @test1(i32 %a) {
6; CHECK-LABEL: @test1
7entry:
8  %sub = add nsw i32 %a, -12
9  %cmp = icmp slt i32 %sub, 0
10  br i1 %cmp, label %if.then, label %if.end
11
12; CHECK: sub [[CMP:w[0-9]+]], w0, #12
13; CHECK: tbnz [[CMP]], #31
14
15if.then:
16  call void @t()
17  br label %if.end
18
19if.end:
20  ret void
21}
22
23define void @test2(i64 %a) {
24; CHECK-LABEL: @test2
25entry:
26  %sub = add nsw i64 %a, -12
27  %cmp = icmp slt i64 %sub, 0
28  br i1 %cmp, label %if.then, label %if.end
29
30; CHECK: sub [[CMP:x[0-9]+]], x0, #12
31; CHECK: tbnz [[CMP]], #63
32
33if.then:
34  call void @t()
35  br label %if.end
36
37if.end:
38  ret void
39}
40
41define void @test3(i32 %a) {
42; CHECK-LABEL: @test3
43entry:
44  %sub = add nsw i32 %a, -12
45  %cmp = icmp sgt i32 %sub, -1
46  br i1 %cmp, label %if.then, label %if.end
47
48; CHECK: sub [[CMP:w[0-9]+]], w0, #12
49; CHECK: tbnz [[CMP]], #31
50
51if.then:
52  call void @t()
53  br label %if.end
54
55if.end:
56  ret void
57}
58
59define void @test4(i64 %a) {
60; CHECK-LABEL: @test4
61entry:
62  %sub = add nsw i64 %a, -12
63  %cmp = icmp sgt i64 %sub, -1
64  br i1 %cmp, label %if.then, label %if.end
65
66; CHECK: sub [[CMP:x[0-9]+]], x0, #12
67; CHECK: tbnz [[CMP]], #63
68
69if.then:
70  call void @t()
71  br label %if.end
72
73if.end:
74  ret void
75}
76
77define void @test5(i32 %a) {
78; CHECK-LABEL: @test5
79entry:
80  %sub = add nsw i32 %a, -12
81  %cmp = icmp sge i32 %sub, 0
82  br i1 %cmp, label %if.then, label %if.end
83
84; CHECK: sub [[CMP:w[0-9]+]], w0, #12
85; CHECK: tbnz [[CMP]], #31
86
87if.then:
88  call void @t()
89  br label %if.end
90
91if.end:
92  ret void
93}
94
95define void @test6(i64 %a) {
96; CHECK-LABEL: @test6
97entry:
98  %sub = add nsw i64 %a, -12
99  %cmp = icmp sge i64 %sub, 0
100  br i1 %cmp, label %if.then, label %if.end
101
102; CHECK: sub [[CMP:x[0-9]+]], x0, #12
103; CHECK: tbnz [[CMP]], #63
104
105if.then:
106  call void @t()
107  br label %if.end
108
109if.end:
110  ret void
111}
112
113define void @test7(i32 %a) {
114; CHECK-LABEL: @test7
115entry:
116  %sub = sub nsw i32 %a, 12
117  %cmp = icmp slt i32 %sub, 0
118  br i1 %cmp, label %if.then, label %if.end
119
120; CHECK: sub [[CMP:w[0-9]+]], w0, #12
121; CHECK: tbnz [[CMP]], #31
122
123if.then:
124  call void @t()
125  br label %if.end
126
127if.end:
128  ret void
129}
130
131define void @test8(i64 %val1, i64 %val2, i64 %val3) {
132; CHECK-LABEL: @test8
133  %and1 = and i64 %val1, %val2
134  %tst1 = icmp slt i64 %and1, 0
135  br i1 %tst1, label %if.then1, label %if.end
136
137; CHECK: tst x0, x1
138; CHECK-NEXT: b.ge
139
140if.then1:
141  %and2 = and i64 %val2, %val3
142  %tst2 = icmp sge i64 %and2, 0
143  br i1 %tst2, label %if.then2, label %if.end
144
145; CHECK: and [[CMP:x[0-9]+]], x1, x2
146; CHECK-NOT: cmp
147; CHECK: tbnz [[CMP]], #63
148
149if.then2:
150  %shifted_op1 = shl i64 %val2, 63
151  %shifted_and1 = and i64 %val1, %shifted_op1
152  %tst3 = icmp slt i64 %shifted_and1, 0
153  br i1 %tst3, label %if.then3, label %if.end
154
155; CHECK: tst x0, x1, lsl #63
156; CHECK: b.lt
157
158if.then3:
159  %shifted_op2 = shl i64 %val2, 62
160  %shifted_and2 = and i64 %val1, %shifted_op2
161  %tst4 = icmp sge i64 %shifted_and2, 0
162  br i1 %tst4, label %if.then4, label %if.end
163
164; CHECK: tst x0, x1, lsl #62
165; CHECK: b.lt
166
167if.then4:
168  call void @t()
169  br label %if.end
170
171if.end:
172  ret void
173}
174
175define void @test9(i64 %val1) {
176; CHECK-LABEL: @test9
177  %tst = icmp slt i64 %val1, 0
178  br i1 %tst, label %if.then, label %if.end
179
180; CHECK-NOT: cmp
181; CHECK: tbnz x0, #63
182
183if.then:
184  call void @t()
185  br label %if.end
186
187if.end:
188  ret void
189}
190
191define void @test10(i64 %val1) {
192; CHECK-LABEL: @test10
193  %tst = icmp slt i64 %val1, 0
194  br i1 %tst, label %if.then, label %if.end
195
196; CHECK-NOT: cmp
197; CHECK: tbnz x0, #63
198
199if.then:
200  call void @t()
201  br label %if.end
202
203if.end:
204  ret void
205}
206
207define void @test11(i64 %val1, i64* %ptr) {
208; CHECK-LABEL: @test11
209
210; CHECK: ldr [[CMP:x[0-9]+]], [x1]
211; CHECK-NOT: cmp
212; CHECK: tbnz [[CMP]], #63
213
214  %val = load i64, i64* %ptr
215  %tst = icmp slt i64 %val, 0
216  br i1 %tst, label %if.then, label %if.end
217
218if.then:
219  call void @t()
220  br label %if.end
221
222if.end:
223  ret void
224}
225
226define void @test12(i64 %val1) {
227; CHECK-LABEL: @test12
228  %tst = icmp slt i64 %val1, 0
229  br i1 %tst, label %if.then, label %if.end
230
231; CHECK-NOT: cmp
232; CHECK: tbnz x0, #63
233
234if.then:
235  call void @t()
236  br label %if.end
237
238if.end:
239  ret void
240}
241
242define void @test13(i64 %val1, i64 %val2) {
243; CHECK-LABEL: @test13
244  %or = or i64 %val1, %val2
245  %tst = icmp slt i64 %or, 0
246  br i1 %tst, label %if.then, label %if.end
247
248; CHECK: orr [[CMP:x[0-9]+]], x0, x1
249; CHECK-NOT: cmp
250; CHECK: tbnz [[CMP]], #63
251
252if.then:
253  call void @t()
254  br label %if.end
255
256if.end:
257  ret void
258}
259
260define void @test14(i1 %cond) {
261; CHECK-LABEL: @test14
262  br i1 %cond, label %if.end, label %if.then
263
264; CHECK-NOT: and
265; CHECK: tbnz w0, #0
266
267if.then:
268  call void @t()
269  br label %if.end
270
271if.end:
272  ret void
273}
274
275define void @test15(i1 %cond) {
276; CHECK-LABEL: @test15
277  %cond1 = xor i1 %cond, -1
278  br i1 %cond1, label %if.then, label %if.end
279
280; CHECK-NOT: movn
281; CHECK: tbnz w0, #0
282
283if.then:
284  call void @t()
285  br label %if.end
286
287if.end:
288  ret void
289}
290
291define void @test16(i64 %in) {
292; CHECK-LABEL: @test16
293  %shl = shl i64 %in, 3
294  %and = and i64 %shl, 32
295  %cond = icmp eq i64 %and, 0
296  br i1 %cond, label %then, label %end
297
298; CHECK-NOT: lsl
299; CHECK: tbnz w0, #2
300
301then:
302  call void @t()
303  br label %end
304
305end:
306  ret void
307}
308
309define void @test17(i64 %in) {
310; CHECK-LABEL: @test17
311  %shr = ashr i64 %in, 3
312  %and = and i64 %shr, 1
313  %cond = icmp eq i64 %and, 0
314  br i1 %cond, label %then, label %end
315
316; CHECK-NOT: lsr
317; CHECK: tbnz w0, #3
318
319then:
320  call void @t()
321  br label %end
322
323end:
324  ret void
325}
326
327define void @test18(i32 %in) {
328; CHECK-LABEL: @test18
329  %shr = ashr i32 %in, 2
330  %cond = icmp sge i32 %shr, 0
331  br i1 %cond, label %then, label %end
332
333; CHECK-NOT: asr
334; CHECK: tbnz w0, #31
335
336then:
337  call void @t()
338  br label %end
339
340end:
341  ret void
342}
343
344define void @test19(i64 %in) {
345; CHECK-LABEL: @test19
346  %shl = lshr i64 %in, 3
347  %trunc = trunc i64 %shl to i32
348  %and = and i32 %trunc, 1
349  %cond = icmp eq i32 %and, 0
350  br i1 %cond, label %then, label %end
351
352; CHECK-NOT: ubfx
353; CHECK: tbnz w0, #3
354
355then:
356  call void @t()
357  br label %end
358
359end:
360  ret void
361}
362
363define void @test20(i32 %in) nounwind {
364; CHECK-LABEL: test20:
365; CHECK:       // %bb.0:
366; CHECK-NEXT:    tbnz w0, #2, .LBB19_2
367; CHECK-NEXT:  // %bb.1: // %then
368; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
369; CHECK-NEXT:    bl t
370; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
371; CHECK-NEXT:  .LBB19_2: // %end
372; CHECK-NEXT:    ret
373  %shl = shl i32 %in, 3
374  %zext = zext i32 %shl to i64
375  %and = and i64 %zext, 32
376  %cond = icmp eq i64 %and, 0
377  br i1 %cond, label %then, label %end
378
379
380then:
381  call void @t()
382  br label %end
383
384end:
385  ret void
386}
387
388