[gcc r17-2945] middle-end: fix condition on multiple negate pattern [PR126602]
Tamar Christina via Gcc-cvs <[email protected]> Tue, 4 Aug 2026 14:24:29 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:fdfe1570235b1bddc4572255ff161b5dc25cc460 commit r17-2945-gfdfe1570235b1bddc4572255ff161b5dc25cc460 Author: Tamar Christina <[email protected]> Date: Tue Aug 4 15:23:23 2026 +0100 middle-end: fix condition on multiple negate pattern [PR126602] The optimization added in r17-527-gca2920882be has a bogus constraint which allows floating point FMAs through and folds them into integer ones. i.e. we produce Matching expression match.pd:159, gimple-match-10.cc:33 Matching expression match.pd:159, gimple-match-10.cc:33 Applying pattern match.pd:10328, gimple-match-5.cc:8685 gimple_simplified to _15 = (vector(8) unsigned int) a_6; _16 = (vector(8) unsigned int) _13; _17 = (vector(8) unsigned int) _1; _18 = .FNMA (_15, _16, _17); _3 = (svfloat32_t __attribute__((arm_sve_vector_bits(256)))) _18; Generated FMA _3 = (svfloat32_t __attribute__((arm_sve_vector_bits(256)))) _18; Which ICEs because the SVE attributes don't match. This fixes the guard where I think the intention was for this to only apply to Integral types. gcc/ChangeLog: PR tree-optimization/126602 * match.pd: Fix constraints. gcc/testsuite/ChangeLog: PR tree-optimization/126602 * gcc.target/aarch64/sve/pr126602.c: New test. Diff: --- gcc/match.pd | 12 +++++------ gcc/testsuite/gcc.target/aarch64/sve/pr126602.c | 28 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 293650760e27..623be4b1b805 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -10319,12 +10319,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (fmas:c (nop_convert (negate @0)) @1 @2) (with { tree t = TREE_TYPE (@0); } - (if ((!ANY_INTEGRAL_TYPE_P (type) - || TYPE_UNSIGNED (type) - || !TYPE_OVERFLOW_SANITIZED (type)) - && (!ANY_INTEGRAL_TYPE_P (t) - || TYPE_UNSIGNED (t) - || !TYPE_OVERFLOW_SANITIZED (type))) + (if ((ANY_INTEGRAL_TYPE_P (type) + && (TYPE_UNSIGNED (type) + || !TYPE_OVERFLOW_SANITIZED (type)) + && ANY_INTEGRAL_TYPE_P (t) + && (TYPE_UNSIGNED (t) + || !TYPE_OVERFLOW_SANITIZED (t)))) /* Move the negation into FNMA only when signed overflow is unobservable for both the outer operation and the inner negate. */ (with { tree utype = unsigned_type_for (type); } diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr126602.c b/gcc/testsuite/gcc.target/aarch64/sve/pr126602.c new file mode 100644 index 000000000000..3b9378cebb14 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr126602.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv9-a -msve-vector-bits=256" } */ + +#include <arm_sve.h> +typedef svfloat32_t sv8f __attribute__((arm_sve_vector_bits(256))); +typedef float v8f __attribute__((vector_size(32))); + +/* c - (sv8f)(a * b), multiply in the GNU vector type. */ +void p (v8f *pa, v8f *pb, sv8f *pc) +{ + v8f a = *pa, b = *pb; + v8f m = a * b; + *pc = *pc - (sv8f)m; +} + +/* Mirrored: multiply in the SVE type, addend a GNU vector. */ +void q (sv8f *pa, sv8f *pb, v8f *pc) +{ + sv8f m = *pa * *pb; + *pc = *pc - (v8f)m; +} + +/* Explicit negate of a multiplicand. */ +void r (v8f *pa, v8f *pb, sv8f *pc) +{ + v8f m = (-*pa) * *pb; + *pc = *pc + (sv8f)m; +}