aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-10-15 19:38:46 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2024-10-15 19:38:46 +0200
commit4366f0c7e296ea0d7279343c9b0a1d597588a1da (patch)
tree513b036d7c93f53bb88594d046e2eabf5d0f2b1d
parent8161c4adea7f1842f9d28633d82e912ebb7a4cf9 (diff)
downloadgcc-4366f0c7e296ea0d7279343c9b0a1d597588a1da.zip
gcc-4366f0c7e296ea0d7279343c9b0a1d597588a1da.tar.gz
gcc-4366f0c7e296ea0d7279343c9b0a1d597588a1da.tar.bz2
match.pd: Further fma negation fixes [PR116891]
On Mon, Oct 14, 2024 at 08:53:29AM +0200, Jakub Jelinek wrote: > > PR middle-end/116891 > > * match.pd ((negate (IFN_FNMS@3 @0 @1 @2)) -> (IFN_FMA @0 @1 @2)): > > Only enable for !HONOR_SIGN_DEPENDENT_ROUNDING. > > Guess it would be nice to have a testcase which FAILs without the patch and > PASSes with it, but it can be added later. I've added such a testcase now, and additionally found the fix only fixed one of the 4 problematic similar cases. Here is a patch which fixes the others too and adds the testcases. fma-pr116891.c FAILed without your patch, FAILs with your patch too (but only due to the bar/baz/qux checks) and PASSes with the patch. 2024-10-15 Jakub Jelinek <jakub@redhat.com> PR middle-end/116891 * match.pd ((negate (fmas@3 @0 @1 @2)) -> (IFN_FNMS @0 @1 @2)): Only enable for !HONOR_SIGN_DEPENDENT_ROUNDING. ((negate (IFN_FMS@3 @0 @1 @2)) -> (IFN_FNMA @0 @1 @2)): Likewise. ((negate (IFN_FNMA@3 @0 @1 @2)) -> (IFN_FMS @0 @1 @2)): Likewise. * gcc.dg/pr116891.c: New test. * gcc.target/i386/fma-pr116891.c: New test.
-rw-r--r--gcc/match.pd6
-rw-r--r--gcc/testsuite/gcc.dg/pr116891.c47
-rw-r--r--gcc/testsuite/gcc.target/i386/fma-pr116891.c19
3 files changed, 69 insertions, 3 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 22fad1a..12d81fc 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -9441,7 +9441,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(IFN_FNMS @0 @1 @2))
(simplify
(negate (fmas@3 @0 @1 @2))
- (if (single_use (@3))
+ (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
(IFN_FNMS @0 @1 @2))))
(simplify
@@ -9455,7 +9455,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(IFN_FNMA @0 @1 @2))
(simplify
(negate (IFN_FMS@3 @0 @1 @2))
- (if (single_use (@3))
+ (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
(IFN_FNMA @0 @1 @2)))
(simplify
@@ -9469,7 +9469,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(IFN_FMS @0 @1 @2))
(simplify
(negate (IFN_FNMA@3 @0 @1 @2))
- (if (single_use (@3))
+ (if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
(IFN_FMS @0 @1 @2)))
(simplify
diff --git a/gcc/testsuite/gcc.dg/pr116891.c b/gcc/testsuite/gcc.dg/pr116891.c
new file mode 100644
index 0000000..446e5ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr116891.c
@@ -0,0 +1,47 @@
+/* PR middle-end/116891 */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-require-effective-target c99_runtime } */
+/* { dg-options "-O2 -frounding-math" } */
+
+#include <fenv.h>
+
+__attribute__((noipa)) double
+foo (double x, double y, double z)
+{
+ return -__builtin_fma (-x, y, -z);
+}
+
+__attribute__((noipa)) double
+bar (double x, double y, double z)
+{
+ return -__builtin_fma (-x, y, z);
+}
+
+__attribute__((noipa)) double
+baz (double x, double y, double z)
+{
+ return -__builtin_fma (x, y, -z);
+}
+
+__attribute__((noipa)) double
+qux (double x, double y, double z)
+{
+ return -__builtin_fma (x, y, z);
+}
+
+int
+main ()
+{
+#if defined (FE_DOWNWARD) && __DBL_MANT_DIG__ == 53 && __DBL_MAX_EXP__ == 1024
+ fesetround (FE_DOWNWARD);
+ double a = foo (-0x1.p256, 0x1.p256, 0x1.p-256);
+ if (a != -__builtin_nextafter (0x1p256 * 0x1p256, 0.))
+ __builtin_abort ();
+ if (a != bar (-0x1.p256, 0x1.p256, -0x1.p-256)
+ || a != baz (0x1.p256, 0x1.p256, 0x1.p-256)
+ || a != qux (0x1.p256, 0x1.p256, -0x1.p-256))
+ __builtin_abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.target/i386/fma-pr116891.c b/gcc/testsuite/gcc.target/i386/fma-pr116891.c
new file mode 100644
index 0000000..34689f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/fma-pr116891.c
@@ -0,0 +1,19 @@
+/* PR middle-end/116891 */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-require-effective-target c99_runtime } */
+/* { dg-require-effective-target fma } */
+/* { dg-options "-O2 -mfma -frounding-math" } */
+
+#include <fenv.h>
+#include "fma-check.h"
+
+#define main() do_main ()
+#include "../../gcc.dg/pr116891.c"
+
+static void
+fma_test (void)
+{
+ do_main ();
+}