
Re-landing #116970 after fixing miscompilation error. The original change made it possible for CMPZ to have multiple uses; `ARMDAGToDAGISel::SelectCMPZ` was not prepared for this. Pull Request: https://github.com/llvm/llvm-project/pull/118887 Original commit message: Following #116547 and #116676, this PR changes the type of results and operands of some nodes to accept / return a normal type instead of Glue. Unfortunately, changing the result type of one node requires changing the operand types of all potential consumer nodes, which in turn requires changing the result types of all other possible producer nodes. So this is a bulk change.
812 lines
21 KiB
LLVM
812 lines
21 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=arm-eabi-unknown-unknown | FileCheck %s --check-prefix=ARM
|
|
; RUN: llc < %s -mtriple=thumbv6t2-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB2
|
|
; RUN: llc < %s -mtriple=thumb-eabi-unknown-unknown | FileCheck %s --check-prefix=THUMB
|
|
|
|
; Select of constants: control flow / conditional moves can always be replaced by logic+math (but may not be worth it?).
|
|
; Test the zeroext/signext variants of each pattern to see if that makes a difference.
|
|
|
|
; select Cond, 0, 1 --> zext (!Cond)
|
|
|
|
define i32 @select_0_or_1(i1 %cond) {
|
|
; ARM-LABEL: select_0_or_1:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #1
|
|
; ARM-NEXT: bic r0, r1, r0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_1:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: movs r1, #1
|
|
; THUMB2-NEXT: bic.w r0, r1, r0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_1:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: bics r1, r0
|
|
; THUMB-NEXT: movs r0, r1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 1
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_0_or_1_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_0_or_1_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: eor r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_1_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: eor r0, r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_1_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: eors r0, r1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 1
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_0_or_1_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_0_or_1_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #1
|
|
; ARM-NEXT: bic r0, r1, r0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_1_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: movs r1, #1
|
|
; THUMB2-NEXT: bic.w r0, r1, r0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_1_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: bics r1, r0
|
|
; THUMB-NEXT: movs r0, r1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 1
|
|
ret i32 %sel
|
|
}
|
|
|
|
; select Cond, 1, 0 --> zext (Cond)
|
|
|
|
define i32 @select_1_or_0(i1 %cond) {
|
|
; ARM-LABEL: select_1_or_0:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: and r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_1_or_0:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: and r0, r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_1_or_0:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: ands r0, r1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_1_or_0_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_1_or_0_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_1_or_0_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_1_or_0_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_1_or_0_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_1_or_0_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: and r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_1_or_0_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: and r0, r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_1_or_0_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: ands r0, r1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
; select Cond, 0, -1 --> sext (!Cond)
|
|
|
|
define i32 @select_0_or_neg1(i1 %cond) {
|
|
; ARM-LABEL: select_0_or_neg1:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: and r0, r0, #1
|
|
; ARM-NEXT: sub r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: and r0, r0, #1
|
|
; THUMB2-NEXT: subs r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: ands r1, r0
|
|
; THUMB-NEXT: subs r0, r1, #1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 -1
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_0_or_neg1_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_0_or_neg1_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: sub r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: subs r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: subs r0, r0, #1
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 -1
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_0_or_neg1_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_0_or_neg1_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mvn r0, r0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: mvns r0, r0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: mvns r0, r0
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 0, i32 -1
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_0_or_neg1_alt(i1 %cond) {
|
|
; ARM-LABEL: select_0_or_neg1_alt:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: and r0, r0, #1
|
|
; ARM-NEXT: sub r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1_alt:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: and r0, r0, #1
|
|
; THUMB2-NEXT: subs r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1_alt:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: ands r1, r0
|
|
; THUMB-NEXT: subs r0, r1, #1
|
|
; THUMB-NEXT: bx lr
|
|
%z = zext i1 %cond to i32
|
|
%add = add i32 %z, -1
|
|
ret i32 %add
|
|
}
|
|
|
|
define i32 @select_0_or_neg1_alt_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_0_or_neg1_alt_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: sub r0, r0, #1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1_alt_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: subs r0, #1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1_alt_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: subs r0, r0, #1
|
|
; THUMB-NEXT: bx lr
|
|
%z = zext i1 %cond to i32
|
|
%add = add i32 %z, -1
|
|
ret i32 %add
|
|
}
|
|
|
|
define i32 @select_0_or_neg1_alt_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_0_or_neg1_alt_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mvn r0, r0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_0_or_neg1_alt_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: mvns r0, r0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_0_or_neg1_alt_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: mvns r0, r0
|
|
; THUMB-NEXT: bx lr
|
|
%z = zext i1 %cond to i32
|
|
%add = add i32 %z, -1
|
|
ret i32 %add
|
|
}
|
|
|
|
; select Cond, -1, 0 --> sext (Cond)
|
|
|
|
define i32 @select_neg1_or_0(i1 %cond) {
|
|
; ARM-LABEL: select_neg1_or_0:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: and r0, r0, #1
|
|
; ARM-NEXT: rsb r0, r0, #0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_neg1_or_0:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: and r0, r0, #1
|
|
; THUMB2-NEXT: rsbs r0, r0, #0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_neg1_or_0:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: movs r1, #1
|
|
; THUMB-NEXT: ands r1, r0
|
|
; THUMB-NEXT: rsbs r0, r1, #0
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 -1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_neg1_or_0_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_neg1_or_0_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: rsb r0, r0, #0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_neg1_or_0_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: rsbs r0, r0, #0
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_neg1_or_0_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: rsbs r0, r0, #0
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 -1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_neg1_or_0_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_neg1_or_0_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_neg1_or_0_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_neg1_or_0_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 -1, i32 0
|
|
ret i32 %sel
|
|
}
|
|
|
|
; select Cond, C+1, C --> add (zext Cond), C
|
|
|
|
define i32 @select_Cplus1_C(i1 %cond) {
|
|
; ARM-LABEL: select_Cplus1_C:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #41
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: movne r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_Cplus1_C:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #41
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r0, #42
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_Cplus1_C:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB15_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB15_2:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 42, i32 41
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_Cplus1_C_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_Cplus1_C_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #41
|
|
; ARM-NEXT: cmp r0, #0
|
|
; ARM-NEXT: movne r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_Cplus1_C_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: movs r1, #41
|
|
; THUMB2-NEXT: cmp r0, #0
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r1, #42
|
|
; THUMB2-NEXT: mov r0, r1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_Cplus1_C_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: cmp r0, #0
|
|
; THUMB-NEXT: bne .LBB16_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB16_2:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 42, i32 41
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_Cplus1_C_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_Cplus1_C_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #41
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: movne r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_Cplus1_C_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #41
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r0, #42
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_Cplus1_C_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB17_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB17_2:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 42, i32 41
|
|
ret i32 %sel
|
|
}
|
|
|
|
; select Cond, C, C+1 --> add (sext Cond), C
|
|
|
|
define i32 @select_C_Cplus1(i1 %cond) {
|
|
; ARM-LABEL: select_C_Cplus1:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #42
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: movne r1, #41
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C_Cplus1:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #42
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r0, #41
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C_Cplus1:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB18_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB18_2:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 41, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_C_Cplus1_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_C_Cplus1_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #42
|
|
; ARM-NEXT: cmp r0, #0
|
|
; ARM-NEXT: movne r1, #41
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C_Cplus1_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: movs r1, #42
|
|
; THUMB2-NEXT: cmp r0, #0
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r1, #41
|
|
; THUMB2-NEXT: mov r0, r1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C_Cplus1_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: cmp r0, #0
|
|
; THUMB-NEXT: bne .LBB19_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB19_2:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 41, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_C_Cplus1_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_C_Cplus1_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #42
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: movne r1, #41
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C_Cplus1_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #42
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r0, #41
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C_Cplus1_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB20_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB20_2:
|
|
; THUMB-NEXT: movs r0, #41
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 41, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
; In general, select of 2 constants could be:
|
|
; select Cond, C1, C2 --> add (mul (zext Cond), C1-C2), C2 --> add (and (sext Cond), C1-C2), C2
|
|
|
|
define i32 @select_C1_C2(i1 %cond) {
|
|
; ARM-LABEL: select_C1_C2:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #165
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: orr r1, r1, #256
|
|
; ARM-NEXT: moveq r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C1_C2:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #42
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movwne r0, #421
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C1_C2:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB21_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB21_2:
|
|
; THUMB-NEXT: movs r0, #255
|
|
; THUMB-NEXT: adds r0, #166
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 421, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_C1_C2_zeroext(i1 zeroext %cond) {
|
|
; ARM-LABEL: select_C1_C2_zeroext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #165
|
|
; ARM-NEXT: cmp r0, #0
|
|
; ARM-NEXT: orr r1, r1, #256
|
|
; ARM-NEXT: moveq r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C1_C2_zeroext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: movs r1, #42
|
|
; THUMB2-NEXT: cmp r0, #0
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movwne r1, #421
|
|
; THUMB2-NEXT: mov r0, r1
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C1_C2_zeroext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: cmp r0, #0
|
|
; THUMB-NEXT: bne .LBB22_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB22_2:
|
|
; THUMB-NEXT: movs r0, #255
|
|
; THUMB-NEXT: adds r0, #166
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 421, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
define i32 @select_C1_C2_signext(i1 signext %cond) {
|
|
; ARM-LABEL: select_C1_C2_signext:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #165
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: orr r1, r1, #256
|
|
; ARM-NEXT: moveq r1, #42
|
|
; ARM-NEXT: mov r0, r1
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: select_C1_C2_signext:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r0, #42
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movwne r0, #421
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: select_C1_C2_signext:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB23_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #42
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .LBB23_2:
|
|
; THUMB-NEXT: movs r0, #255
|
|
; THUMB-NEXT: adds r0, #166
|
|
; THUMB-NEXT: bx lr
|
|
%sel = select i1 %cond, i32 421, i32 42
|
|
ret i32 %sel
|
|
}
|
|
|
|
; 4295032833 = 0x100010001.
|
|
; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
|
|
|
|
define i64 @opaque_constant1(i1 %cond, i64 %x) {
|
|
; ARM-LABEL: opaque_constant1:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: .save {r4, lr}
|
|
; ARM-NEXT: push {r4, lr}
|
|
; ARM-NEXT: mov lr, #1
|
|
; ARM-NEXT: ands r12, r0, #1
|
|
; ARM-NEXT: mov r0, #23
|
|
; ARM-NEXT: orr lr, lr, #65536
|
|
; ARM-NEXT: mvnne r0, #3
|
|
; ARM-NEXT: and r4, r0, lr
|
|
; ARM-NEXT: movne r12, #1
|
|
; ARM-NEXT: subs r0, r4, #1
|
|
; ARM-NEXT: eor r2, r2, lr
|
|
; ARM-NEXT: eor r3, r3, #1
|
|
; ARM-NEXT: sbc r1, r12, #0
|
|
; ARM-NEXT: orrs r2, r2, r3
|
|
; ARM-NEXT: movne r0, r4
|
|
; ARM-NEXT: movne r1, r12
|
|
; ARM-NEXT: pop {r4, lr}
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: opaque_constant1:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: .save {r7, lr}
|
|
; THUMB2-NEXT: push {r7, lr}
|
|
; THUMB2-NEXT: ands r12, r0, #1
|
|
; THUMB2-NEXT: mov.w lr, #1
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne.w r12, #1
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne.w lr, #65536
|
|
; THUMB2-NEXT: subs.w r0, lr, #1
|
|
; THUMB2-NEXT: eor r3, r3, #1
|
|
; THUMB2-NEXT: sbc r1, r12, #0
|
|
; THUMB2-NEXT: eor r2, r2, #65537
|
|
; THUMB2-NEXT: orrs r2, r3
|
|
; THUMB2-NEXT: itt ne
|
|
; THUMB2-NEXT: movne r0, lr
|
|
; THUMB2-NEXT: movne r1, r12
|
|
; THUMB2-NEXT: pop {r7, pc}
|
|
;
|
|
; THUMB-LABEL: opaque_constant1:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: .save {r4, r5, r6, r7, lr}
|
|
; THUMB-NEXT: push {r4, r5, r6, r7, lr}
|
|
; THUMB-NEXT: movs r7, #1
|
|
; THUMB-NEXT: ands r0, r7
|
|
; THUMB-NEXT: subs r1, r0, #1
|
|
; THUMB-NEXT: mov r12, r0
|
|
; THUMB-NEXT: mov r4, r12
|
|
; THUMB-NEXT: sbcs r4, r1
|
|
; THUMB-NEXT: cmp r0, #0
|
|
; THUMB-NEXT: bne .LBB24_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r5, #23
|
|
; THUMB-NEXT: b .LBB24_3
|
|
; THUMB-NEXT: .LBB24_2:
|
|
; THUMB-NEXT: movs r0, #3
|
|
; THUMB-NEXT: mvns r5, r0
|
|
; THUMB-NEXT: .LBB24_3:
|
|
; THUMB-NEXT: ldr r0, .LCPI24_0
|
|
; THUMB-NEXT: ands r5, r0
|
|
; THUMB-NEXT: movs r6, #0
|
|
; THUMB-NEXT: subs r0, r5, #1
|
|
; THUMB-NEXT: mov r12, r4
|
|
; THUMB-NEXT: mov r1, r12
|
|
; THUMB-NEXT: sbcs r1, r6
|
|
; THUMB-NEXT: eors r3, r7
|
|
; THUMB-NEXT: ldr r6, .LCPI24_0
|
|
; THUMB-NEXT: eors r2, r6
|
|
; THUMB-NEXT: orrs r2, r3
|
|
; THUMB-NEXT: cmp r2, #0
|
|
; THUMB-NEXT: beq .LBB24_5
|
|
; THUMB-NEXT: @ %bb.4:
|
|
; THUMB-NEXT: mov r12, r4
|
|
; THUMB-NEXT: mov r1, r12
|
|
; THUMB-NEXT: .LBB24_5:
|
|
; THUMB-NEXT: beq .LBB24_7
|
|
; THUMB-NEXT: @ %bb.6:
|
|
; THUMB-NEXT: movs r0, r5
|
|
; THUMB-NEXT: .LBB24_7:
|
|
; THUMB-NEXT: pop {r4, r5, r6, r7}
|
|
; THUMB-NEXT: pop {r2}
|
|
; THUMB-NEXT: bx r2
|
|
; THUMB-NEXT: .p2align 2
|
|
; THUMB-NEXT: @ %bb.8:
|
|
; THUMB-NEXT: .LCPI24_0:
|
|
; THUMB-NEXT: .long 65537 @ 0x10001
|
|
%sel = select i1 %cond, i64 -4, i64 23
|
|
%bo = and i64 %sel, 4295032833 ; 0x100010001
|
|
%cmp = icmp eq i64 %x, 4295032833
|
|
%sext = sext i1 %cmp to i64
|
|
%add = add i64 %bo, %sext
|
|
ret i64 %add
|
|
}
|
|
|
|
; 65537 == 0x10001.
|
|
; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select.
|
|
|
|
define i64 @opaque_constant2(i1 %cond, i64 %x) {
|
|
; ARM-LABEL: opaque_constant2:
|
|
; ARM: @ %bb.0:
|
|
; ARM-NEXT: mov r1, #1
|
|
; ARM-NEXT: tst r0, #1
|
|
; ARM-NEXT: orr r1, r1, #65536
|
|
; ARM-NEXT: moveq r1, #23
|
|
; ARM-NEXT: bic r0, r1, #22
|
|
; ARM-NEXT: mov r1, #0
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: opaque_constant2:
|
|
; THUMB2: @ %bb.0:
|
|
; THUMB2-NEXT: lsls r0, r0, #31
|
|
; THUMB2-NEXT: mov.w r1, #0
|
|
; THUMB2-NEXT: mov.w r0, #1
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne.w r0, #65537
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: opaque_constant2:
|
|
; THUMB: @ %bb.0:
|
|
; THUMB-NEXT: lsls r0, r0, #31
|
|
; THUMB-NEXT: bne .LBB25_2
|
|
; THUMB-NEXT: @ %bb.1:
|
|
; THUMB-NEXT: movs r0, #23
|
|
; THUMB-NEXT: b .LBB25_3
|
|
; THUMB-NEXT: .LBB25_2:
|
|
; THUMB-NEXT: ldr r0, .LCPI25_0
|
|
; THUMB-NEXT: .LBB25_3:
|
|
; THUMB-NEXT: movs r1, #22
|
|
; THUMB-NEXT: bics r0, r1
|
|
; THUMB-NEXT: movs r1, #0
|
|
; THUMB-NEXT: bx lr
|
|
; THUMB-NEXT: .p2align 2
|
|
; THUMB-NEXT: @ %bb.4:
|
|
; THUMB-NEXT: .LCPI25_0:
|
|
; THUMB-NEXT: .long 65537 @ 0x10001
|
|
%sel = select i1 %cond, i64 65537, i64 23
|
|
%bo = and i64 %sel, 65537
|
|
ret i64 %bo
|
|
}
|
|
|
|
define i64 @func(i64 %arg) {
|
|
; ARM-LABEL: func:
|
|
; ARM: @ %bb.0: @ %entry
|
|
; ARM-NEXT: adds r0, r0, #1
|
|
; ARM-NEXT: mov r2, #0
|
|
; ARM-NEXT: adcs r0, r1, #0
|
|
; ARM-NEXT: mov r1, #0
|
|
; ARM-NEXT: adcs r0, r2, #0
|
|
; ARM-NEXT: movne r0, #8
|
|
; ARM-NEXT: mov pc, lr
|
|
;
|
|
; THUMB2-LABEL: func:
|
|
; THUMB2: @ %bb.0: @ %entry
|
|
; THUMB2-NEXT: adds r0, #1
|
|
; THUMB2-NEXT: mov.w r2, #0
|
|
; THUMB2-NEXT: adcs r0, r1, #0
|
|
; THUMB2-NEXT: mov.w r1, #0
|
|
; THUMB2-NEXT: adcs r0, r2, #0
|
|
; THUMB2-NEXT: it ne
|
|
; THUMB2-NEXT: movne r0, #8
|
|
; THUMB2-NEXT: bx lr
|
|
;
|
|
; THUMB-LABEL: func:
|
|
; THUMB: @ %bb.0: @ %entry
|
|
; THUMB-NEXT: .save {r4, lr}
|
|
; THUMB-NEXT: push {r4, lr}
|
|
; THUMB-NEXT: movs r2, #0
|
|
; THUMB-NEXT: adds r3, r0, #1
|
|
; THUMB-NEXT: mov r12, r1
|
|
; THUMB-NEXT: mov r3, r12
|
|
; THUMB-NEXT: adcs r3, r2
|
|
; THUMB-NEXT: mov r12, r2
|
|
; THUMB-NEXT: mov r3, r12
|
|
; THUMB-NEXT: adcs r3, r2
|
|
; THUMB-NEXT: subs r4, r3, #1
|
|
; THUMB-NEXT: adds r0, r0, #1
|
|
; THUMB-NEXT: adcs r1, r2
|
|
; THUMB-NEXT: sbcs r3, r4
|
|
; THUMB-NEXT: lsls r0, r3, #3
|
|
; THUMB-NEXT: movs r1, r2
|
|
; THUMB-NEXT: pop {r4}
|
|
; THUMB-NEXT: pop {r2}
|
|
; THUMB-NEXT: bx r2
|
|
entry:
|
|
%0 = add i64 %arg, 1
|
|
%1 = icmp ult i64 %0, 1
|
|
%2 = select i1 %1, i64 8, i64 0
|
|
ret i64 %2
|
|
}
|