[lldb] [clang] [libc] [libcxxabi] [libunwind] [llvm] [flang] [libcxx] [lld] [clang-tools-extra] [compiler-rt] [PowerPC] Combine sub within setcc back to sext (PR #66978)

Qiu Chaofan via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 29 18:12:47 PST 2023


https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/66978

>From 2a7b9be6cd0705590c85c51b35ea99fe053aaf47 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 6 Sep 2023 16:16:34 +0800
Subject: [PATCH 1/4] [PowerPC] Combine sub within setcc back to sext

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 37 +++++++++++++-----
 llvm/test/CodeGen/PowerPC/setcc-to-sub.ll   | 42 +++++++++++++++++++++
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f4e3531980d165f..4659ebef35ecf62 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14407,15 +14407,18 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N,
       ShiftCst);
 }
 
-SDValue PPCTargetLowering::combineSetCC(SDNode *N,
-                                        DAGCombinerInfo &DCI) const {
-  assert(N->getOpcode() == ISD::SETCC &&
-         "Should be called with a SETCC node");
+SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
+  assert(N->getOpcode() == ISD::SETCC && "Should be called with a SETCC node");
 
   ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
+  SDLoc DL(N);
+  SelectionDAG &DAG = DCI.DAG;
+  EVT VT = N->getValueType(0);
+  EVT OpVT = LHS.getValueType();
+
   if (CC == ISD::SETNE || CC == ISD::SETEQ) {
-    SDValue LHS = N->getOperand(0);
-    SDValue RHS = N->getOperand(1);
 
     // If there is a '0 - y' pattern, canonicalize the pattern to the RHS.
     if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) &&
@@ -14426,15 +14429,29 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N,
     // x != 0-y --> x+y != 0
     if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) &&
         RHS.hasOneUse()) {
-      SDLoc DL(N);
-      SelectionDAG &DAG = DCI.DAG;
-      EVT VT = N->getValueType(0);
-      EVT OpVT = LHS.getValueType();
       SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1));
       return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
     }
   }
 
+  // Combine (a-2^(M-1)) => sext(trunc(a, M), 64)
+  if (CC == ISD::SETULT && LHS.getOpcode() == ISD::ADD && OpVT == MVT::i64 &&
+      isa<ConstantSDNode>(RHS) && isa<ConstantSDNode>(LHS.getOperand(1))) {
+    uint64_t ShiftVal =
+        ~(cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue()) + 1;
+    uint64_t CmpVal = ~(cast<ConstantSDNode>(RHS)->getZExtValue()) + 1;
+    if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
+      unsigned DestBits = Log2_64(CmpVal);
+      if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
+        SDValue Conv =
+            DAG.getSExtOrTrunc(DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
+                                                  MVT::getIntegerVT(DestBits)),
+                               DL, OpVT);
+        return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+      }
+    }
+  }
+
   return DAGCombineTruncBoolExt(N, DCI);
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index 13c629b6349450c..ce75b77eed29666 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -89,6 +89,48 @@ entry:
   ret i1 %cmp.i5
 }
 
+define zeroext i1 @test5(i64 %a) {
+; CHECK-LABEL: test5:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsw 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -2147483648
+  %cmp = icmp ult i64 %0, -4294967296
+  ret i1 %cmp
+}
+
+define zeroext i1 @test6(i64 %a) {
+; CHECK-LABEL: test6:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsh 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -32768
+  %cmp = icmp ult i64 %0, -65536
+  ret i1 %cmp
+}
+
+define zeroext i1 @test7(i64 %a) {
+; CHECK-LABEL: test7:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsb 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -128
+  %cmp = icmp ult i64 %0, -256
+  ret i1 %cmp
+}
+
 !1 = !{!2, !2, i64 0}
 !2 = !{!"int", !3, i64 0}
 !3 = !{!"omnipotent char", !4, i64 0}

>From fbb7e6362d6223f8e0ee6014e000c1cc5ae6e777 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 6 Sep 2023 16:16:34 +0800
Subject: [PATCH 2/4] [PowerPC] Combine sub within setcc back to sext

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 37 +++++++++++++-----
 llvm/test/CodeGen/PowerPC/setcc-to-sub.ll   | 42 +++++++++++++++++++++
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f4e3531980d165f..4659ebef35ecf62 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14407,15 +14407,18 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N,
       ShiftCst);
 }
 
-SDValue PPCTargetLowering::combineSetCC(SDNode *N,
-                                        DAGCombinerInfo &DCI) const {
-  assert(N->getOpcode() == ISD::SETCC &&
-         "Should be called with a SETCC node");
+SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
+  assert(N->getOpcode() == ISD::SETCC && "Should be called with a SETCC node");
 
   ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
+  SDLoc DL(N);
+  SelectionDAG &DAG = DCI.DAG;
+  EVT VT = N->getValueType(0);
+  EVT OpVT = LHS.getValueType();
+
   if (CC == ISD::SETNE || CC == ISD::SETEQ) {
-    SDValue LHS = N->getOperand(0);
-    SDValue RHS = N->getOperand(1);
 
     // If there is a '0 - y' pattern, canonicalize the pattern to the RHS.
     if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) &&
@@ -14426,15 +14429,29 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N,
     // x != 0-y --> x+y != 0
     if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) &&
         RHS.hasOneUse()) {
-      SDLoc DL(N);
-      SelectionDAG &DAG = DCI.DAG;
-      EVT VT = N->getValueType(0);
-      EVT OpVT = LHS.getValueType();
       SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1));
       return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
     }
   }
 
+  // Combine (a-2^(M-1)) => sext(trunc(a, M), 64)
+  if (CC == ISD::SETULT && LHS.getOpcode() == ISD::ADD && OpVT == MVT::i64 &&
+      isa<ConstantSDNode>(RHS) && isa<ConstantSDNode>(LHS.getOperand(1))) {
+    uint64_t ShiftVal =
+        ~(cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue()) + 1;
+    uint64_t CmpVal = ~(cast<ConstantSDNode>(RHS)->getZExtValue()) + 1;
+    if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
+      unsigned DestBits = Log2_64(CmpVal);
+      if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
+        SDValue Conv =
+            DAG.getSExtOrTrunc(DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
+                                                  MVT::getIntegerVT(DestBits)),
+                               DL, OpVT);
+        return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+      }
+    }
+  }
+
   return DAGCombineTruncBoolExt(N, DCI);
 }
 
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index 13c629b6349450c..ce75b77eed29666 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -89,6 +89,48 @@ entry:
   ret i1 %cmp.i5
 }
 
+define zeroext i1 @test5(i64 %a) {
+; CHECK-LABEL: test5:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsw 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -2147483648
+  %cmp = icmp ult i64 %0, -4294967296
+  ret i1 %cmp
+}
+
+define zeroext i1 @test6(i64 %a) {
+; CHECK-LABEL: test6:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsh 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -32768
+  %cmp = icmp ult i64 %0, -65536
+  ret i1 %cmp
+}
+
+define zeroext i1 @test7(i64 %a) {
+; CHECK-LABEL: test7:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    extsb 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    addic 4, 3, -1
+; CHECK-NEXT:    subfe 3, 4, 3
+; CHECK-NEXT:    blr
+entry:
+  %0 = add i64 %a, -128
+  %cmp = icmp ult i64 %0, -256
+  ret i1 %cmp
+}
+
 !1 = !{!2, !2, i64 0}
 !2 = !{!"int", !3, i64 0}
 !3 = !{!"omnipotent char", !4, i64 0}

>From 7483e99e84cad30105f294caf8e7d556b89d3ac9 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Tue, 21 Nov 2023 13:57:39 +0800
Subject: [PATCH 3/4] Support i16 to i32 case

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 52 +++++++++++++++------
 llvm/test/CodeGen/PowerPC/setcc-to-sub.ll   | 23 ++++-----
 2 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 6cac37d5b940039..d46396ae6b25dc5 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14436,20 +14436,44 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
     }
   }
 
-  // Combine (a-2^(M-1)) => sext(trunc(a, M), 64)
-  if (CC == ISD::SETULT && LHS.getOpcode() == ISD::ADD && OpVT == MVT::i64 &&
-      isa<ConstantSDNode>(RHS) && isa<ConstantSDNode>(LHS.getOperand(1))) {
-    uint64_t ShiftVal =
-        ~(cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue()) + 1;
-    uint64_t CmpVal = ~(cast<ConstantSDNode>(RHS)->getZExtValue()) + 1;
-    if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
-      unsigned DestBits = Log2_64(CmpVal);
-      if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
-        SDValue Conv =
-            DAG.getSExtOrTrunc(DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
-                                                  MVT::getIntegerVT(DestBits)),
-                               DL, OpVT);
-        return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+  if (CC == ISD::SETULT && isa<ConstantSDNode>(RHS)) {
+    uint64_t RHSVal = cast<ConstantSDNode>(RHS)->getZExtValue();
+    if (LHS.getOpcode() == ISD::ADD && isa<ConstantSDNode>(LHS.getOperand(1))) {
+      uint64_t Addend = cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue();
+      if (OpVT == MVT::i64) {
+        // (a-2^(M-1)) => sext(trunc(a, M), 64)
+        uint64_t ShiftVal = ~Addend + 1;
+        uint64_t CmpVal = ~RHSVal + 1;
+        if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
+          unsigned DestBits = Log2_64(CmpVal);
+          if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
+            SDValue Conv = DAG.getSExtOrTrunc(
+                DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
+                                   MVT::getIntegerVT(DestBits)),
+                DL, OpVT);
+            return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+          }
+        }
+      } else if (OpVT == MVT::i32) {
+        if (RHSVal == 0xffffff00 && Addend == 0xffffff80) {
+          SDValue Conv = DAG.getSExtOrTrunc(
+              DAG.getSExtOrTrunc(LHS.getOperand(0), DL, MVT::i8), DL, OpVT);
+          return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+        }
+      }
+    } else if (LHS.getOpcode() == ISD::SRL &&
+               LHS.getOperand(0).getOpcode() == ISD::ADD &&
+               isa<ConstantSDNode>(LHS.getOperand(1)) &&
+               isa<ConstantSDNode>(LHS.getOperand(0).getOperand(1))) {
+      if (RHSVal == 65535 &&
+          cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 16 &&
+          cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1))
+                  ->getZExtValue() == 0xffff8000) {
+        SDValue Conv = DAG.getSExtOrTrunc(
+            DAG.getSExtOrTrunc(LHS.getOperand(0).getOperand(0), DL, MVT::i16),
+            DL, OpVT);
+        return DAG.getSetCC(DL, VT, LHS.getOperand(0).getOperand(0), Conv,
+                            ISD::SETNE);
       }
     }
   }
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index a48458527191c51..1e4d2db2509b257 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -134,12 +134,11 @@ entry:
 define zeroext i1 @test8(i32 %a) {
 ; CHECK-LABEL: test8:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    addi 3, 3, -32768
-; CHECK-NEXT:    lis 4, -1
-; CHECK-NEXT:    rlwinm 3, 3, 16, 16, 31
-; CHECK-NEXT:    ori 4, 4, 1
-; CHECK-NEXT:    add 3, 3, 4
-; CHECK-NEXT:    rldicl 3, 3, 1, 63
+; CHECK-NEXT:    extsh 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    cntlzw 3, 3
+; CHECK-NEXT:    srwi 3, 3, 5
+; CHECK-NEXT:    xori 3, 3, 1
 ; CHECK-NEXT:    blr
 entry:
   %0 = add i32 %a, -32768
@@ -150,13 +149,11 @@ entry:
 define zeroext i1 @test9(i32 %a) {
 ; CHECK-LABEL: test9:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    lis 4, -256
-; CHECK-NEXT:    addi 3, 3, -128
-; CHECK-NEXT:    ori 4, 4, 1
-; CHECK-NEXT:    clrldi 3, 3, 32
-; CHECK-NEXT:    rldic 4, 4, 8, 0
-; CHECK-NEXT:    add 3, 3, 4
-; CHECK-NEXT:    rldicl 3, 3, 1, 63
+; CHECK-NEXT:    extsb 4, 3
+; CHECK-NEXT:    xor 3, 3, 4
+; CHECK-NEXT:    cntlzw 3, 3
+; CHECK-NEXT:    srwi 3, 3, 5
+; CHECK-NEXT:    xori 3, 3, 1
 ; CHECK-NEXT:    blr
 entry:
   %0 = add i32 %a, -128

>From 9bb57d9c55c6625fbe51e7ea3c3464083c1bf4ab Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Thu, 30 Nov 2023 10:11:39 +0800
Subject: [PATCH 4/4] Use hex

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 05e940548ff46a0..a15786e31bc12cc 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14441,7 +14441,6 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
     if (LHS.getOpcode() == ISD::ADD && isa<ConstantSDNode>(LHS.getOperand(1))) {
       uint64_t Addend = cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue();
       if (OpVT == MVT::i64) {
-        // (a-2^(M-1)) => sext(trunc(a, M), 64)
         uint64_t ShiftVal = ~Addend + 1;
         uint64_t CmpVal = ~RHSVal + 1;
         if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
@@ -14465,7 +14464,7 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
                LHS.getOperand(0).getOpcode() == ISD::ADD &&
                isa<ConstantSDNode>(LHS.getOperand(1)) &&
                isa<ConstantSDNode>(LHS.getOperand(0).getOperand(1))) {
-      if (RHSVal == 65535 &&
+      if (RHSVal == 0xffff &&
           cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 16 &&
           cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1))
                   ->getZExtValue() == 0xffff8000) {



More information about the cfe-commits mailing list