[llvm] [SLP] Gather operands of associative binary chains into one node (PR #208514)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 28 11:52:20 PDT 2026


================
@@ -12655,6 +12970,48 @@ void BoUpSLP::buildTreeRec(ArrayRef<Value *> VLRef, unsigned Depth,
   }
   InstructionsCompatibilityAnalysis Analysis(*DT, *DL, *TTI, *TLI);
   SmallVector<ValueList> Operands = Analysis.buildOperands(S, VL);
+  // Flatten associative binary chains into operand columns. Only the peeled
+  // chain links are required to be single-use (they are erased); the root
+  // being flattened may have other uses. Skip alt-shuffle, copyable, and
+  // non-associative nodes. Restricted to BinaryOperator: isAssociative() is
+  // also true for associative intrinsics (e.g. smax/smin/umax/umin), which are
+  // CallInst, not BinaryOperator, and are not supported by the
+  // copyable-identity machinery used below (ConstantExpr::getBinOpIdentity,
+  // isSupportedOpcode).
+  SmallVector<Value *> ReassocScalars;
+  // Cached below (when the peel is kept) so the reorder step further down
+  // does not need to redo the aligning/scoring work.
+  SmallVector<ValueList> ReassocAlignedOperands;
+  std::tuple<unsigned, unsigned, unsigned, int> ReassocPeeledQuality;
+  if (VectorizeReassociatedOps && !S.isAltShuffle() &&
+      !S.areInstructionsWithCopyableElements() && Operands.size() == 2 &&
+      all_of(VL, [](Value *V) {
+        auto *I = dyn_cast<BinaryOperator>(V);
+        return I && I->isAssociative();
+      })) {
+    SmallVector<ValueList> NaturalTwoColumns(Operands);
+    scanAssociativeOperands(S, *DT, *DL, *TTI, *TLI, *this, Operands,
----------------
bababuck wrote:

 `Operands` as used here are not re-associated already, so might misbehave for unbalanced associative chains.

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


More information about the llvm-commits mailing list