diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-10-15 19:38:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2024-10-15 19:38:46 +0200 |
commit | 4366f0c7e296ea0d7279343c9b0a1d597588a1da (patch) | |
tree | 513b036d7c93f53bb88594d046e2eabf5d0f2b1d | |
parent | 8161c4adea7f1842f9d28633d82e912ebb7a4cf9 (diff) | |
download | gcc-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.pd | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr116891.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/fma-pr116891.c | 19 |
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 (); +} |