Kyrylo Tkachov <[email protected]> writes:
>> On 28 Aug 2026, at 11:41, Richard Sandiford
>> <[email protected]> wrote:
>> 
>> Richard Sandiford <[email protected]> writes:
>>> <[email protected]> writes:
>>>> From: Kyrylo Tkachov <[email protected]>
>>>> 
>>>> REDUC_MAX, REDUC_MIN, REDUC_AND and REDUC_IOR are idempotent.  A
>>>> reduction of a nonempty duplicate vector with one of these operations is
>>>> the duplicated element:
>>>> 
>>>>  v = [vec_duplicate_expr] x;
>>>>  res = .REDUC_MAX (v);
>>>> 
>>>> becomes:
>>>> 
>>>>  res = x;
>>>> 
>>>> For example, the new SVE test contains:
>>>> 
>>>>  int __GIMPLE ()
>>>>  reduc_max (int x)
>>>>  {
>>>>    svint32_t v;
>>>>    int res;
>>>> 
>>>>    v = svdup_s32 (x);
>>>>    res = .REDUC_MAX (v);
>>>>    return res;
>>>>  }
>>>> 
>>>> With -O2 -fgimple -march=armv8.2-a+sve, the code changes from:
>>>> 
>>>>  reduc_max:
>>>>          mov     z31.s, w0
>>>>          ptrue   p7.b, all
>>>>          smaxv   s31, p7, z31.s
>>>>          fmov    w0, s31
>>>>          ret
>>>> 
>>>> to:
>>>> 
>>>>  reduc_max:
>>>>          ret
>>>> 
>>>> An XOR reduction of a duplicate vector is zero when the number of lanes
>>>> is even.  GCC permits variable-length vectors whose lane count has
>>>> unknown parity, such as [1, 1].  Fold REDUC_XOR only when multiple_p
>>>> proves that every possible lane count has the required parity.
>>>> 
>>>> Use the same two paths as IFN_VEC_EXTRACT and IFN_VEC_SHL_INSERT.  Match
>>>> a nonconstant VEC_DUPLICATE_EXPR directly in match.pd.  Handle a
>>>> VECTOR_CST in fold_const_reduction.
>>>> 
>>>> Start constant folding with the explicitly encoded elements for both
>>>> fixed-length and variable-length vectors.  A non-stepped encoding can be
>>>> used for an idempotent reduction when every encoded element is guaranteed
>>>> to be present.  For XOR, require the remaining encoded copies to cancel
>>>> in pairs.  Process two periods of a duplicate encoding, or the foreground
>>>> and background of a two-element-per-pattern encoding.  Use the exact
>>>> element count as a fallback when it is known.
>>>> 
>>>> Keep REDUC_MAX and REDUC_MIN when a shortened reduction could return a
>>>> signaling NaN directly.  The full reduction can quiet the NaN and raise an
>>>> invalid-operation exception.
>>>> 
>>>> These folds also let the constant reduction in the PR 127039 rule
>>>> simplify for scalable constants.  The scalar result cannot match the
>>>> inverse reduction-pair rule, so the nontermination cycle stays blocked.
>>>> 
>>>> Bootstrapped and tested on aarch64-none-linunx-gnu.
>>>> Ok for trunk?
>>>> Thanks,
>>>> Kyrill
>>>> 
>>>> gcc/ChangeLog:
>>>> 
>>>> PR tree-optimization/127039
>>>> * fold-const-call.cc (fold_const_reduction): Fold non-stepped constants
>>>> when the available lane-count information determines the result.
>>>> * match.pd (reduction of a vector duplicate): New simplifications to
>>>> the duplicated element or zero.
>>>> 
>>>> gcc/testsuite/ChangeLog:
>>>> 
>>>> PR tree-optimization/127039
>>>> * gcc.target/aarch64/sve/vec-reduc-dup-1.c: New test.
>>>> * gcc.target/aarch64/sve/vec-reduc-pattern-1.c: New test.
>>>> * gcc.target/aarch64/sve/vec-reduc-snan-1.c: New test.
>>>> * gcc.target/aarch64/sve/vec-reduc-uniform-1.c: New test.
>>>> * gcc.target/riscv/rvv/base/reduc-xor-uniform-1.c: New test.
>>>> 
>>>> Signed-off-by: Kyrylo Tkachov <[email protected]>
>>>> ---
>>>> gcc/fold-const-call.cc                        |  36 +++-
>>>> gcc/match.pd                                  |  14 ++
>>>> .../gcc.target/aarch64/sve/vec-reduc-dup-1.c  |  63 +++++++
>>>> .../aarch64/sve/vec-reduc-pattern-1.c         | 156 ++++++++++++++++++
>>>> .../gcc.target/aarch64/sve/vec-reduc-snan-1.c |  65 ++++++++
>>>> .../aarch64/sve/vec-reduc-uniform-1.c         |  71 ++++++++
>>>> .../riscv/rvv/base/reduc-xor-uniform-1.c      |  47 ++++++
>>>> 7 files changed, 449 insertions(+), 3 deletions(-)
>>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/vec-reduc-dup-1.c
>>>> create mode 100644 
>>>> gcc/testsuite/gcc.target/aarch64/sve/vec-reduc-pattern-1.c
>>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/vec-reduc-snan-1.c
>>>> create mode 100644 
>>>> gcc/testsuite/gcc.target/aarch64/sve/vec-reduc-uniform-1.c
>>>> create mode 100644 
>>>> gcc/testsuite/gcc.target/riscv/rvv/base/reduc-xor-uniform-1.c
>>>> 
>>>> diff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc
>>>> index c483b80e704..342a65f4217 100644
>>>> --- a/gcc/fold-const-call.cc
>>>> +++ b/gcc/fold-const-call.cc
>>>> @@ -622,9 +622,39 @@ fold_const_builtin_nan (tree type, tree arg, bool 
>>>> quiet)
>>>> static tree
>>>> fold_const_reduction (tree type, tree arg, tree_code code)
>>>> {
>>>> -  unsigned HOST_WIDE_INT nelts;
>>>> -  if (TREE_CODE (arg) != VECTOR_CST
>>>> -      || !VECTOR_CST_NELTS (arg).is_constant (&nelts))
>>>> +  if (TREE_CODE (arg) != VECTOR_CST)
>>>> +    return NULL_TREE;
>>>> +
>>>> +  bool idempotent_p = (code == MAX_EXPR
>>>> +        || code == MIN_EXPR
>>>> +        || code == BIT_AND_EXPR
>>>> +        || code == BIT_IOR_EXPR);
>>>> +
>>>> +  unsigned HOST_WIDE_INT nelts = vector_cst_encoded_nelts (arg);
>>>> +  bool singleton_snan_p
>>>> +    = (nelts == 1
>>>> + && tree_expr_maybe_signaling_nan_p (VECTOR_CST_ELT (arg, 0)));
>>>> +
>>>> +  if (idempotent_p
>>>> +      && !VECTOR_CST_STEPPED_P (arg)
>>>> +      && multiple_p (VECTOR_CST_NELTS (arg), nelts)
>>>> +      && !singleton_snan_p)
>>> 
>>> I don't understand why the singleton_snan_p exception is needed.
>>> Doesn't that imply that we mishandle that situation below?
>>> 
>>> The condition seems to mean that a 128-bit SVE vector will be handled
>>> differently for -msve-vector-bits=128 and -msve-vector-bits=scalable,
>>> despite the behaviour being the same at runtime.
>> 
>> Sorry, I get it now.  Doubling nelts to force an operation would
>> unnecessarily penalise folds of known single-element vectors,
>> which really don't raise an exception.
>> 
>
> Yeah, that’s the idea.
>
>> So yeah, I suppose this is probably the best way to handle it.
>> 
>
> Thanks, can I take this as an ok for the patch?

Yeah, ok for the fold-const-call.cc part from my POV.

Thanks,
Richard

Reply via email to