[gcc r17-3224] doc: describe the lane freedom of reduc_widen_[us]sum and WIDEN_SUM_EXPR

Kyrylo Tkachov via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:eaca0fdd031bbed1d2ff7dd86c3adfecef1c51cc

commit r17-3224-geaca0fdd031bbed1d2ff7dd86c3adfecef1c51cc
Author: Kyrylo Tkachov <[email protected]>
Date:   Wed Aug 5 14:58:44 2026 +0200

    doc: describe the lane freedom of reduc_widen_[us]sum and WIDEN_SUM_EXPR
    
    The documentation of the reduc_widen_ssum and reduc_widen_usum patterns says
    only that operand 1 is added to operand 2, which reads as though each element
    of operand 1 has to be accumulated into the element of operand 0 at the same
    position.  Nothing says the patterns are only ever used for a reassociable
    reduction, so a port cannot tell whether it is allowed to regroup the input
    elements, for example by using a pairwise widening add.
    
    vect_recog_widen_sum_pattern only forms WIDEN_SUM_EXPR
    through vect_reassociating_reduction_p, which requires the statement to be a
    reduction, refuses a statement nested in the inner loop of an outer-loop
    vectorization because the order of the computation matters there, and refuses
    a type that needs a fold-left reduction.  The comment on the pattern already
    describes the idiom as producing N/2 results by summing up pairs of
    intermediate results.  The accumulator is only ever consumed by a horizontal
    sum in the epilogue, so the distribution of input elements over accumulator
    elements is not observable.
    
    Spell that out in md.texi, along with the constraint that comes with it: an
    implementation that adds elements together before they reach the element width
    of operand 0 has to widen them first so that no intermediate sum can overflow.
    Note that the widen_[us]sum names are left free for a lane preserving pattern.
    
    Give WIDEN_SUM_EXPR the same statement in tree.def.  DOT_PROD_EXPR and SAD_EXPR
    are formed through vect_reassociating_reduction_p as well and read the same way,
    so add a sentence to each pointing at the WIDEN_SUM_EXPR rule.
    
    gcc/ChangeLog:
    
            * doc/md.texi (reduc_widen_ssum@var{n}@var{m}3)
            (reduc_widen_usum@var{n}@var{m}3): Document that the assignment of
            input elements to accumulator elements is unconstrained, that
            intermediate sums must not overflow, and that the widen_[us]sum
            names are reserved.  Fix a typo.
            * tree.def (WIDEN_SUM_EXPR): Document that the assignment of elements
            of the first argument to elements of the second is unconstrained.
            (DOT_PROD_EXPR, SAD_EXPR): Note the same freedom.
    
    Signed-off-by: Kyrylo Tkachov <[email protected]>

Diff:
---
 gcc/doc/md.texi | 23 +++++++++++++++++++++--
 gcc/tree.def    | 19 +++++++++++++++++--
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 4b3dc950aeb0..f86fa8038e8a 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -5097,10 +5097,29 @@ in operand 0, which is of the same mode as operand 3.
 @itemx @samp{reduc_widen_usum@var{n}@var{m}3}
 Operands 0 and 2 are of the same mode, which is wider than the mode of
 operand 1. Add operand 1 to operand 2 and place the widened result in
-operand 0. (This is used express accumulation of elements into an accumulator
-of a wider mode.)
+operand 0. (This is used to express accumulation of elements into an
+accumulator of a wider mode.)
 @var{m} is the mode of operand 1 and @var{n} is the mode of operand 0.
 
+These patterns are only used for a reduction whose summation the vectorizer
+has already established may be reassociated.  Operand 0 is the accumulator
+of that reduction and is itself reduced to a scalar by a horizontal sum once
+the loop is done, so which element of the accumulator a given input element
+ends up in is not observable.  An implementation is therefore free to choose
+which elements of operand 1 it accumulates into which element of operand 0,
+provided that every element of operand 1 is accumulated exactly once.  In
+particular it may add adjacent elements of operand 1 to each other before
+accumulating them, which is what a pairwise widening add instruction does.
+
+The intermediate sums must not overflow.  An implementation that combines
+elements of operand 1 with each other before they reach the element width of
+operand 0 therefore has to widen them first.
+
+The names @samp{widen_ssum@var{n}@var{m}3} and
+@samp{widen_usum@var{n}@var{m}3} are deliberately left free for a future
+lane preserving pattern, which would have to add element @var{i} of
+operand 1 to element @var{i} of operand 2 for every @var{i}.
+
 @mdindex smulhs@var{m}3
 @mdindex umulhs@var{m}3
 @item @samp{smulhs@var{m}3}
diff --git a/gcc/tree.def b/gcc/tree.def
index ad8e676e9421..2e767dbe0453 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1465,7 +1465,10 @@ DEFTREECODE (TRANSACTION_EXPR, "transaction_expr", tcc_expression, 1)
    	arg3 = PLUS_EXPR (tmp, arg3);
    or:
 	tmp = WIDEN_MULT_EXPR(arg1, arg2);
-        arg3 = WIDEN_SUM_EXPR (tmp, arg3);		 */
+        arg3 = WIDEN_SUM_EXPR (tmp, arg3);
+   Like WIDEN_SUM_EXPR, this code is only created for a reduction whose
+   summation may be reassociated, so which products are added into which
+   element of arg3 is not observable.  */
 DEFTREECODE (DOT_PROD_EXPR, "dot_prod_expr", tcc_expression, 3)
 
 /* Widening summation.
@@ -1474,7 +1477,16 @@ DEFTREECODE (DOT_PROD_EXPR, "dot_prod_expr", tcc_expression, 3)
    the size of t1. The type of the entire expression is also t2.
    WIDEN_SUM_EXPR is equivalent to first widening (promoting)
    the first argument from type t1 to type t2, and then summing it
-   with the second argument.  */
+   with the second argument.
+
+   This code is only created for a reduction whose summation the vectorizer
+   has established may be reassociated, and the result is reduced to a scalar
+   by a horizontal sum once the loop is done.  Which element of the second
+   argument a given element of the first argument is added to is therefore
+   not observable, and an expander may choose that assignment freely, so long
+   as every element of the first argument is accumulated exactly once and no
+   intermediate sum overflows.  See the reduc_widen_ssum and reduc_widen_usum
+   patterns in md.texi.  */
 DEFTREECODE (WIDEN_SUM_EXPR, "widen_sum_expr", tcc_binary, 2)
 
 /* Widening sad (sum of absolute differences).
@@ -1490,6 +1502,9 @@ DEFTREECODE (WIDEN_SUM_EXPR, "widen_sum_expr", tcc_binary, 2)
        tmp = IFN_VEC_WIDEN_MINUS_EXPR (arg1, arg2)
        tmp2 = ABS_EXPR (tmp)
        arg3 = WIDEN_SUM_EXPR (tmp2, arg3)
+   Like WIDEN_SUM_EXPR, this code is only created for a reduction whose
+   summation may be reassociated, so which absolute differences are added
+   into which element of arg3 is not observable.
  */
 DEFTREECODE (SAD_EXPR, "sad_expr", tcc_expression, 3)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.