xref: /llvm-project/llvm/test/CodeGen/ARM/select_const.ll (revision 021b613cdc9091092e3429f36abdbe89a988681d)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=arm-eabi-unknown-unknown | FileCheck %s --check-prefix=ARM
3; RUN: llc < %s -mtriple=thumbv6t2-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB2
4; RUN: llc < %s -mtriple=thumb-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB
5
6; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?).
7; Test the zeroext/signext variants of each pattern to see if that makes a difference.
8
9; select Cond, 0, 1 --> zext (!Cond)
10
11define i32 @select_0_or_1(i1 %cond) {
12; ARM-LABEL: select_0_or_1:
13; ARM:       @ %bb.0:
14; ARM-NEXT:    mov r1, #1
15; ARM-NEXT:    bic r0, r1, r0
16; ARM-NEXT:    mov pc, lr
17;
18; THUMB2-LABEL: select_0_or_1:
19; THUMB2:       @ %bb.0:
20; THUMB2-NEXT:    movs r1, #1
21; THUMB2-NEXT:    bic.w r0, r1, r0
22; THUMB2-NEXT:    bx lr
23;
24; THUMB-LABEL: select_0_or_1:
25; THUMB:       @ %bb.0:
26; THUMB-NEXT:    movs r1, #1
27; THUMB-NEXT:    bics r1, r0
28; THUMB-NEXT:    movs r0, r1
29; THUMB-NEXT:    bx lr
30  %sel = select i1 %cond, i32 0, i32 1
31  ret i32 %sel
32}
33
34define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
35; ARM-LABEL: select_0_or_1_zeroext:
36; ARM:       @ %bb.0:
37; ARM-NEXT:    eor r0, r0, #1
38; ARM-NEXT:    mov pc, lr
39;
40; THUMB2-LABEL: select_0_or_1_zeroext:
41; THUMB2:       @ %bb.0:
42; THUMB2-NEXT:    eor r0, r0, #1
43; THUMB2-NEXT:    bx lr
44;
45; THUMB-LABEL: select_0_or_1_zeroext:
46; THUMB:       @ %bb.0:
47; THUMB-NEXT:    movs r1, #1
48; THUMB-NEXT:    eors r0, r1
49; THUMB-NEXT:    bx lr
50  %sel = select i1 %cond, i32 0, i32 1
51  ret i32 %sel
52}
53
54define i32 @select_0_or_1_signext(i1 signext %cond) {
55; ARM-LABEL: select_0_or_1_signext:
56; ARM:       @ %bb.0:
57; ARM-NEXT:    mov r1, #1
58; ARM-NEXT:    bic r0, r1, r0
59; ARM-NEXT:    mov pc, lr
60;
61; THUMB2-LABEL: select_0_or_1_signext:
62; THUMB2:       @ %bb.0:
63; THUMB2-NEXT:    movs r1, #1
64; THUMB2-NEXT:    bic.w r0, r1, r0
65; THUMB2-NEXT:    bx lr
66;
67; THUMB-LABEL: select_0_or_1_signext:
68; THUMB:       @ %bb.0:
69; THUMB-NEXT:    movs r1, #1
70; THUMB-NEXT:    bics r1, r0
71; THUMB-NEXT:    movs r0, r1
72; THUMB-NEXT:    bx lr
73  %sel = select i1 %cond, i32 0, i32 1
74  ret i32 %sel
75}
76
77; select Cond, 1, 0 --> zext (Cond)
78
79define i32 @select_1_or_0(i1 %cond) {
80; ARM-LABEL: select_1_or_0:
81; ARM:       @ %bb.0:
82; ARM-NEXT:    and r0, r0, #1
83; ARM-NEXT:    mov pc, lr
84;
85; THUMB2-LABEL: select_1_or_0:
86; THUMB2:       @ %bb.0:
87; THUMB2-NEXT:    and r0, r0, #1
88; THUMB2-NEXT:    bx lr
89;
90; THUMB-LABEL: select_1_or_0:
91; THUMB:       @ %bb.0:
92; THUMB-NEXT:    movs r1, #1
93; THUMB-NEXT:    ands r0, r1
94; THUMB-NEXT:    bx lr
95  %sel = select i1 %cond, i32 1, i32 0
96  ret i32 %sel
97}
98
99define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
100; ARM-LABEL: select_1_or_0_zeroext:
101; ARM:       @ %bb.0:
102; ARM-NEXT:    mov pc, lr
103;
104; THUMB2-LABEL: select_1_or_0_zeroext:
105; THUMB2:       @ %bb.0:
106; THUMB2-NEXT:    bx lr
107;
108; THUMB-LABEL: select_1_or_0_zeroext:
109; THUMB:       @ %bb.0:
110; THUMB-NEXT:    bx lr
111  %sel = select i1 %cond, i32 1, i32 0
112  ret i32 %sel
113}
114
115define i32 @select_1_or_0_signext(i1 signext %cond) {
116; ARM-LABEL: select_1_or_0_signext:
117; ARM:       @ %bb.0:
118; ARM-NEXT:    and r0, r0, #1
119; ARM-NEXT:    mov pc, lr
120;
121; THUMB2-LABEL: select_1_or_0_signext:
122; THUMB2:       @ %bb.0:
123; THUMB2-NEXT:    and r0, r0, #1
124; THUMB2-NEXT:    bx lr
125;
126; THUMB-LABEL: select_1_or_0_signext:
127; THUMB:       @ %bb.0:
128; THUMB-NEXT:    movs r1, #1
129; THUMB-NEXT:    ands r0, r1
130; THUMB-NEXT:    bx lr
131  %sel = select i1 %cond, i32 1, i32 0
132  ret i32 %sel
133}
134
135; select Cond, 0, -1 --> sext (!Cond)
136
137define i32 @select_0_or_neg1(i1 %cond) {
138; ARM-LABEL: select_0_or_neg1:
139; ARM:       @ %bb.0:
140; ARM-NEXT:    mov r1, #1
141; ARM-NEXT:    bic r0, r1, r0
142; ARM-NEXT:    rsb r0, r0, #0
143; ARM-NEXT:    mov pc, lr
144;
145; THUMB2-LABEL: select_0_or_neg1:
146; THUMB2:       @ %bb.0:
147; THUMB2-NEXT:    movs r1, #1
148; THUMB2-NEXT:    bic.w r0, r1, r0
149; THUMB2-NEXT:    rsbs r0, r0, #0
150; THUMB2-NEXT:    bx lr
151;
152; THUMB-LABEL: select_0_or_neg1:
153; THUMB:       @ %bb.0:
154; THUMB-NEXT:    movs r1, #1
155; THUMB-NEXT:    bics r1, r0
156; THUMB-NEXT:    rsbs r0, r1, #0
157; THUMB-NEXT:    bx lr
158  %sel = select i1 %cond, i32 0, i32 -1
159  ret i32 %sel
160}
161
162define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
163; ARM-LABEL: select_0_or_neg1_zeroext:
164; ARM:       @ %bb.0:
165; ARM-NEXT:    eor r0, r0, #1
166; ARM-NEXT:    rsb r0, r0, #0
167; ARM-NEXT:    mov pc, lr
168;
169; THUMB2-LABEL: select_0_or_neg1_zeroext:
170; THUMB2:       @ %bb.0:
171; THUMB2-NEXT:    eor r0, r0, #1
172; THUMB2-NEXT:    rsbs r0, r0, #0
173; THUMB2-NEXT:    bx lr
174;
175; THUMB-LABEL: select_0_or_neg1_zeroext:
176; THUMB:       @ %bb.0:
177; THUMB-NEXT:    movs r1, #1
178; THUMB-NEXT:    eors r1, r0
179; THUMB-NEXT:    rsbs r0, r1, #0
180; THUMB-NEXT:    bx lr
181  %sel = select i1 %cond, i32 0, i32 -1
182  ret i32 %sel
183}
184
185define i32 @select_0_or_neg1_signext(i1 signext %cond) {
186; ARM-LABEL: select_0_or_neg1_signext:
187; ARM:       @ %bb.0:
188; ARM-NEXT:    mvn r0, r0
189; ARM-NEXT:    mov pc, lr
190;
191; THUMB2-LABEL: select_0_or_neg1_signext:
192; THUMB2:       @ %bb.0:
193; THUMB2-NEXT:    mvns r0, r0
194; THUMB2-NEXT:    bx lr
195;
196; THUMB-LABEL: select_0_or_neg1_signext:
197; THUMB:       @ %bb.0:
198; THUMB-NEXT:    mvns r0, r0
199; THUMB-NEXT:    bx lr
200  %sel = select i1 %cond, i32 0, i32 -1
201  ret i32 %sel
202}
203
204define i32 @select_0_or_neg1_alt(i1 %cond) {
205; ARM-LABEL: select_0_or_neg1_alt:
206; ARM:       @ %bb.0:
207; ARM-NEXT:    and r0, r0, #1
208; ARM-NEXT:    sub r0, r0, #1
209; ARM-NEXT:    mov pc, lr
210;
211; THUMB2-LABEL: select_0_or_neg1_alt:
212; THUMB2:       @ %bb.0:
213; THUMB2-NEXT:    and r0, r0, #1
214; THUMB2-NEXT:    subs r0, #1
215; THUMB2-NEXT:    bx lr
216;
217; THUMB-LABEL: select_0_or_neg1_alt:
218; THUMB:       @ %bb.0:
219; THUMB-NEXT:    movs r1, #1
220; THUMB-NEXT:    ands r1, r0
221; THUMB-NEXT:    subs r0, r1, #1
222; THUMB-NEXT:    bx lr
223  %z = zext i1 %cond to i32
224  %add = add i32 %z, -1
225  ret i32 %add
226}
227
228define i32 @select_0_or_neg1_alt_zeroext(i1 zeroext %cond) {
229; ARM-LABEL: select_0_or_neg1_alt_zeroext:
230; ARM:       @ %bb.0:
231; ARM-NEXT:    sub r0, r0, #1
232; ARM-NEXT:    mov pc, lr
233;
234; THUMB2-LABEL: select_0_or_neg1_alt_zeroext:
235; THUMB2:       @ %bb.0:
236; THUMB2-NEXT:    subs r0, #1
237; THUMB2-NEXT:    bx lr
238;
239; THUMB-LABEL: select_0_or_neg1_alt_zeroext:
240; THUMB:       @ %bb.0:
241; THUMB-NEXT:    subs r0, r0, #1
242; THUMB-NEXT:    bx lr
243  %z = zext i1 %cond to i32
244  %add = add i32 %z, -1
245  ret i32 %add
246}
247
248define i32 @select_0_or_neg1_alt_signext(i1 signext %cond) {
249; ARM-LABEL: select_0_or_neg1_alt_signext:
250; ARM:       @ %bb.0:
251; ARM-NEXT:    mvn r0, r0
252; ARM-NEXT:    mov pc, lr
253;
254; THUMB2-LABEL: select_0_or_neg1_alt_signext:
255; THUMB2:       @ %bb.0:
256; THUMB2-NEXT:    mvns r0, r0
257; THUMB2-NEXT:    bx lr
258;
259; THUMB-LABEL: select_0_or_neg1_alt_signext:
260; THUMB:       @ %bb.0:
261; THUMB-NEXT:    mvns r0, r0
262; THUMB-NEXT:    bx lr
263  %z = zext i1 %cond to i32
264  %add = add i32 %z, -1
265  ret i32 %add
266}
267
268; select Cond, -1, 0 --> sext (Cond)
269
270define i32 @select_neg1_or_0(i1 %cond) {
271; ARM-LABEL: select_neg1_or_0:
272; ARM:       @ %bb.0:
273; ARM-NEXT:    and r0, r0, #1
274; ARM-NEXT:    rsb r0, r0, #0
275; ARM-NEXT:    mov pc, lr
276;
277; THUMB2-LABEL: select_neg1_or_0:
278; THUMB2:       @ %bb.0:
279; THUMB2-NEXT:    and r0, r0, #1
280; THUMB2-NEXT:    rsbs r0, r0, #0
281; THUMB2-NEXT:    bx lr
282;
283; THUMB-LABEL: select_neg1_or_0:
284; THUMB:       @ %bb.0:
285; THUMB-NEXT:    movs r1, #1
286; THUMB-NEXT:    ands r1, r0
287; THUMB-NEXT:    rsbs r0, r1, #0
288; THUMB-NEXT:    bx lr
289  %sel = select i1 %cond, i32 -1, i32 0
290  ret i32 %sel
291}
292
293define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
294; ARM-LABEL: select_neg1_or_0_zeroext:
295; ARM:       @ %bb.0:
296; ARM-NEXT:    rsb r0, r0, #0
297; ARM-NEXT:    mov pc, lr
298;
299; THUMB2-LABEL: select_neg1_or_0_zeroext:
300; THUMB2:       @ %bb.0:
301; THUMB2-NEXT:    rsbs r0, r0, #0
302; THUMB2-NEXT:    bx lr
303;
304; THUMB-LABEL: select_neg1_or_0_zeroext:
305; THUMB:       @ %bb.0:
306; THUMB-NEXT:    rsbs r0, r0, #0
307; THUMB-NEXT:    bx lr
308  %sel = select i1 %cond, i32 -1, i32 0
309  ret i32 %sel
310}
311
312define i32 @select_neg1_or_0_signext(i1 signext %cond) {
313; ARM-LABEL: select_neg1_or_0_signext:
314; ARM:       @ %bb.0:
315; ARM-NEXT:    mov pc, lr
316;
317; THUMB2-LABEL: select_neg1_or_0_signext:
318; THUMB2:       @ %bb.0:
319; THUMB2-NEXT:    bx lr
320;
321; THUMB-LABEL: select_neg1_or_0_signext:
322; THUMB:       @ %bb.0:
323; THUMB-NEXT:    bx lr
324  %sel = select i1 %cond, i32 -1, i32 0
325  ret i32 %sel
326}
327
328; select Cond, C+1, C --> add (zext Cond), C
329
330define i32 @select_Cplus1_C(i1 %cond) {
331; ARM-LABEL: select_Cplus1_C:
332; ARM:       @ %bb.0:
333; ARM-NEXT:    mov r1, #41
334; ARM-NEXT:    tst r0, #1
335; ARM-NEXT:    movne r1, #42
336; ARM-NEXT:    mov r0, r1
337; ARM-NEXT:    mov pc, lr
338;
339; THUMB2-LABEL: select_Cplus1_C:
340; THUMB2:       @ %bb.0:
341; THUMB2-NEXT:    lsls r0, r0, #31
342; THUMB2-NEXT:    mov.w r0, #41
343; THUMB2-NEXT:    it ne
344; THUMB2-NEXT:    movne r0, #42
345; THUMB2-NEXT:    bx lr
346;
347; THUMB-LABEL: select_Cplus1_C:
348; THUMB:       @ %bb.0:
349; THUMB-NEXT:    lsls r0, r0, #31
350; THUMB-NEXT:    bne .LBB15_2
351; THUMB-NEXT:  @ %bb.1:
352; THUMB-NEXT:    movs r0, #41
353; THUMB-NEXT:    bx lr
354; THUMB-NEXT:  .LBB15_2:
355; THUMB-NEXT:    movs r0, #42
356; THUMB-NEXT:    bx lr
357  %sel = select i1 %cond, i32 42, i32 41
358  ret i32 %sel
359}
360
361define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
362; ARM-LABEL: select_Cplus1_C_zeroext:
363; ARM:       @ %bb.0:
364; ARM-NEXT:    mov r1, #41
365; ARM-NEXT:    cmp r0, #0
366; ARM-NEXT:    movne r1, #42
367; ARM-NEXT:    mov r0, r1
368; ARM-NEXT:    mov pc, lr
369;
370; THUMB2-LABEL: select_Cplus1_C_zeroext:
371; THUMB2:       @ %bb.0:
372; THUMB2-NEXT:    movs r1, #41
373; THUMB2-NEXT:    cmp r0, #0
374; THUMB2-NEXT:    it ne
375; THUMB2-NEXT:    movne r1, #42
376; THUMB2-NEXT:    mov r0, r1
377; THUMB2-NEXT:    bx lr
378;
379; THUMB-LABEL: select_Cplus1_C_zeroext:
380; THUMB:       @ %bb.0:
381; THUMB-NEXT:    cmp r0, #0
382; THUMB-NEXT:    bne .LBB16_2
383; THUMB-NEXT:  @ %bb.1:
384; THUMB-NEXT:    movs r0, #41
385; THUMB-NEXT:    bx lr
386; THUMB-NEXT:  .LBB16_2:
387; THUMB-NEXT:    movs r0, #42
388; THUMB-NEXT:    bx lr
389  %sel = select i1 %cond, i32 42, i32 41
390  ret i32 %sel
391}
392
393define i32 @select_Cplus1_C_signext(i1 signext %cond) {
394; ARM-LABEL: select_Cplus1_C_signext:
395; ARM:       @ %bb.0:
396; ARM-NEXT:    mov r1, #41
397; ARM-NEXT:    tst r0, #1
398; ARM-NEXT:    movne r1, #42
399; ARM-NEXT:    mov r0, r1
400; ARM-NEXT:    mov pc, lr
401;
402; THUMB2-LABEL: select_Cplus1_C_signext:
403; THUMB2:       @ %bb.0:
404; THUMB2-NEXT:    lsls r0, r0, #31
405; THUMB2-NEXT:    mov.w r0, #41
406; THUMB2-NEXT:    it ne
407; THUMB2-NEXT:    movne r0, #42
408; THUMB2-NEXT:    bx lr
409;
410; THUMB-LABEL: select_Cplus1_C_signext:
411; THUMB:       @ %bb.0:
412; THUMB-NEXT:    lsls r0, r0, #31
413; THUMB-NEXT:    bne .LBB17_2
414; THUMB-NEXT:  @ %bb.1:
415; THUMB-NEXT:    movs r0, #41
416; THUMB-NEXT:    bx lr
417; THUMB-NEXT:  .LBB17_2:
418; THUMB-NEXT:    movs r0, #42
419; THUMB-NEXT:    bx lr
420  %sel = select i1 %cond, i32 42, i32 41
421  ret i32 %sel
422}
423
424; select Cond, C, C+1 --> add (sext Cond), C
425
426define i32 @select_C_Cplus1(i1 %cond) {
427; ARM-LABEL: select_C_Cplus1:
428; ARM:       @ %bb.0:
429; ARM-NEXT:    mov r1, #42
430; ARM-NEXT:    tst r0, #1
431; ARM-NEXT:    movne r1, #41
432; ARM-NEXT:    mov r0, r1
433; ARM-NEXT:    mov pc, lr
434;
435; THUMB2-LABEL: select_C_Cplus1:
436; THUMB2:       @ %bb.0:
437; THUMB2-NEXT:    lsls r0, r0, #31
438; THUMB2-NEXT:    mov.w r0, #42
439; THUMB2-NEXT:    it ne
440; THUMB2-NEXT:    movne r0, #41
441; THUMB2-NEXT:    bx lr
442;
443; THUMB-LABEL: select_C_Cplus1:
444; THUMB:       @ %bb.0:
445; THUMB-NEXT:    lsls r0, r0, #31
446; THUMB-NEXT:    bne .LBB18_2
447; THUMB-NEXT:  @ %bb.1:
448; THUMB-NEXT:    movs r0, #42
449; THUMB-NEXT:    bx lr
450; THUMB-NEXT:  .LBB18_2:
451; THUMB-NEXT:    movs r0, #41
452; THUMB-NEXT:    bx lr
453  %sel = select i1 %cond, i32 41, i32 42
454  ret i32 %sel
455}
456
457define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
458; ARM-LABEL: select_C_Cplus1_zeroext:
459; ARM:       @ %bb.0:
460; ARM-NEXT:    mov r1, #42
461; ARM-NEXT:    cmp r0, #0
462; ARM-NEXT:    movne r1, #41
463; ARM-NEXT:    mov r0, r1
464; ARM-NEXT:    mov pc, lr
465;
466; THUMB2-LABEL: select_C_Cplus1_zeroext:
467; THUMB2:       @ %bb.0:
468; THUMB2-NEXT:    movs r1, #42
469; THUMB2-NEXT:    cmp r0, #0
470; THUMB2-NEXT:    it ne
471; THUMB2-NEXT:    movne r1, #41
472; THUMB2-NEXT:    mov r0, r1
473; THUMB2-NEXT:    bx lr
474;
475; THUMB-LABEL: select_C_Cplus1_zeroext:
476; THUMB:       @ %bb.0:
477; THUMB-NEXT:    cmp r0, #0
478; THUMB-NEXT:    bne .LBB19_2
479; THUMB-NEXT:  @ %bb.1:
480; THUMB-NEXT:    movs r0, #42
481; THUMB-NEXT:    bx lr
482; THUMB-NEXT:  .LBB19_2:
483; THUMB-NEXT:    movs r0, #41
484; THUMB-NEXT:    bx lr
485  %sel = select i1 %cond, i32 41, i32 42
486  ret i32 %sel
487}
488
489define i32 @select_C_Cplus1_signext(i1 signext %cond) {
490; ARM-LABEL: select_C_Cplus1_signext:
491; ARM:       @ %bb.0:
492; ARM-NEXT:    mov r1, #42
493; ARM-NEXT:    tst r0, #1
494; ARM-NEXT:    movne r1, #41
495; ARM-NEXT:    mov r0, r1
496; ARM-NEXT:    mov pc, lr
497;
498; THUMB2-LABEL: select_C_Cplus1_signext:
499; THUMB2:       @ %bb.0:
500; THUMB2-NEXT:    lsls r0, r0, #31
501; THUMB2-NEXT:    mov.w r0, #42
502; THUMB2-NEXT:    it ne
503; THUMB2-NEXT:    movne r0, #41
504; THUMB2-NEXT:    bx lr
505;
506; THUMB-LABEL: select_C_Cplus1_signext:
507; THUMB:       @ %bb.0:
508; THUMB-NEXT:    lsls r0, r0, #31
509; THUMB-NEXT:    bne .LBB20_2
510; THUMB-NEXT:  @ %bb.1:
511; THUMB-NEXT:    movs r0, #42
512; THUMB-NEXT:    bx lr
513; THUMB-NEXT:  .LBB20_2:
514; THUMB-NEXT:    movs r0, #41
515; THUMB-NEXT:    bx lr
516  %sel = select i1 %cond, i32 41, i32 42
517  ret i32 %sel
518}
519
520; In general, select of 2 constants could be:
521; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
522
523define i32 @select_C1_C2(i1 %cond) {
524; ARM-LABEL: select_C1_C2:
525; ARM:       @ %bb.0:
526; ARM-NEXT:    mov r1, #165
527; ARM-NEXT:    tst r0, #1
528; ARM-NEXT:    orr r1, r1, #256
529; ARM-NEXT:    moveq r1, #42
530; ARM-NEXT:    mov r0, r1
531; ARM-NEXT:    mov pc, lr
532;
533; THUMB2-LABEL: select_C1_C2:
534; THUMB2:       @ %bb.0:
535; THUMB2-NEXT:    lsls r0, r0, #31
536; THUMB2-NEXT:    mov.w r0, #42
537; THUMB2-NEXT:    it ne
538; THUMB2-NEXT:    movwne r0, #421
539; THUMB2-NEXT:    bx lr
540;
541; THUMB-LABEL: select_C1_C2:
542; THUMB:       @ %bb.0:
543; THUMB-NEXT:    lsls r0, r0, #31
544; THUMB-NEXT:    bne .LBB21_2
545; THUMB-NEXT:  @ %bb.1:
546; THUMB-NEXT:    movs r0, #42
547; THUMB-NEXT:    bx lr
548; THUMB-NEXT:  .LBB21_2:
549; THUMB-NEXT:    movs r0, #255
550; THUMB-NEXT:    adds r0, #166
551; THUMB-NEXT:    bx lr
552  %sel = select i1 %cond, i32 421, i32 42
553  ret i32 %sel
554}
555
556define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
557; ARM-LABEL: select_C1_C2_zeroext:
558; ARM:       @ %bb.0:
559; ARM-NEXT:    mov r1, #165
560; ARM-NEXT:    cmp r0, #0
561; ARM-NEXT:    orr r1, r1, #256
562; ARM-NEXT:    moveq r1, #42
563; ARM-NEXT:    mov r0, r1
564; ARM-NEXT:    mov pc, lr
565;
566; THUMB2-LABEL: select_C1_C2_zeroext:
567; THUMB2:       @ %bb.0:
568; THUMB2-NEXT:    movs r1, #42
569; THUMB2-NEXT:    cmp r0, #0
570; THUMB2-NEXT:    it ne
571; THUMB2-NEXT:    movwne r1, #421
572; THUMB2-NEXT:    mov r0, r1
573; THUMB2-NEXT:    bx lr
574;
575; THUMB-LABEL: select_C1_C2_zeroext:
576; THUMB:       @ %bb.0:
577; THUMB-NEXT:    cmp r0, #0
578; THUMB-NEXT:    bne .LBB22_2
579; THUMB-NEXT:  @ %bb.1:
580; THUMB-NEXT:    movs r0, #42
581; THUMB-NEXT:    bx lr
582; THUMB-NEXT:  .LBB22_2:
583; THUMB-NEXT:    movs r0, #255
584; THUMB-NEXT:    adds r0, #166
585; THUMB-NEXT:    bx lr
586  %sel = select i1 %cond, i32 421, i32 42
587  ret i32 %sel
588}
589
590define i32 @select_C1_C2_signext(i1 signext %cond) {
591; ARM-LABEL: select_C1_C2_signext:
592; ARM:       @ %bb.0:
593; ARM-NEXT:    mov r1, #165
594; ARM-NEXT:    tst r0, #1
595; ARM-NEXT:    orr r1, r1, #256
596; ARM-NEXT:    moveq r1, #42
597; ARM-NEXT:    mov r0, r1
598; ARM-NEXT:    mov pc, lr
599;
600; THUMB2-LABEL: select_C1_C2_signext:
601; THUMB2:       @ %bb.0:
602; THUMB2-NEXT:    lsls r0, r0, #31
603; THUMB2-NEXT:    mov.w r0, #42
604; THUMB2-NEXT:    it ne
605; THUMB2-NEXT:    movwne r0, #421
606; THUMB2-NEXT:    bx lr
607;
608; THUMB-LABEL: select_C1_C2_signext:
609; THUMB:       @ %bb.0:
610; THUMB-NEXT:    lsls r0, r0, #31
611; THUMB-NEXT:    bne .LBB23_2
612; THUMB-NEXT:  @ %bb.1:
613; THUMB-NEXT:    movs r0, #42
614; THUMB-NEXT:    bx lr
615; THUMB-NEXT:  .LBB23_2:
616; THUMB-NEXT:    movs r0, #255
617; THUMB-NEXT:    adds r0, #166
618; THUMB-NEXT:    bx lr
619  %sel = select i1 %cond, i32 421, i32 42
620  ret i32 %sel
621}
622
623; 4295032833 = 0x100010001.
624; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
625
626define i64 @opaque_constant1(i1 %cond, i64 %x) {
627; ARM-LABEL: opaque_constant1:
628; ARM:       @ %bb.0:
629; ARM-NEXT:    .save {r4, lr}
630; ARM-NEXT:    push {r4, lr}
631; ARM-NEXT:    mov lr, #1
632; ARM-NEXT:    ands r12, r0, #1
633; ARM-NEXT:    mov r0, #23
634; ARM-NEXT:    orr lr, lr, #65536
635; ARM-NEXT:    mvnne r0, #3
636; ARM-NEXT:    and r4, r0, lr
637; ARM-NEXT:    movne r12, #1
638; ARM-NEXT:    subs r0, r4, #1
639; ARM-NEXT:    eor r2, r2, lr
640; ARM-NEXT:    eor r3, r3, #1
641; ARM-NEXT:    sbc r1, r12, #0
642; ARM-NEXT:    orrs r2, r2, r3
643; ARM-NEXT:    movne r0, r4
644; ARM-NEXT:    movne r1, r12
645; ARM-NEXT:    pop {r4, lr}
646; ARM-NEXT:    mov pc, lr
647;
648; THUMB2-LABEL: opaque_constant1:
649; THUMB2:       @ %bb.0:
650; THUMB2-NEXT:    .save {r7, lr}
651; THUMB2-NEXT:    push {r7, lr}
652; THUMB2-NEXT:    ands r12, r0, #1
653; THUMB2-NEXT:    mov.w lr, #1
654; THUMB2-NEXT:    itt ne
655; THUMB2-NEXT:    movne.w lr, #65536
656; THUMB2-NEXT:    movne.w r12, #1
657; THUMB2-NEXT:    subs.w r0, lr, #1
658; THUMB2-NEXT:    sbc r1, r12, #0
659; THUMB2-NEXT:    eor r3, r3, #1
660; THUMB2-NEXT:    eor r2, r2, #65537
661; THUMB2-NEXT:    orrs r2, r3
662; THUMB2-NEXT:    itt ne
663; THUMB2-NEXT:    movne r0, lr
664; THUMB2-NEXT:    movne r1, r12
665; THUMB2-NEXT:    pop {r7, pc}
666;
667; THUMB-LABEL: opaque_constant1:
668; THUMB:       @ %bb.0:
669; THUMB-NEXT:    .save {r4, r5, r6, r7, lr}
670; THUMB-NEXT:    push {r4, r5, r6, r7, lr}
671; THUMB-NEXT:    movs r7, #1
672; THUMB-NEXT:    ands r0, r7
673; THUMB-NEXT:    subs r1, r0, #1
674; THUMB-NEXT:    push {r0}
675; THUMB-NEXT:    pop {r4}
676; THUMB-NEXT:    sbcs r4, r1
677; THUMB-NEXT:    cmp r0, #0
678; THUMB-NEXT:    bne .LBB24_2
679; THUMB-NEXT:  @ %bb.1:
680; THUMB-NEXT:    movs r5, #23
681; THUMB-NEXT:    b .LBB24_3
682; THUMB-NEXT:  .LBB24_2:
683; THUMB-NEXT:    movs r0, #3
684; THUMB-NEXT:    mvns r5, r0
685; THUMB-NEXT:  .LBB24_3:
686; THUMB-NEXT:    ldr r0, .LCPI24_0
687; THUMB-NEXT:    ands r5, r0
688; THUMB-NEXT:    movs r6, #0
689; THUMB-NEXT:    subs r0, r5, #1
690; THUMB-NEXT:    push {r4}
691; THUMB-NEXT:    pop {r1}
692; THUMB-NEXT:    sbcs r1, r6
693; THUMB-NEXT:    eors r3, r7
694; THUMB-NEXT:    ldr r6, .LCPI24_0
695; THUMB-NEXT:    eors r2, r6
696; THUMB-NEXT:    orrs r2, r3
697; THUMB-NEXT:    beq .LBB24_5
698; THUMB-NEXT:  @ %bb.4:
699; THUMB-NEXT:    movs r1, r4
700; THUMB-NEXT:  .LBB24_5:
701; THUMB-NEXT:    cmp r2, #0
702; THUMB-NEXT:    beq .LBB24_7
703; THUMB-NEXT:  @ %bb.6:
704; THUMB-NEXT:    movs r0, r5
705; THUMB-NEXT:  .LBB24_7:
706; THUMB-NEXT:    pop {r4, r5, r6, r7}
707; THUMB-NEXT:    pop {r2}
708; THUMB-NEXT:    bx r2
709; THUMB-NEXT:    .p2align 2
710; THUMB-NEXT:  @ %bb.8:
711; THUMB-NEXT:  .LCPI24_0:
712; THUMB-NEXT:    .long 65537 @ 0x10001
713  %sel = select i1 %cond, i64 -4, i64 23
714  %bo = and i64 %sel, 4295032833  ; 0x100010001
715  %cmp = icmp eq i64 %x, 4295032833
716  %sext = sext i1 %cmp to i64
717  %add = add i64 %bo, %sext
718  ret i64 %add
719}
720
721; 65537 == 0x10001.
722; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
723
724define i64 @opaque_constant2(i1 %cond, i64 %x) {
725; ARM-LABEL: opaque_constant2:
726; ARM:       @ %bb.0:
727; ARM-NEXT:    mov r1, #1
728; ARM-NEXT:    tst r0, #1
729; ARM-NEXT:    orr r1, r1, #65536
730; ARM-NEXT:    moveq r1, #23
731; ARM-NEXT:    bic r0, r1, #22
732; ARM-NEXT:    mov r1, #0
733; ARM-NEXT:    mov pc, lr
734;
735; THUMB2-LABEL: opaque_constant2:
736; THUMB2:       @ %bb.0:
737; THUMB2-NEXT:    lsls r0, r0, #31
738; THUMB2-NEXT:    mov.w r1, #0
739; THUMB2-NEXT:    mov.w r0, #1
740; THUMB2-NEXT:    it ne
741; THUMB2-NEXT:    movne.w r0, #65537
742; THUMB2-NEXT:    bx lr
743;
744; THUMB-LABEL: opaque_constant2:
745; THUMB:       @ %bb.0:
746; THUMB-NEXT:    lsls r0, r0, #31
747; THUMB-NEXT:    bne .LBB25_2
748; THUMB-NEXT:  @ %bb.1:
749; THUMB-NEXT:    movs r0, #23
750; THUMB-NEXT:    b .LBB25_3
751; THUMB-NEXT:  .LBB25_2:
752; THUMB-NEXT:    ldr r0, .LCPI25_0
753; THUMB-NEXT:  .LBB25_3:
754; THUMB-NEXT:    movs r1, #22
755; THUMB-NEXT:    bics r0, r1
756; THUMB-NEXT:    movs r1, #0
757; THUMB-NEXT:    bx lr
758; THUMB-NEXT:    .p2align 2
759; THUMB-NEXT:  @ %bb.4:
760; THUMB-NEXT:  .LCPI25_0:
761; THUMB-NEXT:    .long 65537 @ 0x10001
762  %sel = select i1 %cond, i64 65537, i64 23
763  %bo = and i64 %sel, 65537
764  ret i64 %bo
765}
766
767