[llvm] [RISCV] custom scmp(x, 0) and scmp(0, x) lowering for RVV (PR #151753)

Olaf Bernstein via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 1 13:17:17 PDT 2025


================
@@ -8223,6 +8225,35 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
   case ISD::SADDSAT:
   case ISD::SSUBSAT:
     return lowerToScalableOp(Op, DAG);
+  case ISD::SCMP: {
+    SDLoc DL(Op);
+    EVT VT = Op->getValueType(0);
+    SDValue LHS = DAG.getFreeze(Op->getOperand(0));
+    SDValue RHS = DAG.getFreeze(Op->getOperand(1));
+    unsigned SEW = VT.getScalarSizeInBits();
+
+    SDValue Shift = DAG.getConstant(SEW-1, DL, VT);
+    SDValue Zero = DAG.getConstant(0, DL, VT);
+    SDValue One = DAG.getConstant(1, DL, VT);
+    SDValue MinusOne = DAG.getAllOnesConstant(DL, VT);
+
+    if (ISD::isConstantSplatVectorAllZeros(RHS.getNode())) {
+      SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, LHS, Shift);
+      if (SEW <= 32) {
+        // scmp(lhs, 0) -> vor.vv(vsra.vi(lhs,SEW-1), vmin.vx(lhs,1))
+        SDValue Min = DAG.getNode(ISD::SMIN, DL, VT, LHS, One);
+        return DAG.getNode(ISD::OR, DL, VT, Sra, Min);
+      }
+      // scmp(lhs, 0) -> vmerge.vi(vmsgt.vi(rhs,0), vsra.vx(lhs,SEW-1), 1)
+      return DAG.getSelectCC(DL, LHS, Zero, Sra, One, ISD::SETGT);
+    } else if (ISD::isConstantSplatVectorAllZeros(LHS.getNode())) {
+      // scmp(0, rhs) -> vmerge.vi(vmsgt.vi(rhs,0), vsrl.vi/vx(rhs,SEW-1), -1)
+      SDValue Srl = DAG.getNode(ISD::SRL, DL, VT, RHS, Shift);
+      return DAG.getSelectCC(DL, RHS, Zero, Srl, MinusOne, ISD::SETGT);
----------------
camel-cdr wrote:

Ok, I tried:
```c
SDValue Setcc = DAG.getSetCC(DL, VT, LHS, Zero, ISD::SETGT);
return DAG.getSelect(DL, VT, Setcc, Sra, One);
```
but that didn't seem to work:
```
LLVM ERROR: Cannot select: t19: nxv2i64 = vselect t18, t16, t22
  t18: nxv2i64 = setcc t2, t24, setgt:ch
    t2: nxv2i64,ch = CopyFromReg t0, Register:nxv2i64 %0
    t24: nxv2i64 = RISCVISD::VMV_V_X_VL undef:nxv2i64, Constant:i64<0>, Register:i64 $x0
  t16: nxv2i64 = sra t2, t23
    t2: nxv2i64,ch = CopyFromReg t0, Register:nxv2i64 %0
    t23: nxv2i64 = RISCVISD::VMV_V_X_VL undef:nxv2i64, Constant:i64<63>, Register:i64 $x0
  t22: nxv2i64 = RISCVISD::VMV_V_X_VL undef:nxv2i64, Constant:i64<1>, Register:i64 $x0
In function: scmp_i64z64
```
I also tried using ISD::VSELECT instead of getSelect, but that didn't work either not sure what else I can do.


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


More information about the llvm-commits mailing list