From 8121a10f943b594cf74bb7972fd9b88d1a8b7738 Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 1 Aug 2025 13:21:36 -0400 Subject: [PATCH 1/5] [SelectionDAG] Move sign pattern check from AArch64 and ARM to general SelectionDAG --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 ++++++++ .../Target/AArch64/AArch64ISelLowering.cpp | 12 ------- llvm/lib/Target/ARM/ARMISelLowering.cpp | 12 ------- llvm/test/CodeGen/ARM/cmp-select-sign.ll | 32 +++++++++---------- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a43020ee62281..0097e8e1aa1a3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28972,6 +28972,19 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, DAG.getSExtOrTrunc(CC == ISD::SETLT ? N3 : N2, DL, VT)); } + // Check for sign pattern (SELECT_CC setgt, iN X, -1, 1, -1) and transform + // into (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 ASR = DAG.getNode( + ISD::SRA, DL, CmpOpVT, N0, + DAG.getConstant(CmpOpVT.getScalarSizeInBits() - 1, DL, CmpOpVT)); + return DAG.getNode(ISD::OR, DL, VT, DAG.getSExtOrTrunc(ASR, 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 From 1c6e7dc33ea1595521c7bafb254f8c5e474924a3 Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 1 Aug 2025 14:04:54 -0400 Subject: [PATCH 2/5] Use ashr and getShiftAmountConstant --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0097e8e1aa1a3..bb0e1d251825a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28965,10 +28965,10 @@ 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( + SDValue ASHR = 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), + 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)); } @@ -28978,10 +28978,10 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, N2C->isOne() && N3C->isAllOnes() && !TLI.shouldAvoidTransformToShift(CmpOpVT, CmpOpVT.getScalarSizeInBits() - 1)) { - SDValue ASR = DAG.getNode( + SDValue ASHR = DAG.getNode( ISD::SRA, DL, CmpOpVT, N0, - DAG.getConstant(CmpOpVT.getScalarSizeInBits() - 1, DL, CmpOpVT)); - return DAG.getNode(ISD::OR, DL, VT, DAG.getSExtOrTrunc(ASR, DL, VT), + DAG.getShiftAmountConstant(CmpOpVT.getScalarSizeInBits() - 1, CmpOpVT, DL)); + return DAG.getNode(ISD::OR, DL, VT, DAG.getSExtOrTrunc(ASHR, DL, VT), DAG.getConstant(1, DL, VT)); } From e5b532406ba4ec59bf3383b3871852b865209013 Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 1 Aug 2025 14:11:17 -0400 Subject: [PATCH 3/5] clang-format --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index bb0e1d251825a..02c3edf7a50e0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28965,9 +28965,10 @@ 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 ASHR = DAG.getNode( - ISD::SRA, DL, CmpOpVT, N0, - DAG.getShiftAmountConstant(CmpOpVT.getScalarSizeInBits() - 1, CmpOpVT, DL)); + 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)); } @@ -28978,9 +28979,10 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, 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)); + 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)); } From 17e29e0e4d5c1e7487fa1afaa9f7dfa0fb12ce8d Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 1 Aug 2025 14:48:44 -0400 Subject: [PATCH 4/5] Fix sign pattern comment --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 02c3edf7a50e0..f735c4b5b09be 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28973,8 +28973,7 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, DAG.getSExtOrTrunc(CC == ISD::SETLT ? N3 : N2, DL, VT)); } - // Check for sign pattern (SELECT_CC setgt, iN X, -1, 1, -1) and transform - // into (or (ashr X, BW-1), 1). + // Fold sign pattern select_cc setgt X, -1, 1, -1 -> (ashr X, BW-1), 1 if (CC == ISD::SETGT && N1C && N2C && N3C && N1C->isAllOnes() && N2C->isOne() && N3C->isAllOnes() && !TLI.shouldAvoidTransformToShift(CmpOpVT, From 0fa1036ee5556bd6d4d2e104a15a43fc98f08471 Mon Sep 17 00:00:00 2001 From: Rose Date: Fri, 1 Aug 2025 16:20:46 -0400 Subject: [PATCH 5/5] Fix comment --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f735c4b5b09be..7c73a78ae42c4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -28973,7 +28973,7 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1, DAG.getSExtOrTrunc(CC == ISD::SETLT ? N3 : N2, DL, VT)); } - // Fold sign pattern select_cc setgt X, -1, 1, -1 -> (ashr X, BW-1), 1 + // 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,