[llvm] [RISCV] Lower SELECT's with one constant more efficiently using Zicond (PR #143581)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 10 13:08:46 PDT 2025


================
@@ -9073,19 +9078,36 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
         }
       }
 
-      const int TrueValCost = RISCVMatInt::getIntMatCost(
-          TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
-      const int FalseValCost = RISCVMatInt::getIntMatCost(
-          FalseVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
-      bool IsCZERO_NEZ = TrueValCost <= FalseValCost;
-      SDValue LHSVal = DAG.getConstant(
-          IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal, DL, VT);
-      SDValue RHSVal =
-          DAG.getConstant(IsCZERO_NEZ ? TrueVal : FalseVal, DL, VT);
-      SDValue CMOV =
-          DAG.getNode(IsCZERO_NEZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ,
-                      DL, VT, LHSVal, CondV);
-      return DAG.getNode(ISD::ADD, DL, VT, CMOV, RHSVal);
+      bool IsCZERO_NEZ;
+      SDValue ConstVal, SubOp;
+      if (BothAreConstant) {
+        const APInt &TrueVal = TrueV->getAsAPIntVal();
+        const APInt &FalseVal = FalseV->getAsAPIntVal();
+        const int TrueValCost = RISCVMatInt::getIntMatCost(
+            TrueVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
+        const int FalseValCost = RISCVMatInt::getIntMatCost(
+            FalseVal, Subtarget.getXLen(), Subtarget, /*CompressionCost=*/true);
+        IsCZERO_NEZ = TrueValCost <= FalseValCost;
+
+        SubOp = DAG.getConstant(
+            IsCZERO_NEZ ? FalseVal - TrueVal : TrueVal - FalseVal, DL, VT);
+        ConstVal = DAG.getConstant(IsCZERO_NEZ ? TrueVal : FalseVal, DL, VT);
+      } else {
+        IsCZERO_NEZ = isa<ConstantSDNode>(TrueV);
+        ConstVal = IsCZERO_NEZ ? TrueV : FalseV;
+
+        SDValue &RegV = IsCZERO_NEZ ? FalseV : TrueV;
+        SubOp = DAG.getNode(ISD::SUB, DL, VT, RegV, ConstVal);
+      }
+      // The one constant case is only efficient is the constant fits into
+      // `ADDI`
+      if (BothAreConstant ||
+          isInt<12>(dyn_cast<ConstantSDNode>(ConstVal)->getSExtValue())) {
----------------
bababuck wrote:

Good catch.

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


More information about the llvm-commits mailing list