[llvm] [DAGCombiner] Reassociate chains of vector reductions (PR #206471)

Pengcheng Wang via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 1 04:55:40 PDT 2026


================
@@ -1401,6 +1401,44 @@ SDValue DAGCombiner::reassociateReduction(unsigned RedOpc, unsigned Opc,
     SDValue Op2 = DAG.getNode(Opc, DL, VT, B, D);
     return DAG.getNode(Opc, DL, VT, Red, Op2);
   }
+
+  // Reassociate a reduction chain so two reductions become adjacent and the
+  // folds above can merge them:
+  //   op(vecreduce(X), op(vecreduce(Y), Z))
+  //     -> op(vecreduce(op(X, Y)), Z)
+  // Applied to fixpoint by the combiner worklist, this collapses an
+  // arbitrarily long chain of reductions (such as the left-leaning chain SLP
+  // emits) into a single reduction.
+  auto FoldReductionChain = [&](SDValue Red0, SDValue Chain) -> SDValue {
+    SDValue X, Y, Z, RedX, RedY;
+    if (!sd_match(Red0, m_AllOf(m_OneUse(m_UnaryOp(RedOpc, m_Value(X))),
+                                m_Value(RedX))) ||
+        !sd_match(Chain, m_OneUse(m_c_BinOp(
+                             Opc,
+                             m_AllOf(m_OneUse(m_UnaryOp(RedOpc, m_Value(Y))),
+                                     m_Value(RedY)),
+                             m_Value(Z)))) ||
+        sd_match(Z, m_UnaryOp(RedOpc, m_Value())) ||
+        X.getValueType() != Y.getValueType() ||
----------------
wangpc-pp wrote:

TBH I don't know, I just copied it from above code. But accroding to the comments in `llvm/include/llvm/CodeGen/ISDOpcodes.h`:
```cpp
  /// Integer reductions may have a result type larger than the vector element
  /// type. However, the reduction is performed using the vector element type
  /// and the value in the top bits is unspecified.
  VECREDUCE_ADD,
```
So a single `VECREDUCE_ADD` can be extending: e.g. `i32 = vecreduce_add <8 x i16>` — it sums the i16 lanes but the result i32's top bits are unspecified.

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


More information about the llvm-commits mailing list