[llvm] [RISCV] Combine (ADDI (ADDI X, C1), C2) -> (ADDI X, C1+C2) (PR #157416)

Piotr Fusik via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 8 03:12:32 PDT 2025


https://github.com/pfusik created https://github.com/llvm/llvm-project/pull/157416

None

>From 0e6f1ad93ea4ab3bc583db2b329c16f20bf47227 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Mon, 8 Sep 2025 12:11:47 +0200
Subject: [PATCH] [RISCV] Combine (ADDI (ADDI X, C1), C2) -> (ADDI X, C1+C2)

---
 .../CodeGen/SelectionDAG/SelectionDAGBuilder.cpp |  2 +-
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp      | 16 +++++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 430e47451fd49..56e273c8d6e81 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4019,7 +4019,7 @@ void SelectionDAGBuilder::visitBitCast(const User &I) {
   // constant integer as an opaque constant.
   else if(ConstantInt *C = dyn_cast<ConstantInt>(I.getOperand(0)))
     setValue(&I, DAG.getConstant(C->getValue(), dl, DestVT, /*isTarget=*/false,
-                                 /*isOpaque*/true));
+                                 /*isOpaque*/false));
   else
     setValue(&I, N);            // noop cast.
 }
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3ab08f990c289..7d77535fbfb42 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -9421,7 +9421,17 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
       // Efficient only if the constant and its negation fit into `ADDI`
       // Prefer Add/Sub over Xor since can be compressed for small immediates
       if (isInt<12>(RawConstVal)) {
-        SDValue SubOp = DAG.getNode(ISD::SUB, DL, VT, RegV, ConstVal);
+        SDValue SubOp;
+        using namespace llvm::SDPatternMatch;
+        SDValue ShAmt;
+        if (sd_match(RegV, m_OneUse(m_Not(m_OneUse(m_Shl(m_AllOnes(), m_Value(ShAmt))))))) {
+          SDValue One = DAG.getConstant(1, DL, VT);
+          SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, One, ShAmt);
+          SDValue SubAmt = DAG.getConstant(1 + RawConstVal, DL, VT);
+          SubOp = DAG.getNode(ISD::SUB, DL, VT, Shl, SubAmt);
+        } else {
+          SubOp = DAG.getNode(ISD::SUB, DL, VT, RegV, ConstVal);
+        }
         SDValue CMOV =
             DAG.getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
                         DL, VT, SubOp, CondV);
@@ -16257,8 +16267,8 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
     SDValue Op0 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N0.getOperand(0));
     SDValue Op1 = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, N0.getOperand(1));
     SDValue Shl = DAG.getNode(ISD::SHL, DL, MVT::i64, Op0, Op1);
-    SDValue And = DAG.getNOT(DL, Shl, MVT::i64);
-    return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, And);
+    SDValue Not = DAG.getNOT(DL, Shl, MVT::i64);
+    return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Not);
   }
 
   // fold (xor (sllw 1, x), -1) -> (rolw ~1, x)



More information about the llvm-commits mailing list