diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c567aa8717..b58b92ad114 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-09-09 Barnaby Wilks + + * match.pd: Add flag_unsafe_math_optimizations check + before deciding on the widest type in a binary math operation. + 2019-09-09 Martin Liska * config/i386/i386.opt: Update comment of removed diff --git a/gcc/match.pd b/gcc/match.pd index 1d13543a615..5b2d95dfa9d 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 ec2872b97df..6129f911f31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-09 Barnaby Wilks + + * gcc.dg/fold-binary-math-casts.c: New test. + 2019-09-09 Jakub Jelinek 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 00000000000..53c247fa143 --- /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 + +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" } } */