This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR/23948 and PR/24123 (recip problems)
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Uros Bizjak <uros at kss-loka dot si>, Richard Guenther <rguenther at suse dot de>
- Date: Wed, 12 Oct 2005 13:03:13 +0200
- Subject: Re: PR/23948 and PR/24123 (recip problems)
- References: <434CE216.7090307@lu.unisi.ch>
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" } } */
+