xref: /llvm-project/llvm/test/CodeGen/ARM/select_xform.ll (revision bed1c7f061aa12417aa081e334afdba45767b938)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm-- -mcpu=cortex-a8 | FileCheck %s -check-prefixes=CHECK,ARM
3; RUN: llc < %s -mtriple=thumb-- -mcpu=cortex-a8 | FileCheck %s -check-prefixes=CHECK,T2
4; rdar://8662825
5
6define i32 @t1(i32 %a, i32 %b, i32 %c) nounwind {
7; ARM-LABEL: t1:
8; ARM:       @ %bb.0:
9; ARM-NEXT:    mov r0, r1
10; ARM-NEXT:    cmp r2, #10
11; ARM-NEXT:    suble r0, r0, #-2147483647
12; ARM-NEXT:    bx lr
13;
14; T2-LABEL: t1:
15; T2:       @ %bb.0:
16; T2-NEXT:    mov r0, r1
17; T2-NEXT:    mvn r1, #-2147483648
18; T2-NEXT:    cmp r2, #10
19; T2-NEXT:    it le
20; T2-NEXT:    addle r0, r1
21; T2-NEXT:    bx lr
22  %tmp1 = icmp sgt i32 %c, 10
23  %tmp2 = select i1 %tmp1, i32 0, i32 2147483647
24  %tmp3 = add i32 %tmp2, %b
25  ret i32 %tmp3
26}
27
28define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
29; ARM-LABEL: t2:
30; ARM:       @ %bb.0:
31; ARM-NEXT:    mov r0, r1
32; ARM-NEXT:    cmp r2, #10
33; ARM-NEXT:    suble r0, r0, #10
34; ARM-NEXT:    bx lr
35;
36; T2-LABEL: t2:
37; T2:       @ %bb.0:
38; T2-NEXT:    mov r0, r1
39; T2-NEXT:    cmp r2, #10
40; T2-NEXT:    it le
41; T2-NEXT:    suble r0, #10
42; T2-NEXT:    bx lr
43  %tmp1 = icmp sgt i32 %c, 10
44  %tmp2 = select i1 %tmp1, i32 0, i32 10
45  %tmp3 = sub i32 %b, %tmp2
46  ret i32 %tmp3
47}
48
49define i32 @t3(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
50; ARM-LABEL: t3:
51; ARM:       @ %bb.0:
52; ARM-NEXT:    cmp r0, r1
53; ARM-NEXT:    andge r3, r3, r2
54; ARM-NEXT:    mov r0, r3
55; ARM-NEXT:    bx lr
56;
57; T2-LABEL: t3:
58; T2:       @ %bb.0:
59; T2-NEXT:    cmp r0, r1
60; T2-NEXT:    it ge
61; T2-NEXT:    andge r3, r2
62; T2-NEXT:    mov r0, r3
63; T2-NEXT:    bx lr
64  %cond = icmp slt i32 %a, %b
65  %z = select i1 %cond, i32 -1, i32 %x
66  %s = and i32 %z, %y
67 ret i32 %s
68}
69
70define i32 @t4(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
71; ARM-LABEL: t4:
72; ARM:       @ %bb.0:
73; ARM-NEXT:    cmp r0, r1
74; ARM-NEXT:    orrge r3, r3, r2
75; ARM-NEXT:    mov r0, r3
76; ARM-NEXT:    bx lr
77;
78; T2-LABEL: t4:
79; T2:       @ %bb.0:
80; T2-NEXT:    cmp r0, r1
81; T2-NEXT:    it ge
82; T2-NEXT:    orrge r3, r2
83; T2-NEXT:    mov r0, r3
84; T2-NEXT:    bx lr
85  %cond = icmp slt i32 %a, %b
86  %z = select i1 %cond, i32 0, i32 %x
87  %s = or i32 %z, %y
88 ret i32 %s
89}
90
91define i32 @t5(i32 %a, i32 %b, i32 %c) nounwind {
92; ARM-LABEL: t5:
93; ARM:       @ %bb.0: @ %entry
94; ARM-NEXT:    cmp r0, r1
95; ARM-NEXT:    orreq r2, r2, #1
96; ARM-NEXT:    mov r0, r2
97; ARM-NEXT:    bx lr
98;
99; T2-LABEL: t5:
100; T2:       @ %bb.0: @ %entry
101; T2-NEXT:    cmp r0, r1
102; T2-NEXT:    it eq
103; T2-NEXT:    orreq r2, r2, #1
104; T2-NEXT:    mov r0, r2
105; T2-NEXT:    bx lr
106entry:
107  %tmp1 = icmp eq i32 %a, %b
108  %tmp2 = zext i1 %tmp1 to i32
109  %tmp3 = or i32 %tmp2, %c
110  ret i32 %tmp3
111}
112
113define i32 @t6(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
114; ARM-LABEL: t6:
115; ARM:       @ %bb.0:
116; ARM-NEXT:    cmp r0, r1
117; ARM-NEXT:    eorlt r3, r3, r2
118; ARM-NEXT:    mov r0, r3
119; ARM-NEXT:    bx lr
120;
121; T2-LABEL: t6:
122; T2:       @ %bb.0:
123; T2-NEXT:    cmp r0, r1
124; T2-NEXT:    it lt
125; T2-NEXT:    eorlt r3, r2
126; T2-NEXT:    mov r0, r3
127; T2-NEXT:    bx lr
128  %cond = icmp slt i32 %a, %b
129  %tmp1 = select i1 %cond, i32 %c, i32 0
130  %tmp2 = xor i32 %tmp1, %d
131  ret i32 %tmp2
132}
133
134define i32 @t7(i32 %a, i32 %b, i32 %c) nounwind {
135; ARM-LABEL: t7:
136; ARM:       @ %bb.0: @ %entry
137; ARM-NEXT:    cmp r0, r1
138; ARM-NEXT:    andeq r2, r2, r2, lsl #1
139; ARM-NEXT:    mov r0, r2
140; ARM-NEXT:    bx lr
141;
142; T2-LABEL: t7:
143; T2:       @ %bb.0: @ %entry
144; T2-NEXT:    cmp r0, r1
145; T2-NEXT:    it eq
146; T2-NEXT:    andeq.w r2, r2, r2, lsl #1
147; T2-NEXT:    mov r0, r2
148; T2-NEXT:    bx lr
149entry:
150  %tmp1 = shl i32 %c, 1
151  %cond = icmp eq i32 %a, %b
152  %tmp2 = select i1 %cond, i32 %tmp1, i32 -1
153  %tmp3 = and i32 %c, %tmp2
154  ret i32 %tmp3
155}
156
157; Fold ORRri into movcc.
158define i32 @t8(i32 %a, i32 %b) nounwind {
159; ARM-LABEL: t8:
160; ARM:       @ %bb.0:
161; ARM-NEXT:    cmp r0, r1
162; ARM-NEXT:    orrge r0, r1, #1
163; ARM-NEXT:    bx lr
164;
165; T2-LABEL: t8:
166; T2:       @ %bb.0:
167; T2-NEXT:    cmp r0, r1
168; T2-NEXT:    it ge
169; T2-NEXT:    orrge r0, r1, #1
170; T2-NEXT:    bx lr
171  %x = or i32 %b, 1
172  %cond = icmp slt i32 %a, %b
173  %tmp1 = select i1 %cond, i32 %a, i32 %x
174  ret i32 %tmp1
175}
176
177; Fold ANDrr into movcc.
178define i32 @t9(i32 %a, i32 %b, i32 %c) nounwind {
179; ARM-LABEL: t9:
180; ARM:       @ %bb.0:
181; ARM-NEXT:    cmp r0, r1
182; ARM-NEXT:    andge r0, r1, r2
183; ARM-NEXT:    bx lr
184;
185; T2-LABEL: t9:
186; T2:       @ %bb.0:
187; T2-NEXT:    cmp r0, r1
188; T2-NEXT:    it ge
189; T2-NEXT:    andge.w r0, r1, r2
190; T2-NEXT:    bx lr
191  %x = and i32 %b, %c
192  %cond = icmp slt i32 %a, %b
193  %tmp1 = select i1 %cond, i32 %a, i32 %x
194  ret i32 %tmp1
195}
196
197; Fold EORrs into movcc.
198define i32 @t10(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
199; ARM-LABEL: t10:
200; ARM:       @ %bb.0:
201; ARM-NEXT:    cmp r0, r1
202; ARM-NEXT:    eorge r0, r1, r2, lsl #7
203; ARM-NEXT:    bx lr
204;
205; T2-LABEL: t10:
206; T2:       @ %bb.0:
207; T2-NEXT:    cmp r0, r1
208; T2-NEXT:    it ge
209; T2-NEXT:    eorge.w r0, r1, r2, lsl #7
210; T2-NEXT:    bx lr
211  %s = shl i32 %c, 7
212  %x = xor i32 %b, %s
213  %cond = icmp slt i32 %a, %b
214  %tmp1 = select i1 %cond, i32 %a, i32 %x
215  ret i32 %tmp1
216}
217
218; Fold ORRri into movcc, reversing the condition.
219define i32 @t11(i32 %a, i32 %b) nounwind {
220; ARM-LABEL: t11:
221; ARM:       @ %bb.0:
222; ARM-NEXT:    cmp r0, r1
223; ARM-NEXT:    orrlt r0, r1, #1
224; ARM-NEXT:    bx lr
225;
226; T2-LABEL: t11:
227; T2:       @ %bb.0:
228; T2-NEXT:    cmp r0, r1
229; T2-NEXT:    it lt
230; T2-NEXT:    orrlt r0, r1, #1
231; T2-NEXT:    bx lr
232  %x = or i32 %b, 1
233  %cond = icmp slt i32 %a, %b
234  %tmp1 = select i1 %cond, i32 %x, i32 %a
235  ret i32 %tmp1
236}
237
238; Fold ADDri12 into movcc
239define i32 @t12(i32 %a, i32 %b) nounwind {
240; ARM-LABEL: t12:
241; ARM:       @ %bb.0:
242; ARM-NEXT:    cmp r0, r1
243; ARM-NEXT:    movw r2, #3000
244; ARM-NEXT:    addge r0, r1, r2
245; ARM-NEXT:    bx lr
246;
247; T2-LABEL: t12:
248; T2:       @ %bb.0:
249; T2-NEXT:    cmp r0, r1
250; T2-NEXT:    it ge
251; T2-NEXT:    addwge r0, r1, #3000
252; T2-NEXT:    bx lr
253  %x = add i32 %b, 3000
254  %cond = icmp slt i32 %a, %b
255  %tmp1 = select i1 %cond, i32 %a, i32 %x
256  ret i32 %tmp1
257}
258
259; Handle frame index operands.
260define void @pr13628() nounwind uwtable align 2 {
261; ARM-LABEL: pr13628:
262; ARM:       @ %bb.0:
263; ARM-NEXT:    push {r11, lr}
264; ARM-NEXT:    sub sp, sp, #256
265; ARM-NEXT:    ldrb r1, [r0]
266; ARM-NEXT:    mov r0, sp
267; ARM-NEXT:    cmp r1, #0
268; ARM-NEXT:    moveq r0, r1
269; ARM-NEXT:    bl bar
270; ARM-NEXT:    add sp, sp, #256
271; ARM-NEXT:    pop {r11, pc}
272;
273; T2-LABEL: pr13628:
274; T2:       @ %bb.0:
275; T2-NEXT:    push {r7, lr}
276; T2-NEXT:    sub sp, #256
277; T2-NEXT:    ldrb r1, [r0]
278; T2-NEXT:    mov r0, sp
279; T2-NEXT:    cmp r1, #0
280; T2-NEXT:    it eq
281; T2-NEXT:    moveq r0, r1
282; T2-NEXT:    bl bar
283; T2-NEXT:    add sp, #256
284; T2-NEXT:    pop {r7, pc}
285  %x3 = alloca i8, i32 256, align 8
286  %x4 = load i8, ptr undef, align 1
287  %x5 = icmp ne i8 %x4, 0
288  %x6 = select i1 %x5, ptr %x3, ptr null
289  call void @bar(ptr %x6) nounwind
290  ret void
291}
292declare void @bar(ptr)
293
294; Fold zext i1 into predicated add
295define i32 @t13(i32 %c, i32 %a) nounwind readnone ssp {
296; ARM-LABEL: t13:
297; ARM:       @ %bb.0: @ %entry
298; ARM-NEXT:    cmp r1, #10
299; ARM-NEXT:    addgt r0, r0, #1
300; ARM-NEXT:    bx lr
301;
302; T2-LABEL: t13:
303; T2:       @ %bb.0: @ %entry
304; T2-NEXT:    cmp r1, #10
305; T2-NEXT:    it gt
306; T2-NEXT:    addgt r0, #1
307; T2-NEXT:    bx lr
308entry:
309  %cmp = icmp sgt i32 %a, 10
310  %conv = zext i1 %cmp to i32
311  %add = add i32 %conv, %c
312  ret i32 %add
313}
314
315; Fold sext i1 into predicated sub
316define i32 @t14(i32 %c, i32 %a) nounwind readnone ssp {
317; ARM-LABEL: t14:
318; ARM:       @ %bb.0: @ %entry
319; ARM-NEXT:    cmp r1, #10
320; ARM-NEXT:    subgt r0, r0, #1
321; ARM-NEXT:    bx lr
322;
323; T2-LABEL: t14:
324; T2:       @ %bb.0: @ %entry
325; T2-NEXT:    cmp r1, #10
326; T2-NEXT:    it gt
327; T2-NEXT:    subgt r0, #1
328; T2-NEXT:    bx lr
329entry:
330  %cmp = icmp sgt i32 %a, 10
331  %conv = sext i1 %cmp to i32
332  %add = add i32 %conv, %c
333  ret i32 %add
334}
335
336; Fold the xor into the select.
337define i32 @t15(i32 %p) {
338; ARM-LABEL: t15:
339; ARM:       @ %bb.0: @ %entry
340; ARM-NEXT:    mov r1, #3
341; ARM-NEXT:    cmp r0, #8
342; ARM-NEXT:    movwgt r1, #0
343; ARM-NEXT:    mov r0, r1
344; ARM-NEXT:    bx lr
345;
346; T2-LABEL: t15:
347; T2:       @ %bb.0: @ %entry
348; T2-NEXT:    movs r1, #3
349; T2-NEXT:    cmp r0, #8
350; T2-NEXT:    it gt
351; T2-NEXT:    movgt r1, #0
352; T2-NEXT:    mov r0, r1
353; T2-NEXT:    bx lr
354entry:
355  %cmp = icmp sgt i32 %p, 8
356  %a = select i1 %cmp, i32 1, i32 2
357  %xor = xor i32 %a, 1
358  ret i32 %xor
359}
360
361define i32 @t16(i32 %x, i32 %y) {
362; ARM-LABEL: t16:
363; ARM:       @ %bb.0: @ %entry
364; ARM-NEXT:    cmp r0, #0
365; ARM-NEXT:    mov r2, #2
366; ARM-NEXT:    movweq r2, #5
367; ARM-NEXT:    mov r0, #4
368; ARM-NEXT:    cmp r1, #0
369; ARM-NEXT:    movweq r0, #3
370; ARM-NEXT:    and r0, r0, r2
371; ARM-NEXT:    bx lr
372;
373; T2-LABEL: t16:
374; T2:       @ %bb.0: @ %entry
375; T2-NEXT:    cmp r0, #0
376; T2-NEXT:    mov.w r2, #2
377; T2-NEXT:    mov.w r0, #4
378; T2-NEXT:    it eq
379; T2-NEXT:    moveq r2, #5
380; T2-NEXT:    cmp r1, #0
381; T2-NEXT:    it eq
382; T2-NEXT:    moveq r0, #3
383; T2-NEXT:    ands r0, r2
384; T2-NEXT:    bx lr
385entry:
386  %cmp = icmp eq i32 %x, 0
387  %cond = select i1 %cmp, i32 5, i32 2
388  %cmp1 = icmp eq i32 %y, 0
389  %cond2 = select i1 %cmp1, i32 3, i32 4
390  %and = and i32 %cond2, %cond
391  ret i32 %and
392}
393
394define i32 @t17(i32 %x, i32 %y) #0 {
395; ARM-LABEL: t17:
396; ARM:       @ %bb.0: @ %entry
397; ARM-NEXT:    cmn r0, #1
398; ARM-NEXT:    mov r2, #2
399; ARM-NEXT:    movweq r2, #5
400; ARM-NEXT:    mov r0, #4
401; ARM-NEXT:    cmn r1, #1
402; ARM-NEXT:    movweq r0, #3
403; ARM-NEXT:    and r0, r0, r2
404; ARM-NEXT:    bx lr
405;
406; T2-LABEL: t17:
407; T2:       @ %bb.0: @ %entry
408; T2-NEXT:    adds r0, #1
409; T2-NEXT:    mov.w r0, #2
410; T2-NEXT:    it eq
411; T2-NEXT:    moveq r0, #5
412; T2-NEXT:    adds r1, #1
413; T2-NEXT:    mov.w r1, #4
414; T2-NEXT:    it eq
415; T2-NEXT:    moveq r1, #3
416; T2-NEXT:    ands r0, r1
417; T2-NEXT:    bx lr
418entry:
419  %cmp = icmp eq i32 %x, -1
420  %cond = select i1 %cmp, i32 5, i32 2
421  %cmp1 = icmp eq i32 %y, -1
422  %cond2 = select i1 %cmp1, i32 3, i32 4
423  %and = and i32 %cond2, %cond
424  ret i32 %and
425}
426
427define i32 @t18(i32 %x, i32 %y) #0 {
428; ARM-LABEL: t18:
429; ARM:       @ %bb.0: @ %entry
430; ARM-NEXT:    mov r1, #2
431; ARM-NEXT:    cmp r0, #0
432; ARM-NEXT:    movwne r1, #5
433; ARM-NEXT:    mov r2, #4
434; ARM-NEXT:    cmn r0, #1
435; ARM-NEXT:    movwne r2, #3
436; ARM-NEXT:    and r0, r2, r1
437; ARM-NEXT:    bx lr
438;
439; T2-LABEL: t18:
440; T2:       @ %bb.0: @ %entry
441; T2-NEXT:    movs r1, #2
442; T2-NEXT:    cmp r0, #0
443; T2-NEXT:    it ne
444; T2-NEXT:    movne r1, #5
445; T2-NEXT:    adds r0, #1
446; T2-NEXT:    mov.w r0, #4
447; T2-NEXT:    it ne
448; T2-NEXT:    movne r0, #3
449; T2-NEXT:    ands r0, r1
450; T2-NEXT:    bx lr
451entry:
452  %cmp = icmp ne i32 %x, 0
453  %cond = select i1 %cmp, i32 5, i32 2
454  %cmp1 = icmp ne i32 %x, -1
455  %cond2 = select i1 %cmp1, i32 3, i32 4
456  %and = and i32 %cond2, %cond
457  ret i32 %and
458}
459
460define i32 @t19(i32 %x, i32 %y) #0 {
461; ARM-LABEL: t19:
462; ARM:       @ %bb.0: @ %entry
463; ARM-NEXT:    cmp r0, #0
464; ARM-NEXT:    mov r2, #2
465; ARM-NEXT:    movwne r2, #5
466; ARM-NEXT:    mov r0, #4
467; ARM-NEXT:    cmp r1, #0
468; ARM-NEXT:    movwne r0, #3
469; ARM-NEXT:    orr r0, r0, r2
470; ARM-NEXT:    bx lr
471;
472; T2-LABEL: t19:
473; T2:       @ %bb.0: @ %entry
474; T2-NEXT:    cmp r0, #0
475; T2-NEXT:    mov.w r2, #2
476; T2-NEXT:    mov.w r0, #4
477; T2-NEXT:    it ne
478; T2-NEXT:    movne r2, #5
479; T2-NEXT:    cmp r1, #0
480; T2-NEXT:    it ne
481; T2-NEXT:    movne r0, #3
482; T2-NEXT:    orrs r0, r2
483; T2-NEXT:    bx lr
484entry:
485  %cmp = icmp ne i32 %x, 0
486  %cond = select i1 %cmp, i32 5, i32 2
487  %cmp1 = icmp ne i32 %y, 0
488  %cond2 = select i1 %cmp1, i32 3, i32 4
489  %or = or i32 %cond2, %cond
490  ret i32 %or
491}
492
493define i32 @t20(i32 %x, i32 %y) #0 {
494; ARM-LABEL: t20:
495; ARM:       @ %bb.0: @ %entry
496; ARM-NEXT:    cmn r0, #1
497; ARM-NEXT:    mov r2, #2
498; ARM-NEXT:    movwne r2, #5
499; ARM-NEXT:    mov r0, #4
500; ARM-NEXT:    cmn r1, #1
501; ARM-NEXT:    movwne r0, #3
502; ARM-NEXT:    orr r0, r0, r2
503; ARM-NEXT:    bx lr
504;
505; T2-LABEL: t20:
506; T2:       @ %bb.0: @ %entry
507; T2-NEXT:    adds r0, #1
508; T2-NEXT:    mov.w r0, #2
509; T2-NEXT:    it ne
510; T2-NEXT:    movne r0, #5
511; T2-NEXT:    adds r1, #1
512; T2-NEXT:    mov.w r1, #4
513; T2-NEXT:    it ne
514; T2-NEXT:    movne r1, #3
515; T2-NEXT:    orrs r0, r1
516; T2-NEXT:    bx lr
517entry:
518  %cmp = icmp ne i32 %x, -1
519  %cond = select i1 %cmp, i32 5, i32 2
520  %cmp1 = icmp ne i32 %y, -1
521  %cond2 = select i1 %cmp1, i32 3, i32 4
522  %or = or i32 %cond2, %cond
523  ret i32 %or
524}
525
526define  <2 x i32> @t21(<2 x i32> %lhs, <2 x i32> %rhs) {
527; CHECK-LABEL: t21:
528; CHECK:       @ %bb.0:
529; CHECK-NEXT:    vmov d16, r2, r3
530; CHECK-NEXT:    vmov d17, r0, r1
531; CHECK-NEXT:    vceq.i32 d16, d17, d16
532; CHECK-NEXT:    vmvn d16, d16
533; CHECK-NEXT:    vshl.i32 d16, d16, #31
534; CHECK-NEXT:    vshr.s32 d16, d16, #31
535; CHECK-NEXT:    vmov r0, r1, d16
536; CHECK-NEXT:    bx lr
537  %tst = icmp eq <2 x i32> %lhs, %rhs
538  %ntst = xor <2 x i1> %tst, <i1 1 , i1 undef>
539  %btst = sext <2 x i1> %ntst to <2 x i32>
540  ret <2 x i32> %btst
541}
542