[llvm] [PowerPC] Extend select_cc lhs, 0, 1, 0, cc optimization to PowerPC 64 (PR #206281)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 10:51:27 PDT 2026


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/206281

>From b4d0382394f56e78fd323e9e39ce6d9e705f719f Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 27 Jun 2026 15:31:33 -0400
Subject: [PATCH 1/2] [PowerPC] Extend select_cc lhs, 0, 1, 0, cc optimization
 to PowerPC 64

---
 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp   | 28 +++++++++++--------
 llvm/test/CodeGen/PowerPC/ppc-crbits-onoff.ll | 13 +++------
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 016c547821f7a..5baa76664ac12 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -5891,17 +5891,23 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
       }
     }
 
-    // Handle the setcc cases here.  select_cc lhs, 0, 1, 0, cc
-    if (!isPPC64 && isNullConstant(N->getOperand(1)) &&
-        isOneConstant(N->getOperand(2)) && isNullConstant(N->getOperand(3)) &&
-        CC == ISD::SETNE &&
-        // FIXME: Implement this optzn for PPC64.
-        N->getValueType(0) == MVT::i32) {
-      SDNode *Tmp =
-          CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
-                                 N->getOperand(0), getI32Imm(~0U, dl));
-      CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDValue(Tmp, 0),
-                           N->getOperand(0), SDValue(Tmp, 1));
+    // Handle the setcc cases here.  select_cc lhs, 0, 1, 0, setne
+    // Compute (lhs != 0) as: addic tmp, lhs, -1; subfe res, tmp, lhs
+    if (isNullConstant(N->getOperand(1)) && isOneConstant(N->getOperand(2)) &&
+        isNullConstant(N->getOperand(3)) && CC == ISD::SETNE &&
+        N->getOperand(0).getValueType() == N->getValueType(0) &&
+        (N->getValueType(0) == MVT::i32 ||
+         (isPPC64 && N->getValueType(0) == MVT::i64))) {
+      bool Is64Bit = N->getValueType(0) == MVT::i64;
+      unsigned AddicOpc = Is64Bit ? PPC::ADDIC8 : PPC::ADDIC;
+      unsigned SubfeOpc = Is64Bit ? PPC::SUBFE8 : PPC::SUBFE;
+      MVT VT = Is64Bit ? MVT::i64 : MVT::i32;
+      SDValue ImmOp = Is64Bit ? getI64Imm(~0ULL, dl) : getI32Imm(~0U, dl);
+
+      SDNode *Tmp = CurDAG->getMachineNode(AddicOpc, dl, VT, MVT::Glue,
+                                           N->getOperand(0), ImmOp);
+      CurDAG->SelectNodeTo(N, SubfeOpc, VT, SDValue(Tmp, 0), N->getOperand(0),
+                           SDValue(Tmp, 1));
       return;
     }
 
diff --git a/llvm/test/CodeGen/PowerPC/ppc-crbits-onoff.ll b/llvm/test/CodeGen/PowerPC/ppc-crbits-onoff.ll
index 49a5687afe4c8..74424f2fc63e6 100644
--- a/llvm/test/CodeGen/PowerPC/ppc-crbits-onoff.ll
+++ b/llvm/test/CodeGen/PowerPC/ppc-crbits-onoff.ll
@@ -9,22 +9,17 @@ define signext i32 @crbitsoff(i32 signext %v1, i32 signext %v2) #0 {
 ; CHECK-LABEL: crbitsoff:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    cntlzw 4, 4
-; CHECK-NEXT:    cmplwi 3, 0
-; CHECK-NEXT:    li 3, 1
-; CHECK-NEXT:    iseleq 3, 0, 3
+; CHECK-NEXT:    addic 5, 3, -1
+; CHECK-NEXT:    subfe 3, 5, 3
 ; CHECK-NEXT:    rlwinm 4, 4, 27, 5, 31
 ; CHECK-NEXT:    and 3, 3, 4
 ; CHECK-NEXT:    blr
 ;
 ; CHECK-NO-ISEL-LABEL: crbitsoff:
 ; CHECK-NO-ISEL:       # %bb.0: # %entry
-; CHECK-NO-ISEL-NEXT:    cmplwi 3, 0
-; CHECK-NO-ISEL-NEXT:    li 3, 1
-; CHECK-NO-ISEL-NEXT:    bne 0, .LBB0_2
-; CHECK-NO-ISEL-NEXT:  # %bb.1: # %entry
-; CHECK-NO-ISEL-NEXT:    li 3, 0
-; CHECK-NO-ISEL-NEXT:  .LBB0_2: # %entry
 ; CHECK-NO-ISEL-NEXT:    cntlzw 4, 4
+; CHECK-NO-ISEL-NEXT:    addic 5, 3, -1
+; CHECK-NO-ISEL-NEXT:    subfe 3, 5, 3
 ; CHECK-NO-ISEL-NEXT:    rlwinm 4, 4, 27, 5, 31
 ; CHECK-NO-ISEL-NEXT:    and 3, 3, 4
 ; CHECK-NO-ISEL-NEXT:    blr

>From 66861074526c4701709fb9c11f69ac5e48d7d025 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 29 Jun 2026 13:25:04 -0400
Subject: [PATCH 2/2] Prevent bug with 32 bit types on 64 bit machines

---
 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index 5baa76664ac12..4cdd0d9cbba33 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -5896,7 +5896,7 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
     if (isNullConstant(N->getOperand(1)) && isOneConstant(N->getOperand(2)) &&
         isNullConstant(N->getOperand(3)) && CC == ISD::SETNE &&
         N->getOperand(0).getValueType() == N->getValueType(0) &&
-        (N->getValueType(0) == MVT::i32 ||
+        ((!isPPC64 && N->getValueType(0) == MVT::i32) ||
          (isPPC64 && N->getValueType(0) == MVT::i64))) {
       bool Is64Bit = N->getValueType(0) == MVT::i64;
       unsigned AddicOpc = Is64Bit ? PPC::ADDIC8 : PPC::ADDIC;



More information about the llvm-commits mailing list