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
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.
9 ; select Cond, 0, 1 --> zext (!Cond)
11 define i32 @select_0_or_1(i1 %cond) {
12 ; ARM-LABEL: select_0_or_1:
14 ; ARM-NEXT: mov r1, #1
15 ; ARM-NEXT: bic r0, r1, r0
16 ; ARM-NEXT: mov pc, lr
18 ; THUMB2-LABEL: select_0_or_1:
20 ; THUMB2-NEXT: movs r1, #1
21 ; THUMB2-NEXT: bic.w r0, r1, r0
24 ; THUMB-LABEL: select_0_or_1:
26 ; THUMB-NEXT: movs r1, #1
27 ; THUMB-NEXT: bics r1, r0
28 ; THUMB-NEXT: movs r0, r1
30 %sel = select i1 %cond, i32 0, i32 1
34 define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
35 ; ARM-LABEL: select_0_or_1_zeroext:
37 ; ARM-NEXT: eor r0, r0, #1
38 ; ARM-NEXT: mov pc, lr
40 ; THUMB2-LABEL: select_0_or_1_zeroext:
42 ; THUMB2-NEXT: eor r0, r0, #1
45 ; THUMB-LABEL: select_0_or_1_zeroext:
47 ; THUMB-NEXT: movs r1, #1
48 ; THUMB-NEXT: eors r0, r1
50 %sel = select i1 %cond, i32 0, i32 1
54 define i32 @select_0_or_1_signext(i1 signext %cond) {
55 ; ARM-LABEL: select_0_or_1_signext:
57 ; ARM-NEXT: mov r1, #1
58 ; ARM-NEXT: bic r0, r1, r0
59 ; ARM-NEXT: mov pc, lr
61 ; THUMB2-LABEL: select_0_or_1_signext:
63 ; THUMB2-NEXT: movs r1, #1
64 ; THUMB2-NEXT: bic.w r0, r1, r0
67 ; THUMB-LABEL: select_0_or_1_signext:
69 ; THUMB-NEXT: movs r1, #1
70 ; THUMB-NEXT: bics r1, r0
71 ; THUMB-NEXT: movs r0, r1
73 %sel = select i1 %cond, i32 0, i32 1
77 ; select Cond, 1, 0 --> zext (Cond)
79 define i32 @select_1_or_0(i1 %cond) {
80 ; ARM-LABEL: select_1_or_0:
82 ; ARM-NEXT: and r0, r0, #1
83 ; ARM-NEXT: mov pc, lr
85 ; THUMB2-LABEL: select_1_or_0:
87 ; THUMB2-NEXT: and r0, r0, #1
90 ; THUMB-LABEL: select_1_or_0:
92 ; THUMB-NEXT: movs r1, #1
93 ; THUMB-NEXT: ands r0, r1
95 %sel = select i1 %cond, i32 1, i32 0
99 define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
100 ; ARM-LABEL: select_1_or_0_zeroext:
102 ; ARM-NEXT: mov pc, lr
104 ; THUMB2-LABEL: select_1_or_0_zeroext:
108 ; THUMB-LABEL: select_1_or_0_zeroext:
111 %sel = select i1 %cond, i32 1, i32 0
115 define i32 @select_1_or_0_signext(i1 signext %cond) {
116 ; ARM-LABEL: select_1_or_0_signext:
118 ; ARM-NEXT: and r0, r0, #1
119 ; ARM-NEXT: mov pc, lr
121 ; THUMB2-LABEL: select_1_or_0_signext:
123 ; THUMB2-NEXT: and r0, r0, #1
126 ; THUMB-LABEL: select_1_or_0_signext:
128 ; THUMB-NEXT: movs r1, #1
129 ; THUMB-NEXT: ands r0, r1
131 %sel = select i1 %cond, i32 1, i32 0
135 ; select Cond, 0, -1 --> sext (!Cond)
137 define i32 @select_0_or_neg1(i1 %cond) {
138 ; ARM-LABEL: select_0_or_neg1:
140 ; ARM-NEXT: and r0, r0, #1
141 ; ARM-NEXT: sub r0, r0, #1
142 ; ARM-NEXT: mov pc, lr
144 ; THUMB2-LABEL: select_0_or_neg1:
146 ; THUMB2-NEXT: and r0, r0, #1
147 ; THUMB2-NEXT: subs r0, #1
150 ; THUMB-LABEL: select_0_or_neg1:
152 ; THUMB-NEXT: movs r1, #1
153 ; THUMB-NEXT: ands r1, r0
154 ; THUMB-NEXT: subs r0, r1, #1
156 %sel = select i1 %cond, i32 0, i32 -1
160 define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
161 ; ARM-LABEL: select_0_or_neg1_zeroext:
163 ; ARM-NEXT: sub r0, r0, #1
164 ; ARM-NEXT: mov pc, lr
166 ; THUMB2-LABEL: select_0_or_neg1_zeroext:
168 ; THUMB2-NEXT: subs r0, #1
171 ; THUMB-LABEL: select_0_or_neg1_zeroext:
173 ; THUMB-NEXT: subs r0, r0, #1
175 %sel = select i1 %cond, i32 0, i32 -1
179 define i32 @select_0_or_neg1_signext(i1 signext %cond) {
180 ; ARM-LABEL: select_0_or_neg1_signext:
182 ; ARM-NEXT: mvn r0, r0
183 ; ARM-NEXT: mov pc, lr
185 ; THUMB2-LABEL: select_0_or_neg1_signext:
187 ; THUMB2-NEXT: mvns r0, r0
190 ; THUMB-LABEL: select_0_or_neg1_signext:
192 ; THUMB-NEXT: mvns r0, r0
194 %sel = select i1 %cond, i32 0, i32 -1
198 define i32 @select_0_or_neg1_alt(i1 %cond) {
199 ; ARM-LABEL: select_0_or_neg1_alt:
201 ; ARM-NEXT: and r0, r0, #1
202 ; ARM-NEXT: sub r0, r0, #1
203 ; ARM-NEXT: mov pc, lr
205 ; THUMB2-LABEL: select_0_or_neg1_alt:
207 ; THUMB2-NEXT: and r0, r0, #1
208 ; THUMB2-NEXT: subs r0, #1
211 ; THUMB-LABEL: select_0_or_neg1_alt:
213 ; THUMB-NEXT: movs r1, #1
214 ; THUMB-NEXT: ands r1, r0
215 ; THUMB-NEXT: subs r0, r1, #1
217 %z = zext i1 %cond to i32
218 %add = add i32 %z, -1
222 define i32 @select_0_or_neg1_alt_zeroext(i1 zeroext %cond) {
223 ; ARM-LABEL: select_0_or_neg1_alt_zeroext:
225 ; ARM-NEXT: sub r0, r0, #1
226 ; ARM-NEXT: mov pc, lr
228 ; THUMB2-LABEL: select_0_or_neg1_alt_zeroext:
230 ; THUMB2-NEXT: subs r0, #1
233 ; THUMB-LABEL: select_0_or_neg1_alt_zeroext:
235 ; THUMB-NEXT: subs r0, r0, #1
237 %z = zext i1 %cond to i32
238 %add = add i32 %z, -1
242 define i32 @select_0_or_neg1_alt_signext(i1 signext %cond) {
243 ; ARM-LABEL: select_0_or_neg1_alt_signext:
245 ; ARM-NEXT: mvn r0, r0
246 ; ARM-NEXT: mov pc, lr
248 ; THUMB2-LABEL: select_0_or_neg1_alt_signext:
250 ; THUMB2-NEXT: mvns r0, r0
253 ; THUMB-LABEL: select_0_or_neg1_alt_signext:
255 ; THUMB-NEXT: mvns r0, r0
257 %z = zext i1 %cond to i32
258 %add = add i32 %z, -1
262 ; select Cond, -1, 0 --> sext (Cond)
264 define i32 @select_neg1_or_0(i1 %cond) {
265 ; ARM-LABEL: select_neg1_or_0:
267 ; ARM-NEXT: and r0, r0, #1
268 ; ARM-NEXT: rsb r0, r0, #0
269 ; ARM-NEXT: mov pc, lr
271 ; THUMB2-LABEL: select_neg1_or_0:
273 ; THUMB2-NEXT: and r0, r0, #1
274 ; THUMB2-NEXT: rsbs r0, r0, #0
277 ; THUMB-LABEL: select_neg1_or_0:
279 ; THUMB-NEXT: movs r1, #1
280 ; THUMB-NEXT: ands r1, r0
281 ; THUMB-NEXT: rsbs r0, r1, #0
283 %sel = select i1 %cond, i32 -1, i32 0
287 define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
288 ; ARM-LABEL: select_neg1_or_0_zeroext:
290 ; ARM-NEXT: rsb r0, r0, #0
291 ; ARM-NEXT: mov pc, lr
293 ; THUMB2-LABEL: select_neg1_or_0_zeroext:
295 ; THUMB2-NEXT: rsbs r0, r0, #0
298 ; THUMB-LABEL: select_neg1_or_0_zeroext:
300 ; THUMB-NEXT: rsbs r0, r0, #0
302 %sel = select i1 %cond, i32 -1, i32 0
306 define i32 @select_neg1_or_0_signext(i1 signext %cond) {
307 ; ARM-LABEL: select_neg1_or_0_signext:
309 ; ARM-NEXT: mov pc, lr
311 ; THUMB2-LABEL: select_neg1_or_0_signext:
315 ; THUMB-LABEL: select_neg1_or_0_signext:
318 %sel = select i1 %cond, i32 -1, i32 0
322 ; select Cond, C+1, C --> add (zext Cond), C
324 define i32 @select_Cplus1_C(i1 %cond) {
325 ; ARM-LABEL: select_Cplus1_C:
327 ; ARM-NEXT: mov r1, #41
328 ; ARM-NEXT: tst r0, #1
329 ; ARM-NEXT: movne r1, #42
330 ; ARM-NEXT: mov r0, r1
331 ; ARM-NEXT: mov pc, lr
333 ; THUMB2-LABEL: select_Cplus1_C:
335 ; THUMB2-NEXT: lsls r0, r0, #31
336 ; THUMB2-NEXT: mov.w r0, #41
338 ; THUMB2-NEXT: movne r0, #42
341 ; THUMB-LABEL: select_Cplus1_C:
343 ; THUMB-NEXT: lsls r0, r0, #31
344 ; THUMB-NEXT: bne .LBB15_2
345 ; THUMB-NEXT: @ %bb.1:
346 ; THUMB-NEXT: movs r0, #41
348 ; THUMB-NEXT: .LBB15_2:
349 ; THUMB-NEXT: movs r0, #42
351 %sel = select i1 %cond, i32 42, i32 41
355 define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
356 ; ARM-LABEL: select_Cplus1_C_zeroext:
358 ; ARM-NEXT: mov r1, #41
359 ; ARM-NEXT: cmp r0, #0
360 ; ARM-NEXT: movne r1, #42
361 ; ARM-NEXT: mov r0, r1
362 ; ARM-NEXT: mov pc, lr
364 ; THUMB2-LABEL: select_Cplus1_C_zeroext:
366 ; THUMB2-NEXT: movs r1, #41
367 ; THUMB2-NEXT: cmp r0, #0
369 ; THUMB2-NEXT: movne r1, #42
370 ; THUMB2-NEXT: mov r0, r1
373 ; THUMB-LABEL: select_Cplus1_C_zeroext:
375 ; THUMB-NEXT: cmp r0, #0
376 ; THUMB-NEXT: bne .LBB16_2
377 ; THUMB-NEXT: @ %bb.1:
378 ; THUMB-NEXT: movs r0, #41
380 ; THUMB-NEXT: .LBB16_2:
381 ; THUMB-NEXT: movs r0, #42
383 %sel = select i1 %cond, i32 42, i32 41
387 define i32 @select_Cplus1_C_signext(i1 signext %cond) {
388 ; ARM-LABEL: select_Cplus1_C_signext:
390 ; ARM-NEXT: mov r1, #41
391 ; ARM-NEXT: tst r0, #1
392 ; ARM-NEXT: movne r1, #42
393 ; ARM-NEXT: mov r0, r1
394 ; ARM-NEXT: mov pc, lr
396 ; THUMB2-LABEL: select_Cplus1_C_signext:
398 ; THUMB2-NEXT: lsls r0, r0, #31
399 ; THUMB2-NEXT: mov.w r0, #41
401 ; THUMB2-NEXT: movne r0, #42
404 ; THUMB-LABEL: select_Cplus1_C_signext:
406 ; THUMB-NEXT: lsls r0, r0, #31
407 ; THUMB-NEXT: bne .LBB17_2
408 ; THUMB-NEXT: @ %bb.1:
409 ; THUMB-NEXT: movs r0, #41
411 ; THUMB-NEXT: .LBB17_2:
412 ; THUMB-NEXT: movs r0, #42
414 %sel = select i1 %cond, i32 42, i32 41
418 ; select Cond, C, C+1 --> add (sext Cond), C
420 define i32 @select_C_Cplus1(i1 %cond) {
421 ; ARM-LABEL: select_C_Cplus1:
423 ; ARM-NEXT: mov r1, #42
424 ; ARM-NEXT: tst r0, #1
425 ; ARM-NEXT: movne r1, #41
426 ; ARM-NEXT: mov r0, r1
427 ; ARM-NEXT: mov pc, lr
429 ; THUMB2-LABEL: select_C_Cplus1:
431 ; THUMB2-NEXT: lsls r0, r0, #31
432 ; THUMB2-NEXT: mov.w r0, #42
434 ; THUMB2-NEXT: movne r0, #41
437 ; THUMB-LABEL: select_C_Cplus1:
439 ; THUMB-NEXT: lsls r0, r0, #31
440 ; THUMB-NEXT: bne .LBB18_2
441 ; THUMB-NEXT: @ %bb.1:
442 ; THUMB-NEXT: movs r0, #42
444 ; THUMB-NEXT: .LBB18_2:
445 ; THUMB-NEXT: movs r0, #41
447 %sel = select i1 %cond, i32 41, i32 42
451 define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
452 ; ARM-LABEL: select_C_Cplus1_zeroext:
454 ; ARM-NEXT: mov r1, #42
455 ; ARM-NEXT: cmp r0, #0
456 ; ARM-NEXT: movne r1, #41
457 ; ARM-NEXT: mov r0, r1
458 ; ARM-NEXT: mov pc, lr
460 ; THUMB2-LABEL: select_C_Cplus1_zeroext:
462 ; THUMB2-NEXT: movs r1, #42
463 ; THUMB2-NEXT: cmp r0, #0
465 ; THUMB2-NEXT: movne r1, #41
466 ; THUMB2-NEXT: mov r0, r1
469 ; THUMB-LABEL: select_C_Cplus1_zeroext:
471 ; THUMB-NEXT: cmp r0, #0
472 ; THUMB-NEXT: bne .LBB19_2
473 ; THUMB-NEXT: @ %bb.1:
474 ; THUMB-NEXT: movs r0, #42
476 ; THUMB-NEXT: .LBB19_2:
477 ; THUMB-NEXT: movs r0, #41
479 %sel = select i1 %cond, i32 41, i32 42
483 define i32 @select_C_Cplus1_signext(i1 signext %cond) {
484 ; ARM-LABEL: select_C_Cplus1_signext:
486 ; ARM-NEXT: mov r1, #42
487 ; ARM-NEXT: tst r0, #1
488 ; ARM-NEXT: movne r1, #41
489 ; ARM-NEXT: mov r0, r1
490 ; ARM-NEXT: mov pc, lr
492 ; THUMB2-LABEL: select_C_Cplus1_signext:
494 ; THUMB2-NEXT: lsls r0, r0, #31
495 ; THUMB2-NEXT: mov.w r0, #42
497 ; THUMB2-NEXT: movne r0, #41
500 ; THUMB-LABEL: select_C_Cplus1_signext:
502 ; THUMB-NEXT: lsls r0, r0, #31
503 ; THUMB-NEXT: bne .LBB20_2
504 ; THUMB-NEXT: @ %bb.1:
505 ; THUMB-NEXT: movs r0, #42
507 ; THUMB-NEXT: .LBB20_2:
508 ; THUMB-NEXT: movs r0, #41
510 %sel = select i1 %cond, i32 41, i32 42
514 ; In general, select of 2 constants could be:
515 ; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
517 define i32 @select_C1_C2(i1 %cond) {
518 ; ARM-LABEL: select_C1_C2:
520 ; ARM-NEXT: mov r1, #165
521 ; ARM-NEXT: tst r0, #1
522 ; ARM-NEXT: orr r1, r1, #256
523 ; ARM-NEXT: moveq r1, #42
524 ; ARM-NEXT: mov r0, r1
525 ; ARM-NEXT: mov pc, lr
527 ; THUMB2-LABEL: select_C1_C2:
529 ; THUMB2-NEXT: lsls r0, r0, #31
530 ; THUMB2-NEXT: mov.w r0, #42
532 ; THUMB2-NEXT: movwne r0, #421
535 ; THUMB-LABEL: select_C1_C2:
537 ; THUMB-NEXT: lsls r0, r0, #31
538 ; THUMB-NEXT: bne .LBB21_2
539 ; THUMB-NEXT: @ %bb.1:
540 ; THUMB-NEXT: movs r0, #42
542 ; THUMB-NEXT: .LBB21_2:
543 ; THUMB-NEXT: movs r0, #255
544 ; THUMB-NEXT: adds r0, #166
546 %sel = select i1 %cond, i32 421, i32 42
550 define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
551 ; ARM-LABEL: select_C1_C2_zeroext:
553 ; ARM-NEXT: mov r1, #165
554 ; ARM-NEXT: cmp r0, #0
555 ; ARM-NEXT: orr r1, r1, #256
556 ; ARM-NEXT: moveq r1, #42
557 ; ARM-NEXT: mov r0, r1
558 ; ARM-NEXT: mov pc, lr
560 ; THUMB2-LABEL: select_C1_C2_zeroext:
562 ; THUMB2-NEXT: movs r1, #42
563 ; THUMB2-NEXT: cmp r0, #0
565 ; THUMB2-NEXT: movwne r1, #421
566 ; THUMB2-NEXT: mov r0, r1
569 ; THUMB-LABEL: select_C1_C2_zeroext:
571 ; THUMB-NEXT: cmp r0, #0
572 ; THUMB-NEXT: bne .LBB22_2
573 ; THUMB-NEXT: @ %bb.1:
574 ; THUMB-NEXT: movs r0, #42
576 ; THUMB-NEXT: .LBB22_2:
577 ; THUMB-NEXT: movs r0, #255
578 ; THUMB-NEXT: adds r0, #166
580 %sel = select i1 %cond, i32 421, i32 42
584 define i32 @select_C1_C2_signext(i1 signext %cond) {
585 ; ARM-LABEL: select_C1_C2_signext:
587 ; ARM-NEXT: mov r1, #165
588 ; ARM-NEXT: tst r0, #1
589 ; ARM-NEXT: orr r1, r1, #256
590 ; ARM-NEXT: moveq r1, #42
591 ; ARM-NEXT: mov r0, r1
592 ; ARM-NEXT: mov pc, lr
594 ; THUMB2-LABEL: select_C1_C2_signext:
596 ; THUMB2-NEXT: lsls r0, r0, #31
597 ; THUMB2-NEXT: mov.w r0, #42
599 ; THUMB2-NEXT: movwne r0, #421
602 ; THUMB-LABEL: select_C1_C2_signext:
604 ; THUMB-NEXT: lsls r0, r0, #31
605 ; THUMB-NEXT: bne .LBB23_2
606 ; THUMB-NEXT: @ %bb.1:
607 ; THUMB-NEXT: movs r0, #42
609 ; THUMB-NEXT: .LBB23_2:
610 ; THUMB-NEXT: movs r0, #255
611 ; THUMB-NEXT: adds r0, #166
613 %sel = select i1 %cond, i32 421, i32 42
617 ; 4295032833 = 0x100010001.
618 ; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
620 define i64 @opaque_constant1(i1 %cond, i64 %x) {
621 ; ARM-LABEL: opaque_constant1:
623 ; ARM-NEXT: .save {r4, lr}
624 ; ARM-NEXT: push {r4, lr}
625 ; ARM-NEXT: mov lr, #1
626 ; ARM-NEXT: ands r12, r0, #1
627 ; ARM-NEXT: mov r0, #23
628 ; ARM-NEXT: orr lr, lr, #65536
629 ; ARM-NEXT: mvnne r0, #3
630 ; ARM-NEXT: and r4, r0, lr
631 ; ARM-NEXT: movne r12, #1
632 ; ARM-NEXT: subs r0, r4, #1
633 ; ARM-NEXT: eor r2, r2, lr
634 ; ARM-NEXT: eor r3, r3, #1
635 ; ARM-NEXT: sbc r1, r12, #0
636 ; ARM-NEXT: orrs r2, r2, r3
637 ; ARM-NEXT: movne r0, r4
638 ; ARM-NEXT: movne r1, r12
639 ; ARM-NEXT: pop {r4, lr}
640 ; ARM-NEXT: mov pc, lr
642 ; THUMB2-LABEL: opaque_constant1:
644 ; THUMB2-NEXT: .save {r7, lr}
645 ; THUMB2-NEXT: push {r7, lr}
646 ; THUMB2-NEXT: ands r12, r0, #1
647 ; THUMB2-NEXT: mov.w lr, #1
648 ; THUMB2-NEXT: itt ne
649 ; THUMB2-NEXT: movne.w lr, #65536
650 ; THUMB2-NEXT: movne.w r12, #1
651 ; THUMB2-NEXT: subs.w r0, lr, #1
652 ; THUMB2-NEXT: sbc r1, r12, #0
653 ; THUMB2-NEXT: eor r3, r3, #1
654 ; THUMB2-NEXT: eor r2, r2, #65537
655 ; THUMB2-NEXT: orrs r2, r3
656 ; THUMB2-NEXT: itt ne
657 ; THUMB2-NEXT: movne r0, lr
658 ; THUMB2-NEXT: movne r1, r12
659 ; THUMB2-NEXT: pop {r7, pc}
661 ; THUMB-LABEL: opaque_constant1:
663 ; THUMB-NEXT: .save {r4, r5, r6, r7, lr}
664 ; THUMB-NEXT: push {r4, r5, r6, r7, lr}
665 ; THUMB-NEXT: movs r7, #1
666 ; THUMB-NEXT: ands r0, r7
667 ; THUMB-NEXT: subs r1, r0, #1
668 ; THUMB-NEXT: push {r0}
669 ; THUMB-NEXT: pop {r4}
670 ; THUMB-NEXT: sbcs r4, r1
671 ; THUMB-NEXT: cmp r0, #0
672 ; THUMB-NEXT: bne .LBB24_2
673 ; THUMB-NEXT: @ %bb.1:
674 ; THUMB-NEXT: movs r5, #23
675 ; THUMB-NEXT: b .LBB24_3
676 ; THUMB-NEXT: .LBB24_2:
677 ; THUMB-NEXT: movs r0, #3
678 ; THUMB-NEXT: mvns r5, r0
679 ; THUMB-NEXT: .LBB24_3:
680 ; THUMB-NEXT: ldr r0, .LCPI24_0
681 ; THUMB-NEXT: ands r5, r0
682 ; THUMB-NEXT: movs r6, #0
683 ; THUMB-NEXT: subs r0, r5, #1
684 ; THUMB-NEXT: push {r4}
685 ; THUMB-NEXT: pop {r1}
686 ; THUMB-NEXT: sbcs r1, r6
687 ; THUMB-NEXT: eors r3, r7
688 ; THUMB-NEXT: ldr r6, .LCPI24_0
689 ; THUMB-NEXT: eors r2, r6
690 ; THUMB-NEXT: orrs r2, r3
691 ; THUMB-NEXT: beq .LBB24_5
692 ; THUMB-NEXT: @ %bb.4:
693 ; THUMB-NEXT: movs r1, r4
694 ; THUMB-NEXT: .LBB24_5:
695 ; THUMB-NEXT: cmp r2, #0
696 ; THUMB-NEXT: beq .LBB24_7
697 ; THUMB-NEXT: @ %bb.6:
698 ; THUMB-NEXT: movs r0, r5
699 ; THUMB-NEXT: .LBB24_7:
700 ; THUMB-NEXT: pop {r4, r5, r6, r7}
701 ; THUMB-NEXT: pop {r2}
703 ; THUMB-NEXT: .p2align 2
704 ; THUMB-NEXT: @ %bb.8:
705 ; THUMB-NEXT: .LCPI24_0:
706 ; THUMB-NEXT: .long 65537 @ 0x10001
707 %sel = select i1 %cond, i64 -4, i64 23
708 %bo = and i64 %sel, 4295032833 ; 0x100010001
709 %cmp = icmp eq i64 %x, 4295032833
710 %sext = sext i1 %cmp to i64
711 %add = add i64 %bo, %sext
716 ; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
718 define i64 @opaque_constant2(i1 %cond, i64 %x) {
719 ; ARM-LABEL: opaque_constant2:
721 ; ARM-NEXT: mov r1, #1
722 ; ARM-NEXT: tst r0, #1
723 ; ARM-NEXT: orr r1, r1, #65536
724 ; ARM-NEXT: moveq r1, #23
725 ; ARM-NEXT: bic r0, r1, #22
726 ; ARM-NEXT: mov r1, #0
727 ; ARM-NEXT: mov pc, lr
729 ; THUMB2-LABEL: opaque_constant2:
731 ; THUMB2-NEXT: lsls r0, r0, #31
732 ; THUMB2-NEXT: mov.w r1, #0
733 ; THUMB2-NEXT: mov.w r0, #1
735 ; THUMB2-NEXT: movne.w r0, #65537
738 ; THUMB-LABEL: opaque_constant2:
740 ; THUMB-NEXT: lsls r0, r0, #31
741 ; THUMB-NEXT: bne .LBB25_2
742 ; THUMB-NEXT: @ %bb.1:
743 ; THUMB-NEXT: movs r0, #23
744 ; THUMB-NEXT: b .LBB25_3
745 ; THUMB-NEXT: .LBB25_2:
746 ; THUMB-NEXT: ldr r0, .LCPI25_0
747 ; THUMB-NEXT: .LBB25_3:
748 ; THUMB-NEXT: movs r1, #22
749 ; THUMB-NEXT: bics r0, r1
750 ; THUMB-NEXT: movs r1, #0
752 ; THUMB-NEXT: .p2align 2
753 ; THUMB-NEXT: @ %bb.4:
754 ; THUMB-NEXT: .LCPI25_0:
755 ; THUMB-NEXT: .long 65537 @ 0x10001
756 %sel = select i1 %cond, i64 65537, i64 23
757 %bo = and i64 %sel, 65537
761 define i64 @func(i64 %arg) {
763 ; ARM: @ %bb.0: @ %entry
764 ; ARM-NEXT: adds r0, r0, #1
765 ; ARM-NEXT: mov r2, #0
766 ; ARM-NEXT: adcs r0, r1, #0
767 ; ARM-NEXT: mov r1, #0
768 ; ARM-NEXT: adcs r0, r2, #0
769 ; ARM-NEXT: movne r0, #8
770 ; ARM-NEXT: mov pc, lr
772 ; THUMB2-LABEL: func:
773 ; THUMB2: @ %bb.0: @ %entry
774 ; THUMB2-NEXT: adds r0, #1
775 ; THUMB2-NEXT: mov.w r2, #0
776 ; THUMB2-NEXT: adcs r0, r1, #0
777 ; THUMB2-NEXT: mov.w r1, #0
778 ; THUMB2-NEXT: adcs r0, r2, #0
780 ; THUMB2-NEXT: movne r0, #8
784 ; THUMB: @ %bb.0: @ %entry
785 ; THUMB-NEXT: .save {r4, lr}
786 ; THUMB-NEXT: push {r4, lr}
787 ; THUMB-NEXT: movs r2, #0
788 ; THUMB-NEXT: adds r3, r0, #1
789 ; THUMB-NEXT: push {r1}
790 ; THUMB-NEXT: pop {r3}
791 ; THUMB-NEXT: adcs r3, r2
792 ; THUMB-NEXT: push {r2}
793 ; THUMB-NEXT: pop {r3}
794 ; THUMB-NEXT: adcs r3, r2
795 ; THUMB-NEXT: subs r4, r3, #1
796 ; THUMB-NEXT: adds r0, r0, #1
797 ; THUMB-NEXT: adcs r1, r2
798 ; THUMB-NEXT: sbcs r3, r4
799 ; THUMB-NEXT: lsls r0, r3, #3
800 ; THUMB-NEXT: movs r1, r2
801 ; THUMB-NEXT: pop {r4}
802 ; THUMB-NEXT: pop {r2}
806 %1 = icmp ult i64 %0, 1
807 %2 = select i1 %1, i64 8, i64 0