From a6edd18cb32993213508aaa4879af7485c1bbaac Mon Sep 17 00:00:00 2001
From: Barnaby Wilks <barnaby.wilks@arm.com>
Date: Mon, 9 Sep 2019 12:05:36 +0000
Subject: [PATCH] match.pd: Add flag_unsafe_math_optimizations check before
 deciding on the widest type in...

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.

	* gcc.dg/fold-binary-math-casts.c: New test.

From-SVN: r275518
---
 gcc/ChangeLog                                 |  5 ++
 gcc/match.pd                                  | 12 +++-
 gcc/testsuite/ChangeLog                       |  4 ++
 gcc/testsuite/gcc.dg/fold-binary-math-casts.c | 58 +++++++++++++++++++
 4 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/fold-binary-math-casts.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6c567aa8717e..b58b92ad1145 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 1d13543a6159..5b2d95dfa9d8 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 ec2872b97df9..6129f911f31e 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 000000000000..53c247fa1436
--- /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" } } */
-- 
GitLab