[llvm] [SLP] Extend compare chains downward before bottom-up vectorization (PR #210921)

Balakrishna Bandlapalli via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 17 23:19:00 PDT 2026


================
@@ -32394,6 +32399,61 @@ static bool compareCmp(Value *V, Value *V2, TargetLibraryInfo &TLI,
   return IsCompatibility;
 }
 
+bool SLPVectorizerPass::tryToVectorizeListDownwards(ArrayRef<Value *> VL,
+                                                    BoUpSLP &R, unsigned Depth,
+                                                    bool MaxVFOnly) {
+  if (VL.size() <= 1)
+    return false;
+  if (Depth > RecursionMaxDepth)
+    return false;
+  // Collect the single, in-block, isomorphic user of each value. If every
+  // value has such a user, the users form a list one level closer to the sinks
+  // that we can try to reroot the tree at.
+  SmallVector<Value *, 8> UseVL;
+  Instruction *ReprInst = nullptr;
+  for (Value *V : VL) {
+    if (!V->hasOneUse())
+      break;
+    auto *I = dyn_cast<Instruction>(*V->user_begin());
+    if (!I)
+      break;
+    if (I->isTerminator() || isa<CallInst>(I))
+      break;
+    if (isa<InsertElementInst, InsertValueInst, ExtractValueInst,
+            ExtractElementInst>(I))
+      break;
+    if (!ReprInst)
+      ReprInst = I;
+    else if (I->getParent() != ReprInst->getParent())
+      break;
+    if (ReprInst->getOpcode() != I->getOpcode() ||
+        ReprInst->getType() != I->getType())
+      break;
+    UseVL.push_back(I);
+  }
+  // Try the deepest reachable list first: rerooting further down subsumes the
+  // current list as operands of a larger tree.
+  if (UseVL.size() == VL.size() &&
+      tryToVectorizeListDownwards(UseVL, R, Depth + 1, MaxVFOnly))
+    return true;
+  // insertvalue/insertelement bundles can share a result type while their
+  // inserted-value operands differ in type, which would feed buildTree a
+  // mixed-type operand bundle. They are handled by vectorizeInserts, not here.
+  if (isa<InsertElementInst, InsertValueInst, ExtractValueInst,
+          ExtractElementInst>(VL[0]))
+    return false;
+  // The downward use-chain collection above only matches opcodes, so the list
+  // may mix element types. buildTree asserts that a bundle is all-constant or
+  // all-same-type, so guard against mixed-type lists here.
+  if ((allConstant(VL) || allSameType(VL)) &&
+      tryToVectorizeList(VL, R, MaxVFOnly)) {
----------------
amd-bbandlap wrote:

Understood. 
I will follow the original bottom-up approach building the graphs directly during the traversal for single-use instructions and restricting special compare handling to compares with external uses.

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


More information about the llvm-commits mailing list