d8ad067a1bfa4e1d1bc3faab4c71e6f11f7cea2c
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-ccmp.ll
1 ; RUN: llc < %s -mcpu=cyclone -verify-machineinstrs -aarch64-ccmp -aarch64-stress-ccmp | FileCheck %s
2 target triple = "arm64-apple-ios"
3
4 ; CHECK: single_same
5 ; CHECK: cmp w0, #5
6 ; CHECK-NEXT: ccmp w1, #17, #4, ne
7 ; CHECK-NEXT: b.ne
8 ; CHECK: %if.then
9 ; CHECK: bl _foo
10 ; CHECK: %if.end
11 define i32 @single_same(i32 %a, i32 %b) nounwind ssp {
12 entry:
13   %cmp = icmp eq i32 %a, 5
14   %cmp1 = icmp eq i32 %b, 17
15   %or.cond = or i1 %cmp, %cmp1
16   br i1 %or.cond, label %if.then, label %if.end
17
18 if.then:
19   %call = tail call i32 @foo() nounwind
20   br label %if.end
21
22 if.end:
23   ret i32 7
24 }
25
26 ; Different condition codes for the two compares.
27 ; CHECK: single_different
28 ; CHECK: cmp w0, #6
29 ; CHECK-NEXT: ccmp w1, #17, #0, ge
30 ; CHECK-NEXT: b.eq
31 ; CHECK: %if.then
32 ; CHECK: bl _foo
33 ; CHECK: %if.end
34 define i32 @single_different(i32 %a, i32 %b) nounwind ssp {
35 entry:
36   %cmp = icmp sle i32 %a, 5
37   %cmp1 = icmp ne i32 %b, 17
38   %or.cond = or i1 %cmp, %cmp1
39   br i1 %or.cond, label %if.then, label %if.end
40
41 if.then:
42   %call = tail call i32 @foo() nounwind
43   br label %if.end
44
45 if.end:
46   ret i32 7
47 }
48
49 ; Second block clobbers the flags, can't convert (easily).
50 ; CHECK: single_flagclobber
51 ; CHECK: cmp
52 ; CHECK: b.eq
53 ; CHECK: cmp
54 ; CHECK: b.gt
55 define i32 @single_flagclobber(i32 %a, i32 %b) nounwind ssp {
56 entry:
57   %cmp = icmp eq i32 %a, 5
58   br i1 %cmp, label %if.then, label %lor.lhs.false
59
60 lor.lhs.false:                                    ; preds = %entry
61   %cmp1 = icmp slt i32 %b, 7
62   %mul = shl nsw i32 %b, 1
63   %add = add nsw i32 %b, 1
64   %cond = select i1 %cmp1, i32 %mul, i32 %add
65   %cmp2 = icmp slt i32 %cond, 17
66   br i1 %cmp2, label %if.then, label %if.end
67
68 if.then:                                          ; preds = %lor.lhs.false, %entry
69   %call = tail call i32 @foo() nounwind
70   br label %if.end
71
72 if.end:                                           ; preds = %if.then, %lor.lhs.false
73   ret i32 7
74 }
75
76 ; Second block clobbers the flags and ends with a tbz terminator.
77 ; CHECK: single_flagclobber_tbz
78 ; CHECK: cmp
79 ; CHECK: b.eq
80 ; CHECK: cmp
81 ; CHECK: tbz
82 define i32 @single_flagclobber_tbz(i32 %a, i32 %b) nounwind ssp {
83 entry:
84   %cmp = icmp eq i32 %a, 5
85   br i1 %cmp, label %if.then, label %lor.lhs.false
86
87 lor.lhs.false:                                    ; preds = %entry
88   %cmp1 = icmp slt i32 %b, 7
89   %mul = shl nsw i32 %b, 1
90   %add = add nsw i32 %b, 1
91   %cond = select i1 %cmp1, i32 %mul, i32 %add
92   %and = and i32 %cond, 8
93   %cmp2 = icmp ne i32 %and, 0
94   br i1 %cmp2, label %if.then, label %if.end
95
96 if.then:                                          ; preds = %lor.lhs.false, %entry
97   %call = tail call i32 @foo() nounwind
98   br label %if.end
99
100 if.end:                                           ; preds = %if.then, %lor.lhs.false
101   ret i32 7
102 }
103
104 ; Speculatively execute division by zero.
105 ; The sdiv/udiv instructions do not trap when the divisor is zero, so they are
106 ; safe to speculate.
107 ; CHECK-LABEL: speculate_division:
108 ; CHECK: cmp w0, #1
109 ; CHECK: sdiv [[DIVRES:w[0-9]+]], w1, w0
110 ; CHECK: ccmp [[DIVRES]], #16, #0, ge
111 ; CHECK: b.gt [[BLOCK:LBB[0-9_]+]]
112 ; CHECK: bl _foo
113 ; CHECK: [[BLOCK]]:
114 ; CHECK: orr w0, wzr, #0x7
115 define i32 @speculate_division(i32 %a, i32 %b) nounwind ssp {
116 entry:
117   %cmp = icmp sgt i32 %a, 0
118   br i1 %cmp, label %land.lhs.true, label %if.end
119
120 land.lhs.true:
121   %div = sdiv i32 %b, %a
122   %cmp1 = icmp slt i32 %div, 17
123   br i1 %cmp1, label %if.then, label %if.end
124
125 if.then:
126   %call = tail call i32 @foo() nounwind
127   br label %if.end
128
129 if.end:
130   ret i32 7
131 }
132
133 ; Floating point compare.
134 ; CHECK: single_fcmp
135 ; CHECK: cmp
136 ; CHECK-NOT: b.
137 ; CHECK: fccmp {{.*}}, #8, ge
138 ; CHECK: b.lt
139 define i32 @single_fcmp(i32 %a, float %b) nounwind ssp {
140 entry:
141   %cmp = icmp sgt i32 %a, 0
142   br i1 %cmp, label %land.lhs.true, label %if.end
143
144 land.lhs.true:
145   %conv = sitofp i32 %a to float
146   %div = fdiv float %b, %conv
147   %cmp1 = fcmp oge float %div, 1.700000e+01
148   br i1 %cmp1, label %if.then, label %if.end
149
150 if.then:
151   %call = tail call i32 @foo() nounwind
152   br label %if.end
153
154 if.end:
155   ret i32 7
156 }
157
158 ; Chain multiple compares.
159 ; CHECK: multi_different
160 ; CHECK: cmp
161 ; CHECK: ccmp
162 ; CHECK: ccmp
163 ; CHECK: b.
164 define void @multi_different(i32 %a, i32 %b, i32 %c) nounwind ssp {
165 entry:
166   %cmp = icmp sgt i32 %a, %b
167   br i1 %cmp, label %land.lhs.true, label %if.end
168
169 land.lhs.true:
170   %div = sdiv i32 %b, %a
171   %cmp1 = icmp eq i32 %div, 5
172   %cmp4 = icmp sgt i32 %div, %c
173   %or.cond = and i1 %cmp1, %cmp4
174   br i1 %or.cond, label %if.then, label %if.end
175
176 if.then:
177   %call = tail call i32 @foo() nounwind
178   br label %if.end
179
180 if.end:
181   ret void
182 }
183
184 ; Convert a cbz in the head block.
185 ; CHECK: cbz_head
186 ; CHECK: cmp w0, #0
187 ; CHECK: ccmp
188 define i32 @cbz_head(i32 %a, i32 %b) nounwind ssp {
189 entry:
190   %cmp = icmp eq i32 %a, 0
191   %cmp1 = icmp ne i32 %b, 17
192   %or.cond = or i1 %cmp, %cmp1
193   br i1 %or.cond, label %if.then, label %if.end
194
195 if.then:
196   %call = tail call i32 @foo() nounwind
197   br label %if.end
198
199 if.end:
200   ret i32 7
201 }
202
203 ; Check that the immediate operand is in range. The ccmp instruction encodes a
204 ; smaller range of immediates than subs/adds.
205 ; The ccmp immediates must be in the range 0-31.
206 ; CHECK: immediate_range
207 ; CHECK-NOT: ccmp
208 define i32 @immediate_range(i32 %a, i32 %b) nounwind ssp {
209 entry:
210   %cmp = icmp eq i32 %a, 5
211   %cmp1 = icmp eq i32 %b, 32
212   %or.cond = or i1 %cmp, %cmp1
213   br i1 %or.cond, label %if.then, label %if.end
214
215 if.then:
216   %call = tail call i32 @foo() nounwind
217   br label %if.end
218
219 if.end:
220   ret i32 7
221 }
222
223 ; Convert a cbz in the second block.
224 ; CHECK: cbz_second
225 ; CHECK: cmp w0, #0
226 ; CHECK: ccmp w1, #0, #0, ne
227 ; CHECK: b.eq
228 define i32 @cbz_second(i32 %a, i32 %b) nounwind ssp {
229 entry:
230   %cmp = icmp eq i32 %a, 0
231   %cmp1 = icmp ne i32 %b, 0
232   %or.cond = or i1 %cmp, %cmp1
233   br i1 %or.cond, label %if.then, label %if.end
234
235 if.then:
236   %call = tail call i32 @foo() nounwind
237   br label %if.end
238
239 if.end:
240   ret i32 7
241 }
242
243 ; Convert a cbnz in the second block.
244 ; CHECK: cbnz_second
245 ; CHECK: cmp w0, #0
246 ; CHECK: ccmp w1, #0, #4, ne
247 ; CHECK: b.ne
248 define i32 @cbnz_second(i32 %a, i32 %b) nounwind ssp {
249 entry:
250   %cmp = icmp eq i32 %a, 0
251   %cmp1 = icmp eq i32 %b, 0
252   %or.cond = or i1 %cmp, %cmp1
253   br i1 %or.cond, label %if.then, label %if.end
254
255 if.then:
256   %call = tail call i32 @foo() nounwind
257   br label %if.end
258
259 if.end:
260   ret i32 7
261 }
262 declare i32 @foo()
263
264 %str1 = type { %str2 }
265 %str2 = type { [24 x i8], i8*, i32, %str1*, i32, [4 x i8], %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, %str1*, i8*, i8, i8*, %str1*, i8* }
266
267 ; Test case distilled from 126.gcc.
268 ; The phi in sw.bb.i.i gets multiple operands for the %entry predecessor.
269 ; CHECK: build_modify_expr
270 define void @build_modify_expr() nounwind ssp {
271 entry:
272   switch i32 undef, label %sw.bb.i.i [
273     i32 69, label %if.end85
274     i32 70, label %if.end85
275     i32 71, label %if.end85
276     i32 72, label %if.end85
277     i32 73, label %if.end85
278     i32 105, label %if.end85
279     i32 106, label %if.end85
280   ]
281
282 if.end85:
283   ret void
284
285 sw.bb.i.i:
286   %ref.tr.i.i = phi %str1* [ %0, %sw.bb.i.i ], [ undef, %entry ]
287   %operands.i.i = getelementptr inbounds %str1, %str1* %ref.tr.i.i, i64 0, i32 0, i32 2
288   %arrayidx.i.i = bitcast i32* %operands.i.i to %str1**
289   %0 = load %str1*, %str1** %arrayidx.i.i, align 8
290   %code1.i.i.phi.trans.insert = getelementptr inbounds %str1, %str1* %0, i64 0, i32 0, i32 0, i64 16
291   br label %sw.bb.i.i
292 }
293
294 ; CHECK-LABEL: select_and
295 define i64 @select_and(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
296 ; CHECK: cmp w1, #5
297 ; CHECK-NEXT: ccmp w0, w1, #0, ne
298 ; CHECK-NEXT: csel x0, x2, x3, lt
299 ; CHECK-NEXT: ret
300   %1 = icmp slt i32 %w0, %w1
301   %2 = icmp ne i32 5, %w1
302   %3 = and i1 %1, %2
303   %sel = select i1 %3, i64 %x2, i64 %x3
304   ret i64 %sel
305 }
306
307 ; CHECK-LABEL: select_or
308 define i64 @select_or(i32 %w0, i32 %w1, i64 %x2, i64 %x3) {
309 ; CHECK: cmp w1, #5
310 ; CHECK-NEXT: ccmp w0, w1, #8, eq
311 ; CHECK-NEXT: csel x0, x2, x3, lt
312 ; CHECK-NEXT: ret
313   %1 = icmp slt i32 %w0, %w1
314   %2 = icmp ne i32 5, %w1
315   %3 = or i1 %1, %2
316   %sel = select i1 %3, i64 %x2, i64 %x3
317   ret i64 %sel
318 }
319
320 ; CHECK-LABEL: select_complicated
321 define i16 @select_complicated(double %v1, double %v2, i16 %a, i16 %b) {
322 ; CHECK: ldr [[REG:d[0-9]+]],
323 ; CHECK: fcmp d0, d2
324 ; CHECK-NEXT: fmov d2, #13.00000000
325 ; CHECK-NEXT: fccmp d1, d2, #4, ne
326 ; CHECK-NEXT: fccmp d0, d1, #1, ne
327 ; CHECK-NEXT: fccmp d0, d1, #4, vc
328 ; CEHCK-NEXT: csel w0, w0, w1, eq
329   %1 = fcmp one double %v1, %v2
330   %2 = fcmp oeq double %v2, 13.0
331   %3 = fcmp oeq double %v1, 42.0
332   %or0 = or i1 %2, %3
333   %or1 = or i1 %1, %or0
334   %sel = select i1 %or1, i16 %a, i16 %b
335   ret i16 %sel
336 }
337
338 ; CHECK-LABEL: gccbug
339 define i64 @gccbug(i64 %x0, i64 %x1) {
340 ; CHECK: cmp x1, #0
341 ; CHECK-NEXT: ccmp x0, #2, #0, eq
342 ; CHECK-NEXT: ccmp x0, #4, #4, ne
343 ; CHECK-NEXT: orr w[[REGNUM:[0-9]+]], wzr, #0x1
344 ; CHECK-NEXT: cinc x0, x[[REGNUM]], eq
345 ; CHECK-NEXT: ret
346   %cmp0 = icmp eq i64 %x1, 0
347   %cmp1 = icmp eq i64 %x0, 2
348   %cmp2 = icmp eq i64 %x0, 4
349
350   %or = or i1 %cmp2, %cmp1
351   %and = and i1 %or, %cmp0
352
353   %sel = select i1 %and, i64 2, i64 1
354   ret i64 %sel
355 }
356
357 ; CHECK-LABEL: select_ororand
358 define i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
359 ; CHECK: cmp w3, #4
360 ; CHECK-NEXT: ccmp w2, #2, #0, gt
361 ; CHECK-NEXT: ccmp w1, #13, #2, ge
362 ; CHECK-NEXT: ccmp w0, #0, #4, ls
363 ; CHECK-NEXT: csel w0, w3, wzr, eq
364 ; CHECK-NEXT: ret
365   %c0 = icmp eq i32 %w0, 0
366   %c1 = icmp ugt i32 %w1, 13
367   %c2 = icmp slt i32 %w2, 2
368   %c4 = icmp sgt i32 %w3, 4
369   %or = or i1 %c0, %c1
370   %and = and i1 %c2, %c4
371   %or1 = or i1 %or, %and
372   %sel = select i1 %or1, i32 %w3, i32 0
373   ret i32 %sel
374 }
375
376 ; CHECK-LABEL: select_noccmp1
377 define i64 @select_noccmp1(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
378 ; CHECK-NOT: CCMP
379   %c0 = icmp slt i64 %v1, 0
380   %c1 = icmp sgt i64 %v1, 13
381   %c2 = icmp slt i64 %v3, 2
382   %c4 = icmp sgt i64 %v3, 4
383   %and0 = and i1 %c0, %c1
384   %and1 = and i1 %c2, %c4
385   %or = or i1 %and0, %and1
386   %sel = select i1 %or, i64 0, i64 %r
387   ret i64 %sel
388 }
389
390 @g = global i32 0
391
392 ; Should not use ccmp if we have to compute the or expression in an integer
393 ; register anyway because of other users.
394 ; CHECK-LABEL: select_noccmp2
395 define i64 @select_noccmp2(i64 %v1, i64 %v2, i64 %v3, i64 %r) {
396 ; CHECK-NOT: CCMP
397   %c0 = icmp slt i64 %v1, 0
398   %c1 = icmp sgt i64 %v1, 13
399   %or = or i1 %c0, %c1
400   %sel = select i1 %or, i64 0, i64 %r
401   %ext = sext i1 %or to i32
402   store volatile i32 %ext, i32* @g
403   ret i64 %sel
404 }