[llvm] [DAGCombine][RISCV] fold select_cc seteq (and x, 1) 0, 0, -1 -> neg(and(x, 1)) (PR #152062)

via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 4 18:56:54 PDT 2025


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

>From 7f4fc5f95e7537d8963370f813df0d0bd4775393 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 4 Aug 2025 18:57:47 -0400
Subject: [PATCH 1/2] fold select_cc seteq (and x, 1) 0, 0, -1 -> neg(and(x,
 1))

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 11 +++++++++++
 llvm/test/CodeGen/RISCV/pr148084.ll           | 16 +++++++---------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index c008135854621..15a58d94857ed 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -28963,6 +28963,17 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
   if (SDValue V = foldSelectCCToShiftAnd(DL, N0, N1, N2, N3, CC))
     return V;
 
+  // fold select_cc seteq (and x, 1) 0, 0, -1 -> neg(and(x, 1))
+  if (CC == ISD::SETEQ && N0->getOpcode() == ISD::AND &&
+      N0->getValueType(0) == VT && isNullConstant(N1) &&
+      isAllOnesConstant(N2) && isOneConstant(N0->getOperand(1))) {
+    SDValue AndLHS = N0->getOperand(0);
+    // Shift the tested bit over the sign bit.
+    SDValue Neg =
+        DAG.getNode(ISD::AND, DL, VT, AndLHS, DAG.getConstant(1, DL, VT));
+    return DAG.getNegative(Neg, DL, VT);
+  }
+
   // fold (select_cc seteq (and x, y), 0, 0, A) -> (and (sra (shl x)) A)
   // where y is has a single bit set.
   // A plaintext description would be, we can turn the SELECT_CC into an AND
diff --git a/llvm/test/CodeGen/RISCV/pr148084.ll b/llvm/test/CodeGen/RISCV/pr148084.ll
index 9fa26c74021cb..83626e1757dea 100644
--- a/llvm/test/CodeGen/RISCV/pr148084.ll
+++ b/llvm/test/CodeGen/RISCV/pr148084.ll
@@ -10,15 +10,14 @@ define fastcc void @search_tx_type() #0 {
 ; CHECK:       # %bb.0: # %._crit_edge.i
 ; CHECK-NEXT:  # %bb.1: # %bb
 ; CHECK-NEXT:    lbu a1, 0(zero)
-; CHECK-NEXT:    lw a0, 0(zero)
 ; CHECK-NEXT:    lh a2, 0(zero)
+; CHECK-NEXT:    lw a0, 0(zero)
 ; CHECK-NEXT:    seqz a1, a1
-; CHECK-NEXT:    srai a3, a0, 63
 ; CHECK-NEXT:    addi a1, a1, -1
 ; CHECK-NEXT:    and a1, a1, a2
-; CHECK-NEXT:    andi a2, a1, 1
-; CHECK-NEXT:    addi a2, a2, -1
-; CHECK-NEXT:    or a3, a3, a0
+; CHECK-NEXT:    slli a2, a1, 63
+; CHECK-NEXT:    srai a2, a2, 63
+; CHECK-NEXT:    srai a3, a0, 63
 ; CHECK-NEXT:    or a2, a2, a3
 ; CHECK-NEXT:    bgez a2, .LBB0_3
 ; CHECK-NEXT:  # %bb.2:
@@ -36,14 +35,13 @@ define fastcc void @search_tx_type() #0 {
 ; CHECK-NEXT:  # %bb.6: # %bb
 ; CHECK-NEXT:    mv a3, a2
 ; CHECK-NEXT:  .LBB0_7: # %bb
-; CHECK-NEXT:    andi a5, a1, 8
-; CHECK-NEXT:    sext.w a4, a3
+; CHECK-NEXT:    andi a4, a1, 8
 ; CHECK-NEXT:    mv a2, a3
-; CHECK-NEXT:    beqz a5, .LBB0_9
+; CHECK-NEXT:    beqz a4, .LBB0_9
 ; CHECK-NEXT:  # %bb.8: # %bb
 ; CHECK-NEXT:    mv a2, a0
 ; CHECK-NEXT:  .LBB0_9: # %bb
-; CHECK-NEXT:    blt a4, a0, .LBB0_11
+; CHECK-NEXT:    blt a3, a0, .LBB0_11
 ; CHECK-NEXT:  # %bb.10: # %bb
 ; CHECK-NEXT:    mv a2, a3
 ; CHECK-NEXT:  .LBB0_11: # %bb

>From 4e7c3a6fc16aba8e809a090f96856794ef0153f9 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Mon, 4 Aug 2025 21:56:42 -0400
Subject: [PATCH 2/2] Update DAGCombiner.cpp

---
 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 15a58d94857ed..2d5599914ef85 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -28963,7 +28963,7 @@ SDValue DAGCombiner::SimplifySelectCC(const SDLoc &DL, SDValue N0, SDValue N1,
   if (SDValue V = foldSelectCCToShiftAnd(DL, N0, N1, N2, N3, CC))
     return V;
 
-  // fold select_cc seteq (and x, 1) 0, 0, -1 -> neg(and(x, 1))
+  // fold select_cc seteq (and x, 1), 0, 0, -1 -> neg(and(x, 1))
   if (CC == ISD::SETEQ && N0->getOpcode() == ISD::AND &&
       N0->getValueType(0) == VT && isNullConstant(N1) &&
       isAllOnesConstant(N2) && isOneConstant(N0->getOperand(1))) {



More information about the llvm-commits mailing list