if (!VT.isInteger())
return SDValue();
+ // Fold away an unneccessary CMPZ/CMOV
+ // CMOV A, B, C1, $cpsr, (CMPZ (CMOV 1, 0, C2, D), 0) ->
+ // if C1==EQ -> CMOV A, B, C2, $cpsr, D
+ // if C1==NE -> CMOV A, B, NOT(C2), $cpsr, D
+ if (N->getConstantOperandVal(2) == ARMCC::EQ ||
+ N->getConstantOperandVal(2) == ARMCC::NE) {
+ ARMCC::CondCodes Cond;
+ if (SDValue C = IsCMPZCSINC(N->getOperand(4).getNode(), Cond)) {
+ if (N->getConstantOperandVal(2) == ARMCC::NE)
+ Cond = ARMCC::getOppositeCondition(Cond);
+ return DAG.getNode(N->getOpcode(), SDLoc(N), MVT::i32, N->getOperand(0),
+ N->getOperand(1),
+ DAG.getTargetConstant(Cond, SDLoc(N), MVT::i32),
+ N->getOperand(3), C);
+ }
+ }
+
// Materialize a boolean comparison for integers so we can avoid branching.
if (isNullConstant(FalseVal)) {
if (CC == ARMCC::EQ && isOneConstant(TrueVal)) {
; CHECK-NEXT: vmov r0, r1, d0
; CHECK-NEXT: orrs r0, r1
; CHECK-NEXT: vmov r1, r2, d2
-; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r1, r2
; CHECK-NEXT: cset r1, eq
; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: movne r1, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: moveq r1, #1
; CHECK-NEXT: rsbs r0, r1, #0
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: bfi r1, r0, #0, #8
; CHECK-NEXT: vmov r0, r2, d1
; CHECK-NEXT: orrs r0, r2
; CHECK-NEXT: vmov r2, r3, d3
-; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r2, r3
; CHECK-NEXT: cset r2, eq
; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: movne r2, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: moveq r2, #1
; CHECK-NEXT: rsbs r0, r2, #0
; CHECK-NEXT: bfi r1, r0, #8, #8
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmov r1, r2, d0
; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r1, r2
-; CHECK-NEXT: vmov r12, r2, d5
-; CHECK-NEXT: cset r1, eq
-; CHECK-NEXT: cmp r1, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: movne r0, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: moveq r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: bfi r1, r0, #0, #8
+; CHECK-NEXT: vmov r12, r2, d5
; CHECK-NEXT: vmov r3, r0, d3
; CHECK-NEXT: eors r0, r2
; CHECK-NEXT: eor.w r2, r3, r12
; CHECK-NEXT: vmov r2, r3, d1
; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r2, r3
-; CHECK-NEXT: cset r2, eq
-; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: movne r0, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: moveq r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #8, #8
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmov r0, r1, d4
; CHECK-NEXT: orrs r0, r1
; CHECK-NEXT: vmov r1, r2, d0
-; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r1, r2
; CHECK-NEXT: vmov r2, r3, d2
; CHECK-NEXT: cset r1, eq
; CHECK-NEXT: orrs r2, r3
; CHECK-NEXT: cset r2, eq
; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: csel r0, r1, r2, ne
+; CHECK-NEXT: csel r0, r1, r2, eq
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #0, #8
; CHECK-NEXT: vmov r0, r2, d5
-; CHECK-NEXT: orrs r0, r2
+; CHECK-NEXT: orr.w r12, r0, r2
; CHECK-NEXT: vmov r2, r3, d1
-; CHECK-NEXT: cset r12, eq
; CHECK-NEXT: orrs r2, r3
; CHECK-NEXT: vmov r3, r0, d3
; CHECK-NEXT: cset r2, eq
; CHECK-NEXT: orrs r0, r3
; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: cmp.w r12, #0
-; CHECK-NEXT: csel r0, r2, r0, ne
+; CHECK-NEXT: csel r0, r2, r0, eq
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #8, #8
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmov r0, r1, d0
; CHECK-NEXT: orrs r0, r1
; CHECK-NEXT: vmov r1, r2, d2
-; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r1, r2
; CHECK-NEXT: cset r1, eq
; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r1, r1, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: eoreq r1, r1, #1
; CHECK-NEXT: rsbs r0, r1, #0
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: bfi r1, r0, #0, #8
; CHECK-NEXT: vmov r0, r2, d1
; CHECK-NEXT: orrs r0, r2
; CHECK-NEXT: vmov r2, r3, d3
-; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r2, r3
; CHECK-NEXT: cset r2, eq
; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r2, r2, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: eoreq r2, r2, #1
; CHECK-NEXT: rsbs r0, r2, #0
; CHECK-NEXT: bfi r1, r0, #8, #8
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmov r1, r2, d0
; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r1, r2
-; CHECK-NEXT: vmov r12, r2, d5
-; CHECK-NEXT: cset r1, eq
-; CHECK-NEXT: cmp r1, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r0, r0, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: eoreq r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: bfi r1, r0, #0, #8
+; CHECK-NEXT: vmov r12, r2, d5
; CHECK-NEXT: vmov r3, r0, d3
; CHECK-NEXT: eors r0, r2
; CHECK-NEXT: eor.w r2, r3, r12
; CHECK-NEXT: vmov r2, r3, d1
; CHECK-NEXT: cset r0, eq
; CHECK-NEXT: orrs r2, r3
-; CHECK-NEXT: cset r2, eq
-; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r0, r0, #1
+; CHECK-NEXT: it eq
+; CHECK-NEXT: eoreq r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #8, #8
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: cmp r1, #0
; CHECK-NEXT: cset r1, ne
; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: cset r2, mi
-; CHECK-NEXT: cmp r2, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r1, r1, #1
-; CHECK-NEXT: rsbs r1, r1, #0
+; CHECK-NEXT: it mi
+; CHECK-NEXT: eormi r1, r1, #1
; CHECK-NEXT: movs r2, #0
+; CHECK-NEXT: rsbs r1, r1, #0
; CHECK-NEXT: bfi r2, r1, #0, #8
; CHECK-NEXT: vmov r1, r3, d3
; CHECK-NEXT: adds r1, r1, r0
; CHECK-NEXT: vmov q0[3], q0[1], lr, r5
; CHECK-NEXT: cset r0, ne
; CHECK-NEXT: cmp r3, #0
-; CHECK-NEXT: cset r3, mi
-; CHECK-NEXT: cmp r3, #0
-; CHECK-NEXT: it ne
-; CHECK-NEXT: eorne r0, r0, #1
+; CHECK-NEXT: it mi
+; CHECK-NEXT: eormi r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r2, r0, #8, #8
; CHECK-NEXT: asrs r0, r5, #31