Re: [patch v2]middle-end: fix condition on multiple negate pattern [PR126602]

Richard Biener <[email protected]> Tue, 4 Aug 2026 15:57:48 +0200 (CEST)
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On Tue, 4 Aug 2026, Tamar Christina wrote:

> 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.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and no issues.
> 
> Ok for master?

OK.

> Thanks,
> Tamar
> 
> 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 --git a/gcc/match.pd b/gcc/match.pd
> index f6ecee41509e360e430da5e0339f998c069495ba..0bb0c754d3279f6dcdd63755424b63f7aa022459 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -10305,12 +10305,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 0000000000000000000000000000000000000000..3b9378cebb14530443b2503a04634aeee2d2e901
> --- /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;
> +}
> 
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)