This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PR/23948 and PR/24123 (recip problems)



From Uros Bizjak's experiments, it turns out it is more effective to do the optimization only if there are three consecutive divides. I think this should be target-specific, and a param provides a way to avoid magic numbers in the source code.

And some the tests obviously need 2 as the minimum value, or they won't pass.


Paolo
2005-10-12  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/23948
	PR tree-optimization/24123

	* gcc.dg/tree-ssa/recip-3.c, gcc.dg/tree-ssa/recip-4.c,
	gcc.dg/tree-ssa/recip-5.c, gcc.dg/tree-ssa/recip-6.c,
	gcc.dg/tree-ssa/recip-7.c, gcc.dg/tree-ssa/pr23109.c,
	g++.dg/tree-ssa/pr23948.C: New testcases.
	* gcc.dg/tree-ssa/pr23234.c: Add --param min-divides-for-recip-mul=2.

Index: testsuite/g++.dg/tree-ssa/pr23948.C
===================================================================
RCS file: testsuite/g++.dg/tree-ssa/pr23948.C
diff -N testsuite/g++.dg/tree-ssa/pr23948.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/tree-ssa/pr23948.C	12 Oct 2005 10:59:27 -0000
@@ -0,0 +1,18 @@
+/* { dg-options "-O1 -ffast-math -fdump-tree-recip --param min-divides-for-recip-mul=2" } */
+/* { dg-do compile } */
+
+struct MIOFILE {
+  ~MIOFILE();
+};
+double potentially_runnable_resource_share();
+void f1(double);
+int make_scheduler_request(double a)
+{
+  MIOFILE mf;
+  double prrs = potentially_runnable_resource_share();
+  f1(a/prrs);
+  f1(1/prrs);
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
Index: testsuite/gcc.dg/tree-ssa/pr23109.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/pr23109.c
diff -N testsuite/gcc.dg/tree-ssa/pr23109.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/pr23109.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funsafe-math-optimizations -fdump-tree-recip" } */
+
+double F[2] = { 0., 0. }, e = 0.;
+
+int main()
+{
+	int i;
+	double E, W, P, d;
+
+        /* make sure the program crashes on FP exception */
+        unsigned short int Mask;
+
+	W = 1.;
+	d = 2.*e;
+	E = 1. - d;
+
+	for( i=0; i < 2; i++ )
+		if( d > 0.01 )
+		{
+			P = ( W < E ) ? (W - E)/d : (E - W)/d;
+			F[i] += P;
+		}
+
+	return 0;
+}
+
+/* LIM only performs the transformation in the no-trapping-math case.  In
+   the future we will do it for trapping-math as well in recip, check that
+   this is not wrongly optimized.  */
+/* { dg-final { scan-tree-dump-not "reciptmp" "lim" } } */
+/* { dg-final { scan-tree-dump-not "reciptmp" "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+
Index: testsuite/gcc.dg/tree-ssa/pr23234.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c,v
retrieving revision 1.1
diff -p -u -u -r1.1 pr23234.c
--- testsuite/gcc.dg/tree-ssa/pr23234.c	9 Aug 2005 03:28:38 -0000	1.1
+++ testsuite/gcc.dg/tree-ssa/pr23234.c	12 Oct 2005 10:59:28 -0000
@@ -1,7 +1,7 @@
 /* The problem in this PR was mostly finding a suitable place to insert
    the reciprocals of the function arguments.  This test case tries to
    test three possible ways of how this may go wrong.  */
-/* { dg-options "-O2 -ffast-math" } */
+/* { dg-options "-O2 -ffast-math --param min-divides-for-recip-mul=2" } */
 /* { dg-do compile } */
 
 /* The original test case.  */
Index: testsuite/gcc.dg/tree-ssa/recip-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-ssa/recip-2.c,v
retrieving revision 1.1
diff -p -u -u -r1.1 recip-2.c
--- testsuite/gcc.dg/tree-ssa/recip-2.c	17 May 2005 09:55:44 -0000	1.1
+++ testsuite/gcc.dg/tree-ssa/recip-2.c	12 Oct 2005 10:59:28 -0000
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -funsafe-math-optimizations -fdump-tree-recip" } */
+/* { dg-options "-O1 -funsafe-math-optimizations -fdump-tree-recip --param min-divides-for-recip-mul=2" } */
 
 float e(float a, float b, float c, float d, float e, float f)
 {
Index: testsuite/gcc.dg/tree-ssa/recip-3.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/recip-3.c
diff -N testsuite/gcc.dg/tree-ssa/recip-3.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/recip-3.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-trapping-math -funsafe-math-optimizations -fdump-tree-recip" } */
+
+double F[2] = { 0.0, 0.0 }, e;
+
+/* In this case the optimization is interesting.  */
+float h ()
+{
+	int i;
+	double E, W, P, d;
+
+	W = 1.;
+	d = 2.*e;
+	E = 1. - d;
+
+	for( i=0; i < 2; i++ )
+		if( d > 0.01 )
+		{
+			P = ( W < E ) ? (W - E)/d : (E - W)/d;
+			F[i] += P;
+		}
+
+	F[0] += E / d;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
Index: testsuite/gcc.dg/tree-ssa/recip-4.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/recip-4.c
diff -N testsuite/gcc.dg/tree-ssa/recip-4.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/recip-4.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-trapping-math -funsafe-math-optimizations -fdump-tree-recip" } */
+
+/* based on the test case in pr23109 */
+
+double F[2] = { 0., 0. }, e = 0.;
+
+/* Nope, we cannot prove the optimization is worthwhile in this case.  */
+void f ()
+{
+	int i;
+	double E, W, P, d;
+
+	W = 1.;
+	d = 2.*e;
+	E = 1. - d;
+
+	if( d > 0.01 )
+	{
+		P = ( W < E ) ? (W - E)/d : (E - W)/d;
+		F[i] += P;
+	}
+}
+
+/* We also cannot prove the optimization is worthwhile in this case.  */
+float g ()
+{
+	int i;
+	double E, W, P, d;
+
+	W = 1.;
+	d = 2.*e;
+	E = 1. - d;
+
+	if( d > 0.01 )
+	{
+		P = ( W < E ) ? (W - E)/d : (E - W)/d;
+		F[i] += P;
+	}
+
+	return 1.0 / d;
+}
+
+/* { dg-final { scan-tree-dump-not "reciptmp" "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
Index: testsuite/gcc.dg/tree-ssa/recip-5.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/recip-5.c
diff -N testsuite/gcc.dg/tree-ssa/recip-5.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/recip-5.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,30 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -ftrapping-math -fdump-tree-recip -fdump-tree-optimized --param min-divides-for-recip-mul=2" } */
+/* { dg-do compile } */
+
+/* Test the reciprocal optimizations together with trapping math.  */
+
+extern int g();
+
+double f(double y, double z, double w)
+{
+  double b, c, d, e;
+
+  if (g ())
+    /* inserts one division here */
+    b = 1 / y, c = z / y;
+  else
+    /* one division here */
+    b = 3 / y, c = w / y;
+
+  /* and one here, that should be removed afterwards */
+  d = b / y;
+  e = c / y;
+
+  return b + c + d + e;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 3 "recip" } } */
+/* { dg-final { scan-tree-dump-times " / " 2 "optimized" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
Index: testsuite/gcc.dg/tree-ssa/recip-6.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/recip-6.c
diff -N testsuite/gcc.dg/tree-ssa/recip-6.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/recip-6.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,25 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -fno-trapping-math -fdump-tree-recip --param min-divides-for-recip-mul=2" } */
+/* { dg-do compile } */
+
+/* Test inserting in a block that does not contain a division.  */
+
+extern int g();
+
+double f(double y, double z, double w)
+{
+  double b, c, d, e;
+
+  if (g ())
+    b = 1 / y, c = z / y;
+  else
+    b = 3 / y, c = w / y;
+
+  d = b / y;
+  e = c / y;
+
+  return b + c + d + e;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+
Index: testsuite/gcc.dg/tree-ssa/recip-7.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/recip-7.c
diff -N testsuite/gcc.dg/tree-ssa/recip-7.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/tree-ssa/recip-7.c	12 Oct 2005 10:59:28 -0000
@@ -0,0 +1,26 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -fno-trapping-math -fdump-tree-recip --param min-divides-for-recip-mul=2" } */
+/* { dg-do compile } */
+
+/* Test inserting in a block that does not contain a division.  */
+
+extern double h();
+
+double f(int x, double z, double w)
+{
+  double b, c, d, e;
+  double y = h ();
+
+  if (x)
+    b = 1 / y, c = z / y;
+  else
+    b = 3 / y, c = w / y;
+
+  d = b / y;
+  e = c / y;
+
+  return b + c + d + e;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]