[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / ARM / select-imm.ll
blob628bae6e1dc93f85935e4cd95e719a7e7ac2383b
1 ; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s --check-prefix=ARM
3 ; RUN: llc -mtriple=arm-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - \
4 ; RUN:  | FileCheck %s --check-prefix=ARMT2
6 ; RUN: llc -mtriple=thumb-eabi -mcpu=cortex-m0 %s -o - \
7 ; RUN:  | FileCheck %s --check-prefix=THUMB1
9 ; RUN: llc -mtriple=thumb-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - \
10 ; RUN:  | FileCheck %s --check-prefix=THUMB2
12 ; RUN: llc -mtriple=thumbv8m.base-eabi %s -o - \
13 ; RUN:  | FileCheck %s --check-prefix=V8MBASE
15 define i32 @t1(i32 %c) nounwind readnone {
16 entry:
17 ; ARM-LABEL: t1:
18 ; ARM: mov [[R1:r[0-9]+]], #101
19 ; ARM: orr [[R1b:r[0-9]+]], [[R1]], #256
20 ; ARM: movgt {{r[0-1]}}, #123
22 ; ARMT2-LABEL: t1:
23 ; ARMT2: movw [[R:r[0-1]]], #357
24 ; ARMT2: movwgt [[R]], #123
26 ; THUMB1-LABEL: t1:
27 ; THUMB1: cmp     r0, #1
28 ; THUMB1: bgt     .LBB0_2
30 ; THUMB2-LABEL: t1:
31 ; THUMB2: movw [[R:r[0-1]]], #357
32 ; THUMB2: movgt [[R]], #123
34   %0 = icmp sgt i32 %c, 1
35   %1 = select i1 %0, i32 123, i32 357
36   ret i32 %1
39 define i32 @t2(i32 %c) nounwind readnone {
40 entry:
41 ; ARM-LABEL: t2:
42 ; ARM: mov [[R:r[0-9]+]], #101
43 ; ARM: orr [[R]], [[R]], #256
44 ; ARM: movle [[R]], #123
46 ; ARMT2-LABEL: t2:
47 ; ARMT2: mov [[R:r[0-1]]], #123
48 ; ARMT2: movwgt [[R]], #357
50 ; THUMB1-LABEL: t2:
51 ; THUMB1: cmp r{{[0-9]+}}, #1
52 ; THUMB1: bgt
54 ; THUMB2-LABEL: t2:
55 ; THUMB2: mov{{(s|\.w)}} [[R:r[0-1]]], #123
56 ; THUMB2: movwgt [[R]], #357
58   %0 = icmp sgt i32 %c, 1
59   %1 = select i1 %0, i32 357, i32 123
60   ret i32 %1
63 define i32 @t3(i32 %a) nounwind readnone {
64 entry:
65 ; ARM-LABEL: t3:
66 ; ARM: rsbs r1, r0, #0
67 ; ARM: adc  r0, r0, r1
69 ; ARMT2-LABEL: t3:
70 ; ARMT2: clz r0, r0
71 ; ARMT2: lsr r0, r0, #5
73 ; THUMB1-LABEL: t3:
74 ; THUMB1: rsbs r1, r0, #0
75 ; THUMB1: adcs r0, r1
77 ; THUMB2-LABEL: t3:
78 ; THUMB2: clz r0, r0
79 ; THUMB2: lsrs r0, r0, #5
80   %0 = icmp eq i32 %a, 160
81   %1 = zext i1 %0 to i32
82   ret i32 %1
85 define i32 @t4(i32 %a, i32 %b, i32 %x) nounwind {
86 entry:
87 ; ARM-LABEL: t4:
88 ; ARM: ldr
89 ; ARM: mov{{lt|ge}}
91 ; ARMT2-LABEL: t4:
92 ; ARMT2: movwlt [[R0:r[0-9]+]], #65365
93 ; ARMT2: movtlt [[R0]], #65365
95 ; THUMB1-LABEL: t4:
96 ; THUMB1: cmp r{{[0-9]+}}, r{{[0-9]+}}
97 ; THUMB1: b{{lt|ge}}
99 ; THUMB2-LABEL: t4:
100 ; THUMB2: mvnlt [[R0:r[0-9]+]], #11141290
101   %0 = icmp slt i32 %a, %b
102   %1 = select i1 %0, i32 4283826005, i32 %x
103   ret i32 %1
106 ; rdar://9758317
107 define i32 @t5(i32 %a) nounwind {
108 entry:
109 ; ARM-LABEL: t5:
110 ; ARM-NOT: mov
111 ; ARM: sub  r0, r0, #1
112 ; ARM-NOT: mov
113 ; ARM: rsbs r1, r0, #0
114 ; ARM: adc  r0, r0, r1
116 ; THUMB1-LABEL: t5:
117 ; THUMB1-NOT: bne
118 ; THUMB1: rsbs r0, r1, #0
119 ; THUMB1: adcs r0, r1
121 ; THUMB2-LABEL: t5:
122 ; THUMB2-NOT: mov
123 ; THUMB2: subs r0, #1
124 ; THUMB2: clz  r0, r0
125 ; THUMB2: lsrs r0, r0, #5
127   %cmp = icmp eq i32 %a, 1
128   %conv = zext i1 %cmp to i32
129   ret i32 %conv
132 define i32 @t6(i32 %a) nounwind {
133 entry:
134 ; ARM-LABEL: t6:
135 ; ARM-NOT: mov
136 ; ARM: cmp r0, #0
137 ; ARM: movne r0, #1
139 ; THUMB1-LABEL: t6:
140 ; THUMB1: subs r1, r0, #1
141 ; THUMB1: sbcs r0, r1
143 ; THUMB2-LABEL: t6:
144 ; THUMB2-NOT: mov
145 ; THUMB2: cmp r0, #0
146 ; THUMB2: it ne
147 ; THUMB2: movne r0, #1
148   %tobool = icmp ne i32 %a, 0
149   %lnot.ext = zext i1 %tobool to i32
150   ret i32 %lnot.ext
153 define i32 @t7(i32 %a, i32 %b) nounwind readnone {
154 entry:
155 ; ARM-LABEL: t7:
156 ; ARM: subs r0, r0, r1
157 ; ARM: movne   r0, #1
158 ; ARM: lsl     r0, r0, #2
160 ; ARMT2-LABEL: t7:
161 ; ARMT2: subs r0, r0, r1
162 ; ARMT2: movwne r0, #1
163 ; ARMT2: lsl     r0, r0, #2
165 ; THUMB1-LABEL: t7:
166 ; THUMB1: subs r0, r0, r1
167 ; THUMB1: subs r1, r0, #1
168 ; THUMB1: sbcs r0, r1
169 ; THUMB1: lsls r0, r0, #2
171 ; THUMB2-LABEL: t7:
172 ; THUMB2: subs r0, r0, r1
173 ; THUMB2: it ne
174 ; THUMB2: movne r0, #1
175 ; THUMB2: lsls    r0, r0, #2
176   %0 = icmp ne i32 %a, %b
177   %1 = select i1 %0, i32 4, i32 0
178   ret i32 %1
181 define void @t8(i32 %a) {
182 entry:
184 ; ARM scheduler emits icmp/zext before both calls, so isn't relevant
186 ; ARMT2-LABEL: t8:
187 ; ARMT2: bl t7
188 ; ARMT2: mov r1, r0
189 ; ARMT2: sub r0, r4, #5
190 ; ARMT2: clz r0, r0
191 ; ARMT2: lsr r0, r0, #5
193 ; THUMB1-LABEL: t8:
194 ; THUMB1: bl t7
195 ; THUMB1: mov r1, r0
196 ; THUMB1: subs r2, r4, #5
197 ; THUMB1: rsbs r0, r2, #0
198 ; THUMB1: adcs r0, r2
200 ; THUMB2-LABEL: t8:
201 ; THUMB2: bl t7
202 ; THUMB2: mov r1, r0
203 ; THUMB2: subs r0, r4, #5
204 ; THUMB2: clz r0, r0
205 ; THUMB2: lsrs r0, r0, #5
207   %cmp = icmp eq i32 %a, 5
208   %conv = zext i1 %cmp to i32
209   %call = tail call i32 @t7(i32 9, i32 %a)
210   tail call i32 @t7(i32 %conv, i32 %call)
211   ret void
214 define void @t9(i8* %a, i8 %b) {
215 entry:
217 ; ARM scheduler emits icmp/zext before both calls, so isn't relevant
219 ; ARMT2-LABEL: t9:
220 ; ARMT2: bl f
221 ; ARMT2: uxtb r0, r4
222 ; ARMT2: cmp  r0, r0
223 ; ARMT2: add  r1, r4, #1
224 ; ARMT2: mov  r2, r0
225 ; ARMT2: add  r2, r2, #1
226 ; ARMT2: add  r1, r1, #1
227 ; ARMT2: uxtb r3, r2
228 ; ARMT2: cmp  r3, r0
230 ; THUMB1-LABEL: t9:
231 ; THUMB1: bl f
232 ; THUMB1: sxtb r1, r4
233 ; THUMB1: uxtb r0, r1
234 ; THUMB1: cmp  r0, r0
235 ; THUMB1: adds r1, r1, #1
236 ; THUMB1: mov  r2, r0
237 ; THUMB1: adds r1, r1, #1
238 ; THUMB1: adds r2, r2, #1
239 ; THUMB1: uxtb r3, r2
240 ; THUMB1: cmp  r3, r0
242 ; THUMB2-LABEL: t9:
243 ; THUMB2: bl f
244 ; THUMB2: uxtb r0, r4
245 ; THUMB2: cmp  r0, r0
246 ; THUMB2: adds r1, r4, #1
247 ; THUMB2: mov  r2, r0
248 ; THUMB2: adds r2, #1
249 ; THUMB2: adds r1, #1
250 ; THUMB2: uxtb r3, r2
251 ; THUMB2: cmp  r3, r0
253   %0 = load i8, i8* %a
254   %conv = sext i8 %0 to i32
255   %conv119 = zext i8 %0 to i32
256   %conv522 = and i32 %conv, 255
257   %cmp723 = icmp eq i32 %conv522, %conv119
258   tail call void @f(i1 zeroext %cmp723)
259   br i1 %cmp723, label %while.body, label %while.end
261 while.body:                                       ; preds = %entry, %while.body
262   %ref.025 = phi i8 [ %inc9, %while.body ], [ %0, %entry ]
263   %in.024 = phi i32 [ %inc, %while.body ], [ %conv, %entry ]
264   %inc = add i32 %in.024, 1
265   %inc9 = add i8 %ref.025, 1
266   %conv1 = zext i8 %inc9 to i32
267   %cmp = icmp slt i32 %conv1, %conv119
268   %conv5 = and i32 %inc, 255
269   br i1 %cmp, label %while.body, label %while.end
271 while.end:
272   ret void
275 declare void @f(i1 zeroext)
278 define i1 @t10() {
279 entry:
280   %q = alloca i32
281   %p = alloca i32
282   store i32 -3, i32* %q
283   store i32 -8, i32* %p
284   %0 = load i32, i32* %q
285   %1 = load i32, i32* %p
286   %div = sdiv i32 %0, %1
287   %mul = mul nsw i32 %div, %1
288   %rem = srem i32 %0, %1
289   %add = add nsw i32 %mul, %rem
290   %cmp = icmp eq i32 %add, %0
291   ret i1 %cmp
293 ; ARM-LABEL: t10:
294 ; ARM: rsbs r1, r0, #0
295 ; ARM: adc  r0, r0, r1
297 ; ARMT2-LABEL: t10:
298 ; ARMT2: clz r0, r0
299 ; ARMT2: lsr r0, r0, #5
301 ; THUMB1-LABEL: t10:
302 ; THUMB1: rsbs r0, r1, #0
303 ; THUMB1: adcs r0, r1
305 ; THUMB2-LABEL: t10:
306 ; THUMB2: clz r0, r0
307 ; THUMB2: lsrs r0, r0, #5
309 ; V8MBASE-LABEL: t10:
310 ; V8MBASE-NOT: movs r0, #0
311 ; V8MBASE: movs r0, #7
314 define i1 @t11() {
315 entry:
316   %bit = alloca i32
317   %load = load i32, i32* %bit
318   %clear = and i32 %load, -4096
319   %set = or i32 %clear, 33
320   store i32 %set, i32* %bit
321   %load1 = load i32, i32* %bit
322   %clear2 = and i32 %load1, -33550337
323   %set3 = or i32 %clear2, 40960
324   %clear5 = and i32 %set3, 4095
325   %rem = srem i32 %clear5, 10
326   %clear9 = and i32 %set3, -4096
327   %set10 = or i32 %clear9, %rem
328   store i32 %set10, i32* %bit
329   %clear12 = and i32 %set10, 4095
330   %cmp = icmp eq i32 %clear12, 3
331   ret i1 %cmp
333 ; ARM-LABEL: t11:
334 ; ARM: rsbs r1, r0, #0
335 ; ARM: adc  r0, r0, r1
337 ; ARMT2-LABEL: t11:
338 ; ARMT2: clz r0, r0
339 ; ARMT2: lsr r0, r0, #5
341 ; THUMB1-LABEL: t11:
342 ; THUMB1-NOT: movs r0, #0
343 ; THUMB1: movs r0, #5
345 ; THUMB2-LABEL: t11:
346 ; THUMB2: clz r0, r0
347 ; THUMB2: lsrs r0, r0, #5
349 ; V8MBASE-LABEL: t11:
350 ; V8MBASE-NOT: movs r0, #0
351 ; V8MBASE: movw r0, #40960
354 define i32 @t12(i32 %a) nounwind {
355 entry:
356 ; ARM-LABEL: t12:
357 ; ARM-NOT: mov
358 ; ARM: cmp r0, #0
359 ; ARM: movne r0, #1
361 ; THUMB1-LABEL: t12:
362 ; THUMB1: subs r1, r0, #1
363 ; THUMB1: sbcs r0, r1
364 ; THUMB1: lsls r0, r0, #1
366 ; THUMB2-LABEL: t12:
367 ; THUMB2-NOT: mov
368 ; THUMB2: cmp r0, #0
369 ; THUMB2: it ne
370 ; THUMB2: movne r0, #1
371   %tobool = icmp ne i32 %a, 0
372   %lnot.ext = select i1 %tobool, i32 2, i32 0
373   ret i32 %lnot.ext
376 define i32 @t13(i32 %a) nounwind {
377 entry:
378 ; ARM-LABEL: t13:
379 ; ARM-NOT: mov
380 ; ARM: cmp r0, #0
381 ; ARM: movne r0, #3
383 ; THUMB1-LABEL: t13:
384 ; THUMB1: cmp r0, #0
385 ; THUMB1: beq
386 ; THUMB1: movs r0, #3
388 ; THUMB2-LABEL: t13:
389 ; THUMB2-NOT: mov
390 ; THUMB2: cmp r0, #0
391 ; THUMB2: it ne
392 ; THUMB2: movne r0, #3
393   %tobool = icmp ne i32 %a, 0
394   %lnot.ext = select i1 %tobool, i32 3, i32 0
395   ret i32 %lnot.ext