[llvm] [RISCV] Rewrite ADD to SUB to reuse a materialized negated constant (PR #221027)

Pengcheng Wang via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 3 21:56:47 PDT 2026


================
@@ -128,6 +128,42 @@ void RISCVDAGToDAGISel::PreprocessISelDAG() {
                                TrueMask, VLMAX);
       break;
     }
+    case ISD::ADD: {
+      // Turn (add X, C) into (sub X, -C) when a constant node holding -C
+      // already exists in the DAG, so both share one materialization. Do this
+      // before selection, while both are still ConstantSDNodes: by selection
+      // time -C may already have been selected into instructions.
+      auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+      if (!N1C)
+        break;
+      MVT VT = N->getSimpleValueType(0);
+      if (VT != Subtarget->getXLenVT())
+        break;
+      int64_t Imm = N1C->getSExtValue();
+      // Small constants are a single instruction, and -INT64_MIN == INT64_MIN.
+      if (isInt<32>(Imm) || Imm == INT64_MIN)
+        break;
+      // Reusing a register is free, so require only that -C is no more
+      // expensive to materialize than C.
+      int OrigCost = RISCVMatInt::getIntMatCost(APInt(64, Imm), 64, *Subtarget,
+                                                /*CompressionCost=*/true);
+      int NegCost = RISCVMatInt::getIntMatCost(APInt(64, -Imm), 64, *Subtarget,
+                                               /*CompressionCost=*/true);
+      if (NegCost > OrigCost)
+        break;
+      // Only rewrite when -C already exists, else this just moves the cost.
+      bool HasNegConst = any_of(CurDAG->allnodes(), [&](const SDNode &Node) {
+        auto *C = dyn_cast<ConstantSDNode>(&Node);
+        return C && C->getSimpleValueType(0) == VT && C->getSExtValue() == -Imm;
+      });
+      if (!HasNegConst)
+        break;
+      SDLoc DL(N);
+      // getConstant uniques onto the existing -C node, so it is shared.
+      Result = CurDAG->getNode(ISD::SUB, DL, VT, N->getOperand(0),
----------------
wangpc-pp wrote:

https://github.com/llvm/llvm-project/pull/221027/commits/0de89c9e36e4f48adbb5bdde436d514c811628ee

https://github.com/llvm/llvm-project/pull/221027


More information about the llvm-commits mailing list