[llvm] [SLP]Keep originals when uniques do not reduce register uses (PR #218294)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 25 11:56:05 PDT 2026


================
@@ -10981,8 +10981,60 @@ static bool tryToFindDuplicates(SmallVectorImpl<Value *> &VL,
                                          /*Extract=*/false, CostKind,
                                          AreAllValuesNonConst, UniqueValues);
     UniquesCost += ReusesCost;
-    if (UniquesCost <= InsertsCost)
+    if (UniquesCost <= InsertsCost) {
+      // Packing to a vector that occupies the same register width as the
+      // original only adds the reshuffle cost; keep the originals. Loads may
+      // instead benefit from a wider contiguous load.
+      if (S && S.getOpcode() != Instruction::Load) {
+        unsigned EltBits =
+            S.getMainOp()->getDataLayout().getTypeSizeInBits(ScalarTy);
+        unsigned MinVF = R.getMinVF(EltBits);
+        auto RegWidth = [&](unsigned N) {
+          return std::max(getFullVectorNumberOfElements(TTI, ScalarTy, N),
+                          MinVF);
+        };
+        // Keeping the originals just moves the reshuffle to the operand
+        // columns with duplicates; keep them only if at most one operand
+        // column has duplicates, so the total number of reshuffles does not
+        // grow.
+        auto HasExtraReshuffle = [&]() {
+          if (BuildGatherOnly)
+            return false;
+          unsigned NumDupColumns = 0;
+          for (unsigned OpIdx :
+               seq<unsigned>(S.getMainOp()->getNumOperands())) {
+            unsigned NumOps = 0, NumUniqueOps = 0;
+            SmallPtrSet<const Value *, 16> UniqueOps;
+            for (Value *V : VL) {
+              if (isa<PoisonValue>(V))
+                continue;
+              Value *Op;
+              if (S.isCopyableElement(V)) {
+                if (OpIdx != 0)
+                  continue;
+                Op = V;
+              } else {
+                auto *I = dyn_cast<Instruction>(V);
+                if (!I || OpIdx >= I->getNumOperands())
+                  continue;
+                Op = I->getOperand(OpIdx);
+              }
+              ++NumOps;
+              if (isConstant(Op) || UniqueOps.insert(Op).second)
+                ++NumUniqueOps;
+            }
+            NumDupColumns += NumUniqueOps < NumOps;
----------------
bababuck wrote:

Nit: early exit
```suggestion
              if (isConstant(Op) || UniqueOps.insert(Op).second) {
                ++NumDupColumns;
                break;
              }
            }
```

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


More information about the llvm-commits mailing list