Index: llvm/lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -17954,6 +17954,23 @@ 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)) { Index: llvm/test/CodeGen/Thumb2/mve-pred-or.ll =================================================================== --- llvm/test/CodeGen/Thumb2/mve-pred-or.ll +++ llvm/test/CodeGen/Thumb2/mve-pred-or.ll @@ -380,24 +380,22 @@ ; 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 @@ -422,14 +420,12 @@ ; 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 @@ -437,10 +433,8 @@ ; 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 Index: llvm/test/CodeGen/Thumb2/mve-pred-vselect.ll =================================================================== --- llvm/test/CodeGen/Thumb2/mve-pred-vselect.ll +++ llvm/test/CodeGen/Thumb2/mve-pred-vselect.ll @@ -73,28 +73,26 @@ ; 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 Index: llvm/test/CodeGen/Thumb2/mve-pred-xor.ll =================================================================== --- llvm/test/CodeGen/Thumb2/mve-pred-xor.ll +++ llvm/test/CodeGen/Thumb2/mve-pred-xor.ll @@ -460,24 +460,22 @@ ; 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 @@ -502,14 +500,12 @@ ; 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 @@ -517,10 +513,8 @@ ; 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 Index: llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll =================================================================== --- llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll +++ llvm/test/CodeGen/Thumb2/mve-saturating-arith.ll @@ -47,12 +47,10 @@ ; 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 @@ -66,10 +64,8 @@ ; 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