[ARM] Favour PL/MI over GE/LT when possible

The arm condition codes for GE is N==V (and for LT is N!=V). If the source of
flags cannot set V (overflow), such as a cmp against #0, then we can use the
simpler PL and MI conditions that only check N. As these PL/MI conditions are
simpler than GE/LT, other passes like the peephole optimiser can have a better
time optimising away the redundant CMPs.

The exception is the VSEL instruction, which cannot take the PL code, so there
the transform favours GE.

Differential Revision: https://reviews.llvm.org/D64160

llvm-svn: 365117
This commit is contained in:
David Green 2019-07-04 08:58:58 +00:00
parent 147547ee80
commit 2b20ee4110
9 changed files with 181 additions and 195 deletions

View File

@ -4017,6 +4017,22 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
}
ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
// If the RHS is a constant zero then the V (overflow) flag will never be
// set. This can allow us to simplify GE to PL or LT to MI, which can be
// simpler for other passes (like the peephole optimiser) to deal with.
if (isNullConstant(RHS)) {
switch (CondCode) {
default: break;
case ARMCC::GE:
CondCode = ARMCC::PL;
break;
case ARMCC::LT:
CondCode = ARMCC::MI;
break;
}
}
ARMISD::NodeType CompareType;
switch (CondCode) {
default:
@ -4645,6 +4661,9 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue ARMcc;
SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
// Choose GE over PL, which vsel does now support
if (cast<ConstantSDNode>(ARMcc)->getZExtValue() == ARMCC::PL)
ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, CCR, Cmp, DAG);
}

View File

@ -40,7 +40,7 @@ entry:
bb1: ; preds = %bb2.preheader, %bb1
; CHECK: LBB1_[[BB3:.]]: @ %bb3
; CHECK: LBB1_[[PREHDR:.]]: @ %bb2.preheader
; CHECK: blt LBB1_[[BB3]]
; CHECK: bmi LBB1_[[BB3]]
%indvar = phi i32 [ %indvar.next, %bb1 ], [ 0, %bb2.preheader ] ; <i32> [#uses=2]
%sum.08 = phi i32 [ %2, %bb1 ], [ %sum.110, %bb2.preheader ] ; <i32> [#uses=1]
%tmp17 = sub i32 %i.07, %indvar ; <i32> [#uses=1]

View File

@ -370,14 +370,13 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: push {r11, lr}
; ARM6-NEXT: mov r12, #-2147483648
; ARM6-NEXT: sub lr, r2, #32
; ARM6-NEXT: subs lr, r2, #32
; ARM6-NEXT: lsr r3, r12, r2
; ARM6-NEXT: rsb r2, r2, #32
; ARM6-NEXT: cmp lr, #0
; ARM6-NEXT: lsl r2, r12, r2
; ARM6-NEXT: movge r3, #0
; ARM6-NEXT: lsrge r2, r12, lr
; ARM6-NEXT: movpl r3, #0
; ARM6-NEXT: and r1, r3, r1
; ARM6-NEXT: lsl r2, r12, r2
; ARM6-NEXT: lsrpl r2, r12, lr
; ARM6-NEXT: and r0, r2, r0
; ARM6-NEXT: orr r0, r0, r1
; ARM6-NEXT: clz r0, r0
@ -388,14 +387,13 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: push {r11, lr}
; ARM78-NEXT: mov r12, #-2147483648
; ARM78-NEXT: sub lr, r2, #32
; ARM78-NEXT: subs lr, r2, #32
; ARM78-NEXT: lsr r3, r12, r2
; ARM78-NEXT: rsb r2, r2, #32
; ARM78-NEXT: cmp lr, #0
; ARM78-NEXT: lsl r2, r12, r2
; ARM78-NEXT: movwge r3, #0
; ARM78-NEXT: lsrge r2, r12, lr
; ARM78-NEXT: movwpl r3, #0
; ARM78-NEXT: and r1, r3, r1
; ARM78-NEXT: lsl r2, r12, r2
; ARM78-NEXT: lsrpl r2, r12, lr
; ARM78-NEXT: and r0, r2, r0
; ARM78-NEXT: orr r0, r0, r1
; ARM78-NEXT: clz r0, r0
@ -423,14 +421,13 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; THUMB7-NEXT: push {r7, lr}
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: mov.w r12, #-2147483648
; THUMB7-NEXT: sub.w lr, r2, #32
; THUMB7-NEXT: subs.w lr, r2, #32
; THUMB7-NEXT: lsr.w r2, r12, r2
; THUMB7-NEXT: lsl.w r3, r12, r3
; THUMB7-NEXT: cmp.w lr, #0
; THUMB7-NEXT: it ge
; THUMB7-NEXT: lsrge.w r3, r12, lr
; THUMB7-NEXT: it ge
; THUMB7-NEXT: movge r2, #0
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lsrpl.w r3, r12, lr
; THUMB7-NEXT: it pl
; THUMB7-NEXT: movpl r2, #0
; THUMB7-NEXT: ands r0, r3
; THUMB7-NEXT: ands r1, r2
; THUMB7-NEXT: orrs r0, r1
@ -440,25 +437,24 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
;
; THUMB8-LABEL: scalar_i64_signbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: .save {r4, lr}
; THUMB8-NEXT: push {r4, lr}
; THUMB8-NEXT: rsb.w r4, r2, #32
; THUMB8-NEXT: sub.w r3, r2, #32
; THUMB8-NEXT: .save {r7, lr}
; THUMB8-NEXT: push {r7, lr}
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: mov.w r12, #-2147483648
; THUMB8-NEXT: cmp r3, #0
; THUMB8-NEXT: lsl.w r4, r12, r4
; THUMB8-NEXT: lsr.w r2, r12, r2
; THUMB8-NEXT: lsr.w lr, r12, r3
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r4, lr
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r2, #0
; THUMB8-NEXT: ands r0, r4
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsr.w r2, r12, r2
; THUMB8-NEXT: lsl.w r3, r12, r3
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r3, lr
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r2, #0
; THUMB8-NEXT: ands r0, r3
; THUMB8-NEXT: ands r1, r2
; THUMB8-NEXT: orrs r0, r1
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: pop {r4, pc}
; THUMB8-NEXT: pop {r7, pc}
%t0 = lshr i64 9223372036854775808, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
@ -470,9 +466,8 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: mov r1, #1
; ARM6-NEXT: lsr r1, r1, r2
; ARM6-NEXT: sub r2, r2, #32
; ARM6-NEXT: cmp r2, #0
; ARM6-NEXT: movge r1, #0
; ARM6-NEXT: subs r2, r2, #32
; ARM6-NEXT: movpl r1, #0
; ARM6-NEXT: and r0, r1, r0
; ARM6-NEXT: clz r0, r0
; ARM6-NEXT: lsr r0, r0, #5
@ -482,9 +477,8 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: mov r1, #1
; ARM78-NEXT: lsr r1, r1, r2
; ARM78-NEXT: sub r2, r2, #32
; ARM78-NEXT: cmp r2, #0
; ARM78-NEXT: movwge r1, #0
; ARM78-NEXT: subs r2, r2, #32
; ARM78-NEXT: movwpl r1, #0
; ARM78-NEXT: and r0, r1, r0
; ARM78-NEXT: clz r0, r0
; ARM78-NEXT: lsr r0, r0, #5
@ -510,9 +504,8 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; THUMB78-NEXT: movs r1, #1
; THUMB78-NEXT: lsrs r1, r2
; THUMB78-NEXT: subs r2, #32
; THUMB78-NEXT: cmp r2, #0
; THUMB78-NEXT: it ge
; THUMB78-NEXT: movge r1, #0
; THUMB78-NEXT: it pl
; THUMB78-NEXT: movpl r1, #0
; THUMB78-NEXT: ands r0, r1
; THUMB78-NEXT: clz r0, r0
; THUMB78-NEXT: lsrs r0, r0, #5
@ -528,11 +521,10 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: push {r11, lr}
; ARM6-NEXT: mov r12, #255
; ARM6-NEXT: sub lr, r2, #32
; ARM6-NEXT: subs lr, r2, #32
; ARM6-NEXT: orr r12, r12, #65280
; ARM6-NEXT: cmp lr, #0
; ARM6-NEXT: lsr r3, r12, r2
; ARM6-NEXT: movge r3, #0
; ARM6-NEXT: movpl r3, #0
; ARM6-NEXT: and r1, r3, r1
; ARM6-NEXT: mov r3, #16711680
; ARM6-NEXT: cmp lr, #0
@ -540,7 +532,7 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM6-NEXT: lsr r3, r3, r2
; ARM6-NEXT: rsb r2, r2, #32
; ARM6-NEXT: orr r2, r3, r12, lsl r2
; ARM6-NEXT: lsrge r2, r12, lr
; ARM6-NEXT: lsrpl r2, r12, lr
; ARM6-NEXT: and r0, r2, r0
; ARM6-NEXT: orr r0, r0, r1
; ARM6-NEXT: clz r0, r0
@ -551,10 +543,9 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: push {r11, lr}
; ARM78-NEXT: movw r12, #65535
; ARM78-NEXT: sub lr, r2, #32
; ARM78-NEXT: subs lr, r2, #32
; ARM78-NEXT: lsr r3, r12, r2
; ARM78-NEXT: cmp lr, #0
; ARM78-NEXT: movwge r3, #0
; ARM78-NEXT: movwpl r3, #0
; ARM78-NEXT: and r1, r3, r1
; ARM78-NEXT: movw r3, #0
; ARM78-NEXT: cmp lr, #0
@ -562,7 +553,7 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM78-NEXT: lsr r3, r3, r2
; ARM78-NEXT: rsb r2, r2, #32
; ARM78-NEXT: orr r2, r3, r12, lsl r2
; ARM78-NEXT: lsrge r2, r12, lr
; ARM78-NEXT: lsrpl r2, r12, lr
; ARM78-NEXT: and r0, r2, r0
; ARM78-NEXT: orr r0, r0, r1
; ARM78-NEXT: clz r0, r0
@ -599,15 +590,14 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB7-NEXT: lsr.w r12, r3, r2
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: lsl.w r3, lr, r3
; THUMB7-NEXT: orr.w r3, r3, r12
; THUMB7-NEXT: sub.w r12, r2, #32
; THUMB7-NEXT: orr.w r12, r12, r3
; THUMB7-NEXT: subs.w r3, r2, #32
; THUMB7-NEXT: lsr.w r2, lr, r2
; THUMB7-NEXT: cmp.w r12, #0
; THUMB7-NEXT: it ge
; THUMB7-NEXT: lsrge.w r3, lr, r12
; THUMB7-NEXT: it ge
; THUMB7-NEXT: movge r2, #0
; THUMB7-NEXT: ands r0, r3
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lsrpl.w r12, lr, r3
; THUMB7-NEXT: it pl
; THUMB7-NEXT: movpl r2, #0
; THUMB7-NEXT: and.w r0, r0, r12
; THUMB7-NEXT: ands r1, r2
; THUMB7-NEXT: orrs r0, r1
; THUMB7-NEXT: clz r0, r0
@ -616,8 +606,8 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
;
; THUMB8-LABEL: scalar_i64_bitsinmiddle_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: .save {r4, lr}
; THUMB8-NEXT: push {r4, lr}
; THUMB8-NEXT: .save {r7, lr}
; THUMB8-NEXT: push {r7, lr}
; THUMB8-NEXT: movs r3, #0
; THUMB8-NEXT: movw lr, #65535
; THUMB8-NEXT: movt r3, #65535
@ -625,20 +615,19 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsl.w r3, lr, r3
; THUMB8-NEXT: orr.w r12, r12, r3
; THUMB8-NEXT: sub.w r3, r2, #32
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: lsr.w r2, lr, r2
; THUMB8-NEXT: cmp r3, #0
; THUMB8-NEXT: lsr.w r4, lr, r3
; THUMB8-NEXT: it lt
; THUMB8-NEXT: movlt r4, r12
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r2, #0
; THUMB8-NEXT: ands r0, r4
; THUMB8-NEXT: lsr.w r3, lr, r3
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r3, r12
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r2, #0
; THUMB8-NEXT: ands r0, r3
; THUMB8-NEXT: ands r1, r2
; THUMB8-NEXT: orrs r0, r1
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: pop {r4, pc}
; THUMB8-NEXT: pop {r7, pc}
%t0 = lshr i64 281474976645120, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
@ -1239,7 +1228,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; ARM6-NEXT: sxtb r1, r0
; ARM6-NEXT: mov r0, #0
; ARM6-NEXT: cmp r1, #0
; ARM6-NEXT: movlt r0, #1
; ARM6-NEXT: movmi r0, #1
; ARM6-NEXT: bx lr
;
; ARM78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
@ -1250,7 +1239,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; ARM78-NEXT: sxtb r1, r0
; ARM78-NEXT: mov r0, #0
; ARM78-NEXT: cmp r1, #0
; ARM78-NEXT: movwlt r0, #1
; ARM78-NEXT: movwmi r0, #1
; ARM78-NEXT: bx lr
;
; THUMB6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
@ -1261,7 +1250,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; THUMB6-NEXT: ands r2, r0
; THUMB6-NEXT: sxtb r0, r2
; THUMB6-NEXT: cmp r0, #0
; THUMB6-NEXT: blt .LBB20_2
; THUMB6-NEXT: bmi .LBB20_2
; THUMB6-NEXT: @ %bb.1:
; THUMB6-NEXT: movs r0, #0
; THUMB6-NEXT: bx lr
@ -1278,8 +1267,8 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; THUMB78-NEXT: sxtb r1, r0
; THUMB78-NEXT: movs r0, #0
; THUMB78-NEXT: cmp r1, #0
; THUMB78-NEXT: it lt
; THUMB78-NEXT: movlt r0, #1
; THUMB78-NEXT: it mi
; THUMB78-NEXT: movmi r0, #1
; THUMB78-NEXT: bx lr
%t0 = lshr i8 24, %y
%t1 = and i8 %t0, %x

View File

@ -390,9 +390,8 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: mov r0, #-2147483648
; ARM6-NEXT: lsl r0, r0, r2
; ARM6-NEXT: sub r2, r2, #32
; ARM6-NEXT: cmp r2, #0
; ARM6-NEXT: movge r0, #0
; ARM6-NEXT: subs r2, r2, #32
; ARM6-NEXT: movpl r0, #0
; ARM6-NEXT: and r0, r0, r1
; ARM6-NEXT: clz r0, r0
; ARM6-NEXT: lsr r0, r0, #5
@ -402,9 +401,8 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: mov r0, #-2147483648
; ARM78-NEXT: lsl r0, r0, r2
; ARM78-NEXT: sub r2, r2, #32
; ARM78-NEXT: cmp r2, #0
; ARM78-NEXT: movwge r0, #0
; ARM78-NEXT: subs r2, r2, #32
; ARM78-NEXT: movwpl r0, #0
; ARM78-NEXT: and r0, r0, r1
; ARM78-NEXT: clz r0, r0
; ARM78-NEXT: lsr r0, r0, #5
@ -431,9 +429,8 @@ define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
; THUMB78-NEXT: mov.w r0, #-2147483648
; THUMB78-NEXT: lsls r0, r2
; THUMB78-NEXT: subs r2, #32
; THUMB78-NEXT: cmp r2, #0
; THUMB78-NEXT: it ge
; THUMB78-NEXT: movge r0, #0
; THUMB78-NEXT: it pl
; THUMB78-NEXT: movpl r0, #0
; THUMB78-NEXT: ands r0, r1
; THUMB78-NEXT: clz r0, r0
; THUMB78-NEXT: lsrs r0, r0, #5
@ -449,14 +446,13 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: push {r11, lr}
; ARM6-NEXT: mov r12, #1
; ARM6-NEXT: sub lr, r2, #32
; ARM6-NEXT: subs lr, r2, #32
; ARM6-NEXT: lsl r3, r12, r2
; ARM6-NEXT: rsb r2, r2, #32
; ARM6-NEXT: cmp lr, #0
; ARM6-NEXT: lsr r2, r12, r2
; ARM6-NEXT: movge r3, #0
; ARM6-NEXT: lslge r2, r12, lr
; ARM6-NEXT: movpl r3, #0
; ARM6-NEXT: and r0, r3, r0
; ARM6-NEXT: lsr r2, r12, r2
; ARM6-NEXT: lslpl r2, r12, lr
; ARM6-NEXT: and r1, r2, r1
; ARM6-NEXT: orr r0, r0, r1
; ARM6-NEXT: clz r0, r0
@ -467,14 +463,13 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: push {r11, lr}
; ARM78-NEXT: mov r12, #1
; ARM78-NEXT: sub lr, r2, #32
; ARM78-NEXT: subs lr, r2, #32
; ARM78-NEXT: lsl r3, r12, r2
; ARM78-NEXT: rsb r2, r2, #32
; ARM78-NEXT: cmp lr, #0
; ARM78-NEXT: lsr r2, r12, r2
; ARM78-NEXT: movwge r3, #0
; ARM78-NEXT: lslge r2, r12, lr
; ARM78-NEXT: movwpl r3, #0
; ARM78-NEXT: and r0, r3, r0
; ARM78-NEXT: lsr r2, r12, r2
; ARM78-NEXT: lslpl r2, r12, lr
; ARM78-NEXT: and r1, r2, r1
; ARM78-NEXT: orr r0, r0, r1
; ARM78-NEXT: clz r0, r0
@ -501,14 +496,13 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
; THUMB7-NEXT: push {r7, lr}
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: mov.w r12, #1
; THUMB7-NEXT: sub.w lr, r2, #32
; THUMB7-NEXT: subs.w lr, r2, #32
; THUMB7-NEXT: lsl.w r2, r12, r2
; THUMB7-NEXT: lsr.w r3, r12, r3
; THUMB7-NEXT: cmp.w lr, #0
; THUMB7-NEXT: it ge
; THUMB7-NEXT: lslge.w r3, r12, lr
; THUMB7-NEXT: it ge
; THUMB7-NEXT: movge r2, #0
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lslpl.w r3, r12, lr
; THUMB7-NEXT: it pl
; THUMB7-NEXT: movpl r2, #0
; THUMB7-NEXT: ands r1, r3
; THUMB7-NEXT: ands r0, r2
; THUMB7-NEXT: orrs r0, r1
@ -518,25 +512,24 @@ define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
;
; THUMB8-LABEL: scalar_i64_lowestbit_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: .save {r4, lr}
; THUMB8-NEXT: push {r4, lr}
; THUMB8-NEXT: rsb.w r4, r2, #32
; THUMB8-NEXT: sub.w r3, r2, #32
; THUMB8-NEXT: .save {r7, lr}
; THUMB8-NEXT: push {r7, lr}
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: mov.w r12, #1
; THUMB8-NEXT: cmp r3, #0
; THUMB8-NEXT: lsr.w r4, r12, r4
; THUMB8-NEXT: lsl.w r2, r12, r2
; THUMB8-NEXT: lsl.w lr, r12, r3
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r4, lr
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r2, #0
; THUMB8-NEXT: ands r1, r4
; THUMB8-NEXT: rsb.w r3, r2, #32
; THUMB8-NEXT: lsl.w r2, r12, r2
; THUMB8-NEXT: lsr.w r3, r12, r3
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r3, lr
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r2, #0
; THUMB8-NEXT: ands r1, r3
; THUMB8-NEXT: ands r0, r2
; THUMB8-NEXT: orrs r0, r1
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: pop {r4, pc}
; THUMB8-NEXT: pop {r7, pc}
%t0 = shl i64 1, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
@ -548,19 +541,18 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM6: @ %bb.0:
; ARM6-NEXT: push {r4, lr}
; ARM6-NEXT: mov r12, #16711680
; ARM6-NEXT: sub lr, r2, #32
; ARM6-NEXT: subs lr, r2, #32
; ARM6-NEXT: orr r12, r12, #-16777216
; ARM6-NEXT: cmp lr, #0
; ARM6-NEXT: mov r4, #255
; ARM6-NEXT: lsl r3, r12, r2
; ARM6-NEXT: orr r4, r4, #65280
; ARM6-NEXT: movge r3, #0
; ARM6-NEXT: lsl r3, r12, r2
; ARM6-NEXT: movpl r3, #0
; ARM6-NEXT: and r0, r3, r0
; ARM6-NEXT: rsb r3, r2, #32
; ARM6-NEXT: cmp lr, #0
; ARM6-NEXT: lsr r3, r12, r3
; ARM6-NEXT: orr r2, r3, r4, lsl r2
; ARM6-NEXT: lslge r2, r12, lr
; ARM6-NEXT: lslpl r2, r12, lr
; ARM6-NEXT: and r1, r2, r1
; ARM6-NEXT: orr r0, r0, r1
; ARM6-NEXT: clz r0, r0
@ -571,18 +563,17 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; ARM78: @ %bb.0:
; ARM78-NEXT: push {r4, lr}
; ARM78-NEXT: movw r12, #0
; ARM78-NEXT: sub lr, r2, #32
; ARM78-NEXT: subs lr, r2, #32
; ARM78-NEXT: movt r12, #65535
; ARM78-NEXT: cmp lr, #0
; ARM78-NEXT: lsl r3, r12, r2
; ARM78-NEXT: movw r4, #65535
; ARM78-NEXT: movwge r3, #0
; ARM78-NEXT: lsl r3, r12, r2
; ARM78-NEXT: movwpl r3, #0
; ARM78-NEXT: and r0, r3, r0
; ARM78-NEXT: rsb r3, r2, #32
; ARM78-NEXT: cmp lr, #0
; ARM78-NEXT: lsr r3, r12, r3
; ARM78-NEXT: orr r2, r3, r4, lsl r2
; ARM78-NEXT: lslge r2, r12, lr
; ARM78-NEXT: lslpl r2, r12, lr
; ARM78-NEXT: and r1, r2, r1
; ARM78-NEXT: orr r0, r0, r1
; ARM78-NEXT: clz r0, r0
@ -619,15 +610,14 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB7-NEXT: rsb.w r3, r2, #32
; THUMB7-NEXT: movt lr, #65535
; THUMB7-NEXT: lsr.w r3, lr, r3
; THUMB7-NEXT: orr.w r3, r3, r12
; THUMB7-NEXT: sub.w r12, r2, #32
; THUMB7-NEXT: orr.w r12, r12, r3
; THUMB7-NEXT: subs.w r3, r2, #32
; THUMB7-NEXT: lsl.w r2, lr, r2
; THUMB7-NEXT: cmp.w r12, #0
; THUMB7-NEXT: it ge
; THUMB7-NEXT: lslge.w r3, lr, r12
; THUMB7-NEXT: it ge
; THUMB7-NEXT: movge r2, #0
; THUMB7-NEXT: ands r1, r3
; THUMB7-NEXT: it pl
; THUMB7-NEXT: lslpl.w r12, lr, r3
; THUMB7-NEXT: it pl
; THUMB7-NEXT: movpl r2, #0
; THUMB7-NEXT: and.w r1, r1, r12
; THUMB7-NEXT: ands r0, r2
; THUMB7-NEXT: orrs r0, r1
; THUMB7-NEXT: clz r0, r0
@ -636,8 +626,8 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
;
; THUMB8-LABEL: scalar_i64_bitsinmiddle_eq:
; THUMB8: @ %bb.0:
; THUMB8-NEXT: .save {r4, lr}
; THUMB8-NEXT: push {r4, lr}
; THUMB8-NEXT: .save {r7, lr}
; THUMB8-NEXT: push {r7, lr}
; THUMB8-NEXT: movw r3, #65535
; THUMB8-NEXT: movw lr, #0
; THUMB8-NEXT: lsl.w r12, r3, r2
@ -645,20 +635,19 @@ define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
; THUMB8-NEXT: movt lr, #65535
; THUMB8-NEXT: lsr.w r3, lr, r3
; THUMB8-NEXT: orr.w r12, r12, r3
; THUMB8-NEXT: sub.w r3, r2, #32
; THUMB8-NEXT: subs.w r3, r2, #32
; THUMB8-NEXT: lsl.w r2, lr, r2
; THUMB8-NEXT: cmp r3, #0
; THUMB8-NEXT: lsl.w r4, lr, r3
; THUMB8-NEXT: it lt
; THUMB8-NEXT: movlt r4, r12
; THUMB8-NEXT: it ge
; THUMB8-NEXT: movge r2, #0
; THUMB8-NEXT: ands r1, r4
; THUMB8-NEXT: lsl.w r3, lr, r3
; THUMB8-NEXT: it mi
; THUMB8-NEXT: movmi r3, r12
; THUMB8-NEXT: it pl
; THUMB8-NEXT: movpl r2, #0
; THUMB8-NEXT: ands r1, r3
; THUMB8-NEXT: ands r0, r2
; THUMB8-NEXT: orrs r0, r1
; THUMB8-NEXT: clz r0, r0
; THUMB8-NEXT: lsrs r0, r0, #5
; THUMB8-NEXT: pop {r4, pc}
; THUMB8-NEXT: pop {r7, pc}
%t0 = shl i64 281474976645120, %y
%t1 = and i64 %t0, %x
%res = icmp eq i64 %t1, 0
@ -1250,7 +1239,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; ARM6-NEXT: sxtb r1, r0
; ARM6-NEXT: mov r0, #0
; ARM6-NEXT: cmp r1, #0
; ARM6-NEXT: movlt r0, #1
; ARM6-NEXT: movmi r0, #1
; ARM6-NEXT: bx lr
;
; ARM78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
@ -1261,7 +1250,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; ARM78-NEXT: sxtb r1, r0
; ARM78-NEXT: mov r0, #0
; ARM78-NEXT: cmp r1, #0
; ARM78-NEXT: movwlt r0, #1
; ARM78-NEXT: movwmi r0, #1
; ARM78-NEXT: bx lr
;
; THUMB6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
@ -1272,7 +1261,7 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; THUMB6-NEXT: ands r2, r0
; THUMB6-NEXT: sxtb r0, r2
; THUMB6-NEXT: cmp r0, #0
; THUMB6-NEXT: blt .LBB20_2
; THUMB6-NEXT: bmi .LBB20_2
; THUMB6-NEXT: @ %bb.1:
; THUMB6-NEXT: movs r0, #0
; THUMB6-NEXT: bx lr
@ -1289,8 +1278,8 @@ define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
; THUMB78-NEXT: sxtb r1, r0
; THUMB78-NEXT: movs r0, #0
; THUMB78-NEXT: cmp r1, #0
; THUMB78-NEXT: it lt
; THUMB78-NEXT: movlt r0, #1
; THUMB78-NEXT: it mi
; THUMB78-NEXT: movmi r0, #1
; THUMB78-NEXT: bx lr
%t0 = shl i8 24, %y
%t1 = and i8 %t0, %x

View File

@ -28,18 +28,16 @@ define i64 @f0(i64 %A, i64 %B) {
define i32 @f1(i64 %x, i64 %y) {
; CHECK-LE-LABEL: f1:
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: sub r1, r2, #32
; CHECK-LE-NEXT: lsl r0, r0, r2
; CHECK-LE-NEXT: cmp r1, #0
; CHECK-LE-NEXT: movge r0, #0
; CHECK-LE-NEXT: subs r1, r2, #32
; CHECK-LE-NEXT: movpl r0, #0
; CHECK-LE-NEXT: mov pc, lr
;
; CHECK-BE-LABEL: f1:
; CHECK-BE: @ %bb.0:
; CHECK-BE-NEXT: lsl r0, r1, r3
; CHECK-BE-NEXT: sub r1, r3, #32
; CHECK-BE-NEXT: cmp r1, #0
; CHECK-BE-NEXT: movge r0, #0
; CHECK-BE-NEXT: subs r1, r3, #32
; CHECK-BE-NEXT: movpl r0, #0
; CHECK-BE-NEXT: mov pc, lr
%a = shl i64 %x, %y
@ -52,10 +50,9 @@ define i32 @f2(i64 %x, i64 %y) {
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: rsb r3, r2, #32
; CHECK-LE-NEXT: lsr r0, r0, r2
; CHECK-LE-NEXT: sub r2, r2, #32
; CHECK-LE-NEXT: subs r2, r2, #32
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
; CHECK-LE-NEXT: cmp r2, #0
; CHECK-LE-NEXT: asrge r0, r1, r2
; CHECK-LE-NEXT: asrpl r0, r1, r2
; CHECK-LE-NEXT: mov pc, lr
;
; CHECK-BE-LABEL: f2:
@ -63,9 +60,8 @@ define i32 @f2(i64 %x, i64 %y) {
; CHECK-BE-NEXT: rsb r2, r3, #32
; CHECK-BE-NEXT: lsr r1, r1, r3
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
; CHECK-BE-NEXT: sub r2, r3, #32
; CHECK-BE-NEXT: cmp r2, #0
; CHECK-BE-NEXT: asrge r1, r0, r2
; CHECK-BE-NEXT: subs r2, r3, #32
; CHECK-BE-NEXT: asrpl r1, r0, r2
; CHECK-BE-NEXT: mov r0, r1
; CHECK-BE-NEXT: mov pc, lr
@ -79,10 +75,9 @@ define i32 @f3(i64 %x, i64 %y) {
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: rsb r3, r2, #32
; CHECK-LE-NEXT: lsr r0, r0, r2
; CHECK-LE-NEXT: sub r2, r2, #32
; CHECK-LE-NEXT: subs r2, r2, #32
; CHECK-LE-NEXT: orr r0, r0, r1, lsl r3
; CHECK-LE-NEXT: cmp r2, #0
; CHECK-LE-NEXT: lsrge r0, r1, r2
; CHECK-LE-NEXT: lsrpl r0, r1, r2
; CHECK-LE-NEXT: mov pc, lr
;
; CHECK-BE-LABEL: f3:
@ -90,9 +85,8 @@ define i32 @f3(i64 %x, i64 %y) {
; CHECK-BE-NEXT: rsb r2, r3, #32
; CHECK-BE-NEXT: lsr r1, r1, r3
; CHECK-BE-NEXT: orr r1, r1, r0, lsl r2
; CHECK-BE-NEXT: sub r2, r3, #32
; CHECK-BE-NEXT: cmp r2, #0
; CHECK-BE-NEXT: lsrge r1, r0, r2
; CHECK-BE-NEXT: subs r2, r3, #32
; CHECK-BE-NEXT: lsrpl r1, r0, r2
; CHECK-BE-NEXT: mov r0, r1
; CHECK-BE-NEXT: mov pc, lr

View File

@ -39,15 +39,14 @@ define i16 @sat0_base_16bit(i16 %x) #0 {
; CHECK-ARM-NEXT: lsl r1, r0, #16
; CHECK-ARM-NEXT: asr r1, r1, #16
; CHECK-ARM-NEXT: cmp r1, #0
; CHECK-ARM-NEXT: movlt r0, #0
; CHECK-ARM-NEXT: movmi r0, #0
; CHECK-ARM-NEXT: mov pc, lr
;
; CHECK-T-LABEL: sat0_base_16bit:
; CHECK-T: @ %bb.0: @ %entry
; CHECK-T-NEXT: lsls r1, r0, #16
; CHECK-T-NEXT: asrs r1, r1, #16
; CHECK-T-NEXT: cmp r1, #0
; CHECK-T-NEXT: bge .LBB1_2
; CHECK-T-NEXT: bpl .LBB1_2
; CHECK-T-NEXT: @ %bb.1:
; CHECK-T-NEXT: movs r0, #0
; CHECK-T-NEXT: .LBB1_2: @ %entry
@ -57,8 +56,8 @@ define i16 @sat0_base_16bit(i16 %x) #0 {
; CHECK-T2: @ %bb.0: @ %entry
; CHECK-T2-NEXT: sxth r1, r0
; CHECK-T2-NEXT: cmp r1, #0
; CHECK-T2-NEXT: it lt
; CHECK-T2-NEXT: movlt r0, #0
; CHECK-T2-NEXT: it mi
; CHECK-T2-NEXT: movmi r0, #0
; CHECK-T2-NEXT: bx lr
entry:
%cmpLow = icmp slt i16 %x, 0
@ -74,15 +73,14 @@ define i8 @sat0_base_8bit(i8 %x) #0 {
; CHECK-ARM-NEXT: lsl r1, r0, #24
; CHECK-ARM-NEXT: asr r1, r1, #24
; CHECK-ARM-NEXT: cmp r1, #0
; CHECK-ARM-NEXT: movlt r0, #0
; CHECK-ARM-NEXT: movmi r0, #0
; CHECK-ARM-NEXT: mov pc, lr
;
; CHECK-T-LABEL: sat0_base_8bit:
; CHECK-T: @ %bb.0: @ %entry
; CHECK-T-NEXT: lsls r1, r0, #24
; CHECK-T-NEXT: asrs r1, r1, #24
; CHECK-T-NEXT: cmp r1, #0
; CHECK-T-NEXT: bge .LBB2_2
; CHECK-T-NEXT: bpl .LBB2_2
; CHECK-T-NEXT: @ %bb.1:
; CHECK-T-NEXT: movs r0, #0
; CHECK-T-NEXT: .LBB2_2: @ %entry
@ -92,8 +90,8 @@ define i8 @sat0_base_8bit(i8 %x) #0 {
; CHECK-T2: @ %bb.0: @ %entry
; CHECK-T2-NEXT: sxtb r1, r0
; CHECK-T2-NEXT: cmp r1, #0
; CHECK-T2-NEXT: it lt
; CHECK-T2-NEXT: movlt r0, #0
; CHECK-T2-NEXT: it mi
; CHECK-T2-NEXT: movmi r0, #0
; CHECK-T2-NEXT: bx lr
entry:
%cmpLow = icmp slt i8 %x, 0
@ -265,14 +263,14 @@ define i32 @no_sat0_incorrect_variable(i32 %x, i32 %y) #0 {
; CHECK-ARM-LABEL: no_sat0_incorrect_variable:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: cmp r0, #0
; CHECK-ARM-NEXT: movlt r1, #0
; CHECK-ARM-NEXT: movmi r1, #0
; CHECK-ARM-NEXT: mov r0, r1
; CHECK-ARM-NEXT: mov pc, lr
;
; CHECK-T-LABEL: no_sat0_incorrect_variable:
; CHECK-T: @ %bb.0: @ %entry
; CHECK-T-NEXT: cmp r0, #0
; CHECK-T-NEXT: bge .LBB8_2
; CHECK-T-NEXT: bpl .LBB8_2
; CHECK-T-NEXT: @ %bb.1:
; CHECK-T-NEXT: movs r1, #0
; CHECK-T-NEXT: .LBB8_2: @ %entry
@ -282,8 +280,8 @@ define i32 @no_sat0_incorrect_variable(i32 %x, i32 %y) #0 {
; CHECK-T2-LABEL: no_sat0_incorrect_variable:
; CHECK-T2: @ %bb.0: @ %entry
; CHECK-T2-NEXT: cmp r0, #0
; CHECK-T2-NEXT: it lt
; CHECK-T2-NEXT: movlt r1, #0
; CHECK-T2-NEXT: it mi
; CHECK-T2-NEXT: movmi r1, #0
; CHECK-T2-NEXT: mov r0, r1
; CHECK-T2-NEXT: bx lr
entry:
@ -297,13 +295,13 @@ define i32 @no_sat0_incorrect_constant(i32 %x) {
; CHECK-ARM-LABEL: no_sat0_incorrect_constant:
; CHECK-ARM: @ %bb.0: @ %entry
; CHECK-ARM-NEXT: cmp r0, #0
; CHECK-ARM-NEXT: mvnlt r0, #0
; CHECK-ARM-NEXT: mvnmi r0, #0
; CHECK-ARM-NEXT: mov pc, lr
;
; CHECK-T-LABEL: no_sat0_incorrect_constant:
; CHECK-T: @ %bb.0: @ %entry
; CHECK-T-NEXT: cmp r0, #0
; CHECK-T-NEXT: bge .LBB9_2
; CHECK-T-NEXT: bpl .LBB9_2
; CHECK-T-NEXT: @ %bb.1:
; CHECK-T-NEXT: movs r0, #0
; CHECK-T-NEXT: mvns r0, r0
@ -313,8 +311,8 @@ define i32 @no_sat0_incorrect_constant(i32 %x) {
; CHECK-T2-LABEL: no_sat0_incorrect_constant:
; CHECK-T2: @ %bb.0: @ %entry
; CHECK-T2-NEXT: cmp r0, #0
; CHECK-T2-NEXT: it lt
; CHECK-T2-NEXT: movlt.w r0, #-1
; CHECK-T2-NEXT: it mi
; CHECK-T2-NEXT: movmi.w r0, #-1
; CHECK-T2-NEXT: bx lr
entry:
%cmpLow = icmp slt i32 %x, 0

View File

@ -62,8 +62,8 @@ entry:
define double @f7(double %a, double %b) {
;CHECK-LABEL: f7:
;CHECK: movlt
;CHECK: movge
;CHECK: movmi
;CHECK: movpl
;CHECK-VFP-LABEL: f7:
;CHECK-VFP: vmovmi
%tmp = fcmp olt double %a, 1.234e+00

View File

@ -8,11 +8,10 @@ define i64 @test_shl(i64 %val, i64 %amt) {
; CHECK-NEXT: rsb r3, r2, #32
; CHECK-NEXT: lsr r3, r0, r3
; CHECK-NEXT: orr r1, r3, r1, lsl r2
; CHECK-NEXT: sub r3, r2, #32
; CHECK-NEXT: cmp r3, #0
; CHECK-NEXT: lslge r1, r0, r3
; CHECK-NEXT: subs r3, r2, #32
; CHECK-NEXT: lslpl r1, r0, r3
; CHECK-NEXT: lsl r0, r0, r2
; CHECK-NEXT: movge r0, #0
; CHECK-NEXT: movpl r0, #0
; CHECK-NEXT: mov pc, lr
;
; EXPAND-LABEL: test_shl:
@ -32,11 +31,10 @@ define i64 @test_lshr(i64 %val, i64 %amt) {
; CHECK-NEXT: rsb r3, r2, #32
; CHECK-NEXT: lsr r0, r0, r2
; CHECK-NEXT: orr r0, r0, r1, lsl r3
; CHECK-NEXT: sub r3, r2, #32
; CHECK-NEXT: cmp r3, #0
; CHECK-NEXT: lsrge r0, r1, r3
; CHECK-NEXT: subs r3, r2, #32
; CHECK-NEXT: lsrpl r0, r1, r3
; CHECK-NEXT: lsr r1, r1, r2
; CHECK-NEXT: movge r1, #0
; CHECK-NEXT: movpl r1, #0
; CHECK-NEXT: mov pc, lr
;
; EXPAND-LABEL: test_lshr:
@ -54,14 +52,13 @@ define i64 @test_lshr(i64 %val, i64 %amt) {
define i64 @test_ashr(i64 %val, i64 %amt) {
; CHECK-LABEL: test_ashr:
; CHECK: @ %bb.0:
; CHECK-NEXT: sub r12, r2, #32
; CHECK-NEXT: asr r3, r1, r2
; CHECK-NEXT: subs r12, r2, #32
; CHECK-NEXT: lsr r0, r0, r2
; CHECK-NEXT: rsb r2, r2, #32
; CHECK-NEXT: cmp r12, #0
; CHECK-NEXT: asrpl r3, r1, #31
; CHECK-NEXT: orr r0, r0, r1, lsl r2
; CHECK-NEXT: asrge r3, r1, #31
; CHECK-NEXT: asrge r0, r1, r12
; CHECK-NEXT: asrpl r0, r1, r12
; CHECK-NEXT: mov r1, r3
; CHECK-NEXT: mov pc, lr
;

View File

@ -73,8 +73,8 @@ define double @f7(double %a, double %b) {
ret double %tmp1
}
; CHECK-LABEL: f7:
; CHECK: {{blt|bge}}
; CHECK: {{blt|bge}}
; CHECK: {{bmi|bpl}}
; CHECK: {{bmi|bpl}}
; CHECK: __ltdf2
; CHECK-EABI-LABEL: f7:
; CHECK-EABI: __aeabi_dcmplt