diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a43020ee62281..7c73a78ae42c4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28965,13 +28965,27 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, ((N1C->isAllOnes() && CC == ISD::SETGT) || (N1C->isZero() && CC == ISD::SETLT)) && !TLI.shouldAvoidTransformToShift(VT, CmpOpVT.getScalarSizeInBits() - 1)) { - SDValue ASR = DAG.getNode( - ISD::SRA, DL, CmpOpVT, N0, - DAG.getConstant(CmpOpVT.getScalarSizeInBits() - 1, DL, CmpOpVT)); - return DAG.getNode(ISD::XOR, DL, VT, DAG.getSExtOrTrunc(ASR, DL, VT), + SDValue ASHR = + DAG.getNode(ISD::SRA, DL, CmpOpVT, N0, + DAG.getShiftAmountConstant( + CmpOpVT.getScalarSizeInBits() - 1, CmpOpVT, DL)); + return DAG.getNode(ISD::XOR, DL, VT, DAG.getSExtOrTrunc(ASHR, DL, VT), DAG.getSExtOrTrunc(CC == ISD::SETLT ? N3 : N2, DL, VT)); } + // Fold sign pattern select_cc setgt X, -1, 1, -1 -> or (ashr X, BW-1), 1 + if (CC == ISD::SETGT && N1C && N2C && N3C && N1C->isAllOnes() && + N2C->isOne() && N3C->isAllOnes() && + !TLI.shouldAvoidTransformToShift(CmpOpVT, + CmpOpVT.getScalarSizeInBits() - 1)) { + SDValue ASHR = + DAG.getNode(ISD::SRA, DL, CmpOpVT, N0, + DAG.getShiftAmountConstant( + CmpOpVT.getScalarSizeInBits() - 1, CmpOpVT, DL)); + return DAG.getNode(ISD::OR, DL, VT, DAG.getSExtOrTrunc(ASHR, DL, VT), + DAG.getConstant(1, DL, VT)); + } + if (SDValue S = PerformMinMaxFpToSatCombine(N0, N1, N2, N3, CC, DAG)) return S; if (SDValue S = PerformUMinFpToSatCombine(N0, N1, N2, N3, CC, DAG)) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 4f6e3ddd18def..d1aedae0b09e6 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11360,18 +11360,6 @@ SDValue AArch64TargetLowering::LowerSELECT_CC( ConstantSDNode *CFVal = dyn_cast(FVal); ConstantSDNode *CTVal = dyn_cast(TVal); ConstantSDNode *RHSC = dyn_cast(RHS); - // Check for sign pattern (SELECT_CC setgt, iN lhs, -1, 1, -1) and transform - // into (OR (ASR lhs, N-1), 1), which requires less instructions for the - // supported types. - if (CC == ISD::SETGT && RHSC && RHSC->isAllOnes() && CTVal && CFVal && - CTVal->isOne() && CFVal->isAllOnes() && - LHS.getValueType() == TVal.getValueType()) { - EVT VT = LHS.getValueType(); - SDValue Shift = - DAG.getNode(ISD::SRA, DL, VT, LHS, - DAG.getConstant(VT.getSizeInBits() - 1, DL, VT)); - return DAG.getNode(ISD::OR, DL, VT, Shift, DAG.getConstant(1, DL, VT)); - } // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns. // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1)) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index bd4b75fd3c167..936625606e315 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -5521,18 +5521,6 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { ConstantSDNode *CTVal = dyn_cast(TrueVal); ConstantSDNode *RHSC = dyn_cast(RHS); if (Op.getValueType().isInteger()) { - // Check for sign pattern (SELECT_CC setgt, iN lhs, -1, 1, -1) and transform - // into (OR (ASR lhs, N-1), 1), which requires less instructions for the - // supported types. - if (CC == ISD::SETGT && RHSC && RHSC->isAllOnes() && CTVal && CFVal && - CTVal->isOne() && CFVal->isAllOnes() && - LHS.getValueType() == TrueVal.getValueType()) { - EVT VT = LHS.getValueType(); - SDValue Shift = - DAG.getNode(ISD::SRA, dl, VT, LHS, - DAG.getConstant(VT.getSizeInBits() - 1, dl, VT)); - return DAG.getNode(ISD::OR, dl, VT, Shift, DAG.getConstant(1, dl, VT)); - } // Check for SMAX(lhs, 0) and SMIN(lhs, 0) patterns. // (SELECT_CC setgt, lhs, 0, lhs, 0) -> (BIC lhs, (SRA lhs, typesize-1)) diff --git a/llvm/test/CodeGen/ARM/cmp-select-sign.ll b/llvm/test/CodeGen/ARM/cmp-select-sign.ll index 298a623ed1d87..61cdc3bdcd277 100644 --- a/llvm/test/CodeGen/ARM/cmp-select-sign.ll +++ b/llvm/test/CodeGen/ARM/cmp-select-sign.ll @@ -75,31 +75,31 @@ define i4 @sign_i4(i4 %a) { define i8 @sign_i8(i8 %a) { ; ARM-LABEL: sign_i8: ; ARM: @ %bb.0: -; ARM-NEXT: lsl r0, r0, #24 +; ARM-NEXT: sxtb r0, r0 ; ARM-NEXT: mov r1, #1 -; ARM-NEXT: orr r0, r1, r0, asr #31 +; ARM-NEXT: orr r0, r1, r0, asr #7 ; ARM-NEXT: bx lr ; ; THUMB-LABEL: sign_i8: ; THUMB: @ %bb.0: -; THUMB-NEXT: lsls r0, r0, #24 -; THUMB-NEXT: asrs r1, r0, #31 +; THUMB-NEXT: sxtb r0, r0 +; THUMB-NEXT: asrs r1, r0, #7 ; THUMB-NEXT: movs r0, #1 ; THUMB-NEXT: orrs r0, r1 ; THUMB-NEXT: bx lr ; ; THUMB2-LABEL: sign_i8: ; THUMB2: @ %bb.0: -; THUMB2-NEXT: lsls r0, r0, #24 +; THUMB2-NEXT: sxtb r0, r0 ; THUMB2-NEXT: movs r1, #1 -; THUMB2-NEXT: orr.w r0, r1, r0, asr #31 +; THUMB2-NEXT: orr.w r0, r1, r0, asr #7 ; THUMB2-NEXT: bx lr ; ; THUMBV8-LABEL: sign_i8: ; THUMBV8: @ %bb.0: -; THUMBV8-NEXT: lsls r0, r0, #24 +; THUMBV8-NEXT: sxtb r0, r0 ; THUMBV8-NEXT: movs r1, #1 -; THUMBV8-NEXT: orr.w r0, r1, r0, asr #31 +; THUMBV8-NEXT: orr.w r0, r1, r0, asr #7 ; THUMBV8-NEXT: bx lr %c = icmp sgt i8 %a, -1 %res = select i1 %c, i8 1, i8 -1 @@ -109,31 +109,31 @@ define i8 @sign_i8(i8 %a) { define i16 @sign_i16(i16 %a) { ; ARM-LABEL: sign_i16: ; ARM: @ %bb.0: -; ARM-NEXT: lsl r0, r0, #16 +; ARM-NEXT: sxth r0, r0 ; ARM-NEXT: mov r1, #1 -; ARM-NEXT: orr r0, r1, r0, asr #31 +; ARM-NEXT: orr r0, r1, r0, asr #15 ; ARM-NEXT: bx lr ; ; THUMB-LABEL: sign_i16: ; THUMB: @ %bb.0: -; THUMB-NEXT: lsls r0, r0, #16 -; THUMB-NEXT: asrs r1, r0, #31 +; THUMB-NEXT: sxth r0, r0 +; THUMB-NEXT: asrs r1, r0, #15 ; THUMB-NEXT: movs r0, #1 ; THUMB-NEXT: orrs r0, r1 ; THUMB-NEXT: bx lr ; ; THUMB2-LABEL: sign_i16: ; THUMB2: @ %bb.0: -; THUMB2-NEXT: lsls r0, r0, #16 +; THUMB2-NEXT: sxth r0, r0 ; THUMB2-NEXT: movs r1, #1 -; THUMB2-NEXT: orr.w r0, r1, r0, asr #31 +; THUMB2-NEXT: orr.w r0, r1, r0, asr #15 ; THUMB2-NEXT: bx lr ; ; THUMBV8-LABEL: sign_i16: ; THUMBV8: @ %bb.0: -; THUMBV8-NEXT: lsls r0, r0, #16 +; THUMBV8-NEXT: sxth r0, r0 ; THUMBV8-NEXT: movs r1, #1 -; THUMBV8-NEXT: orr.w r0, r1, r0, asr #31 +; THUMBV8-NEXT: orr.w r0, r1, r0, asr #15 ; THUMBV8-NEXT: bx lr %c = icmp sgt i16 %a, -1 %res = select i1 %c, i16 1, i16 -1