[llvm] [RISCV] Sink vp.splat operands of VP intrinsic. (PR #133245)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 11 18:32:53 PDT 2025


================
@@ -2823,41 +2823,55 @@ bool RISCVTTIImpl::isProfitableToSinkOperands(
   if (!ST->sinkSplatOperands())
     return false;
 
-  for (auto OpIdx : enumerate(I->operands())) {
-    if (!canSplatOperand(I, OpIdx.index()))
-      continue;
+  // Capture EVL value.
+  Value *EVL = nullptr;
+  if (auto *VPI = dyn_cast<VPIntrinsic>(I))
+    EVL = VPI->getVectorLengthParam();
 
-    Instruction *Op = dyn_cast<Instruction>(OpIdx.value().get());
+  for (auto &U : I->operands()) {
+    auto *Op = dyn_cast<Instruction>(U.get());
     // Make sure we are not already sinking this operand
     if (!Op || any_of(Ops, [&](Use *U) { return U->get() == Op; }))
       continue;
 
-    // We are looking for a splat that can be sunk.
-    if (!match(Op, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_ZeroInt()),
+    // We are looking for a splat/vp.splat that can be sunk.
+    bool IsVPSplat =
+        EVL && match(Op, m_Intrinsic<Intrinsic::experimental_vp_splat>(
+                             m_Value(), m_AllOnes(), m_Specific(EVL)));
+    if (!IsVPSplat &&
+        !match(Op, m_Shuffle(m_InsertElt(m_Undef(), m_Value(), m_ZeroInt()),
                              m_Undef(), m_ZeroMask())))
       continue;
 
     // Don't sink i1 splats.
     if (cast<VectorType>(Op->getType())->getElementType()->isIntegerTy(1))
       continue;
 
-    // All uses of the shuffle should be sunk to avoid duplicating it across gpr
-    // and vector registers
-    for (Use &U : Op->uses()) {
-      Instruction *Insn = cast<Instruction>(U.getUser());
-      if (!canSplatOperand(Insn, U.getOperandNo()))
-        return false;
+    // All uses of the splat/vp.splat should be sunk to avoid duplicating it
+    // across gpr and vector registers
+    if (all_of(Op->uses(), [&](Use &U) {
+          Instruction *Insn = cast<Instruction>(U.getUser());
+          if (!canSplatOperand(Insn, U.getOperandNo()))
+            return false;
+          if (IsVPSplat) {
+            auto *VPI = dyn_cast<VPIntrinsic>(U.getUser());
+            return VPI && VPI->getVectorLengthParam() == EVL;
+          }
+          return true;
+        })) {
----------------
lukel97 wrote:

Is it possible to keep the previous for loop with the early exit? I think that was easier to read

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


More information about the llvm-commits mailing list