[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)