[llvm] 23022a4 - [SelectionDAG] Move sign pattern check from AArch64 and ARM to general SelectionDAG (#151736)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 1 14:46:54 PDT 2025


Author: AZero13
Date: 2025-08-01T14:46:51-07:00
New Revision: 23022a4683b61c5705fe6bf756b5f33648bd3fbc

URL: https://github.com/llvm/llvm-project/commit/23022a4683b61c5705fe6bf756b5f33648bd3fbc
DIFF: https://github.com/llvm/llvm-project/commit/23022a4683b61c5705fe6bf756b5f33648bd3fbc.diff

LOG: [SelectionDAG] Move sign pattern check from AArch64 and ARM to general SelectionDAG (#151736)

This works on all cases much like the XOR case above it in SelectionDAG.

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/lib/Target/ARM/ARMISelLowering.cpp
    llvm/test/CodeGen/ARM/cmp-select-sign.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5989c1d1c76b8..11e869aebe7da 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -29025,13 +29025,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 8312b0475f57d..2b6ea86ee1af5 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11364,18 +11364,6 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(
     ConstantSDNode *CFVal = dyn_cast<ConstantSDNode>(FVal);
     ConstantSDNode *CTVal = dyn_cast<ConstantSDNode>(TVal);
     ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(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<ConstantSDNode>(TrueVal);
   ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(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


        


More information about the llvm-commits mailing list