[llvm] [AArch64] Optimized rdsvl followed by constant mul (PR #162853)

Kerry McLaughlin via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 21 03:48:09 PDT 2025


================
@@ -19579,6 +19579,47 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
        if (ConstValue.sge(1) && ConstValue.sle(16))
          return SDValue();
 
+  // Multiplying an RDSVL value by a constant can sometimes be done cheaper by
+  // folding a power-of-two factor of the constant into the RDSVL immediate and
+  // compensating with an extra shift.
+  //
+  // We rewrite:
+  //   (mul (srl (rdsvl 1), 3), x)
+  // to one of:
+  //   (shl (rdsvl y),  z)   if z > 0
+  //   (srl (rdsvl y), abs(z))   if z < 0
+  // where integers y, z satisfy   x = y * 2^(3 + z)   and   y ∈ [-32, 31].
+  if ((N0->getOpcode() == ISD::SRL) &&
+      (N0->getOperand(0).getOpcode() == AArch64ISD::RDSVL)) {
+    unsigned AbsConstValue = ConstValue.abs().getZExtValue();
+
+    // z ≤ ctz(|x|) - 3  (largest extra shift we can take while keeping y
+    // integral)
+    int UpperBound = llvm::countr_zero(AbsConstValue) - 3;
----------------
kmclaughlin-arm wrote:

I think the 3 here is coming from the assumption that the RDSVL & shift have come from expanding a `cntsd` intrinsic. If that is the case, should we make sure the shift value is 3 as expected?

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


More information about the llvm-commits mailing list