[patch]middle-end: fix condition on multiple negate pattern [PR126602]
Tamar Christina <[email protected]> Tue, 4 Aug 2026 10:42:56 +0100
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
--MbT4gfHKB4WRUn+F
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
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?
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..9c821575793fa51095c15d0cde68e636138383ad 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))
+ (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)))
+ || !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;
+}
--
--MbT4gfHKB4WRUn+F
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment; filename="rb20766.patch"
diff --git a/gcc/match.pd b/gcc/match.pd
index f6ecee41509e360e430da5e0339f998c069495ba..9c821575793fa51095c15d0cde68e636138383ad 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))
+ (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)))
+ || !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;
+}
--MbT4gfHKB4WRUn+F--