diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c567aa8717ee34e29d42ab9b7d9d87eac24d63b..b58b92ad114524f61f71be10032c4bbd2fce03a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Barnaby Wilks <barnaby.wilks@arm.com> + + * match.pd: Add flag_unsafe_math_optimizations check + before deciding on the widest type in a binary math operation. + 2019-09-09 Martin Liska <mliska@suse.cz> * config/i386/i386.opt: Update comment of removed diff --git a/gcc/match.pd b/gcc/match.pd index 1d13543a6159dc94ce1ff1112c0bfc6b0d588638..5b2d95dfa9d8feef7e7248c0364909fc061da3ab 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -5040,10 +5040,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && newtype == type && types_match (newtype, type)) (op (convert:newtype @1) (convert:newtype @2)) - (with { if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) + (with + { + if (!flag_unsafe_math_optimizations) + { + if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype)) newtype = ty1; + if (TYPE_PRECISION (ty2) > TYPE_PRECISION (newtype)) - newtype = ty2; } + newtype = ty2; + } + } + /* Sometimes this transformation is safe (cannot change results through affecting double rounding cases) and sometimes it is not. If NEWTYPE is diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec2872b97df9708d5b7301cc1f83bc4655cd93ca..6129f911f31e8e180988a01ee9e799829d2e920e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-09 Barnaby Wilks <barnaby.wilks@arm.com> + + * gcc.dg/fold-binary-math-casts.c: New test. + 2019-09-09 Jakub Jelinek <jakub@redhat.com> PR target/87853 diff --git a/gcc/testsuite/gcc.dg/fold-binary-math-casts.c b/gcc/testsuite/gcc.dg/fold-binary-math-casts.c new file mode 100644 index 0000000000000000000000000000000000000000..53c247fa14360c9e5719b432aa213f899caa2d25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-binary-math-casts.c @@ -0,0 +1,58 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fdump-tree-optimized" } */ + +#include <math.h> + +float +f (float x, float y) +{ + double z = 1.0 / x; + return z * y; +} + +float +g (float x, float y) +{ + double a = 1.0 / x; + double b = 1.0 / y; + long double k = x*x*x*x*x*x; + + return a + b - k; +} + +float +h (float x) +{ + double a = x * 2.0; + double b = a / 3.5f; + return a + b; +} + +float +i (float y, float z) +{ + return pow (y, 2.0) / (double) (y + z); +} + +float +j (float x, float y) +{ + double t = 4.0 * x; + double z = t + y; + return z; +} + +float +k (float a) +{ + return 1.0 / sqrtf (a); +} + +float +l (float a) +{ + return (double) a * (a / 2.0); +} + +/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */