[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