summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-11 13:02:18 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-11 13:02:18 +0000
commitac70caaded6c0f5df39f9bd7e2ed9c7f82a8dbd4 (patch)
tree727cbd4df49eeb348d4444be887d342d20481475 /gcc/testsuite/gcc.dg
parente011eba9edce426cbde12b0b43cd4b274b2172d0 (diff)
downloadgcc-ac70caaded6c0f5df39f9bd7e2ed9c7f82a8dbd4.tar.gz
gcc:
2006-01-11 Paolo Bonzini <bonzini@gnu.org> PR tree-optimization/23109 PR tree-optimization/23948 PR tree-optimization/24123 * Makefile.in (tree-ssa-math-opts.o): Adjust dependencies. * tree-cfg.c (single_noncomplex_succ): New. * tree-flow.h (single_noncomplex_succ): Declare it. * tree-ssa-math-opts.c (enum place_reciprocal): Remove. * tree-ssa-math-opts.c (enum place_reciprocal): Remove. (struct occurrence, occ_head, occ_pool, is_divide_by, compute_merit, insert_bb, register_division_in, insert_reciprocals, replace_reciprocal, free_bb): New. (execute_cse_reciprocals_1): Rewritten. (execute_cse_reciprocals): Adjust calls to execute_cse_reciprocals_1. Do not commit any edge insertion. Always compute dominators and create the allocation pool. * target-def.h (TARGET_MIN_DIVISIONS_FOR_RECIP_MUL): New. * target.h (struct gcc_target): Add min_divistions_for_recip_mul. * targhooks.c (default_min_divistions_for_recip_mul): New. * targhooks.h (default_min_divistions_for_recip_mul): New prototype. * passes.c (init_optimization_passes): Run recip after tree loop optimizations. * doc/tm.texi (Misc): Document TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. gcc/testsuite: 2006-01-11 Paolo Bonzini <bonzini@gnu.org> PR tree-optimization/23109 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/recip-2.c, gcc.dg/tree-ssa/pr23234.c: Provide three divisions in order to do the optimization. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109578 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23109.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23234.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-2.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-4.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-5.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-6.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/recip-7.c27
8 files changed, 205 insertions, 4 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
new file mode 100644
index 00000000000..e121a553833
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23109.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funsafe-math-optimizations -fdump-tree-recip -fdump-tree-lim" } */
+
+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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c
index bd0b62b558f..3a3869815c8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23234.c
@@ -9,6 +9,7 @@ double
f1 (double a, double b, double c)
{
double y0;
+ double y1;
if (a == 0.0)
{
@@ -16,7 +17,8 @@ f1 (double a, double b, double c)
return y0;
}
y0 = c / b;
- return y0;
+ y1 = a / b;
+ return y0 * y1;
}
/* Labels may end up in the middle of a block. Also bad. */
@@ -24,6 +26,7 @@ double
f2 (double a, double b, double c)
{
double y0;
+ double y1;
a_label:
another_label:
@@ -33,7 +36,8 @@ another_label:
return y0;
}
y0 = c / b;
- return y0;
+ y1 = a / b;
+ return y0 * y1;
}
/* Uses must still be dominated by their defs. */
@@ -41,6 +45,7 @@ double
f3 (double a, double b, double c)
{
double y0;
+ double y1;
y0 = -c / b;
if (a == 0.0)
@@ -48,5 +53,6 @@ f3 (double a, double b, double c)
return y0;
}
y0 = c / b;
- return y0;
+ y1 = a / b;
+ return y0 * y1;
}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-2.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-2.c
index 7d0e97ae371..af628053ad5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/recip-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-2.c
@@ -10,14 +10,19 @@ float e(float a, float b, float c, float d, float e, float f)
}
/* The PHI nodes for these divisions should be combined. */
+ d = d / a;
e = e / a;
f = f / a;
a = a / c;
b = b / c;
- return a + b + e + f;
+ /* This should not be left as a multiplication. */
+ c = 1 / c;
+
+ return a + b + c + d + e + f;
}
/* { dg-final { scan-tree-dump-times " / " 2 "recip" } } */
+/* { dg-final { scan-tree-dump-times " \\* " 5 "recip" } } */
/* { dg-final { cleanup-tree-dump "recip" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-3.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-3.c
new file mode 100644
index 00000000000..45c8db148ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-3.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-4.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-4.c
new file mode 100644
index 00000000000..20d7681d28d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-4.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-5.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-5.c
new file mode 100644
index 00000000000..bcbd1839cbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-5.c
@@ -0,0 +1,31 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -ftrapping-math -fdump-tree-recip -fdump-tree-optimized" } */
+/* { dg-do compile } */
+
+/* Test the reciprocal optimizations together with trapping math. */
+
+extern int f2();
+
+double f1(double y, double z, double w, double j, double k)
+{
+ double b, c, d, e, f, g;
+
+ if (f2 ())
+ /* inserts one division here */
+ b = 1 / y, c = z / y, d = j / y;
+ else
+ /* one division here */
+ b = 3 / y, c = w / y, d = k / y;
+
+ /* and one here, that should be removed afterwards but is not right now */
+ e = b / y;
+ f = c / y;
+ g = d / y;
+
+ return e + f + g;
+}
+
+/* { 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" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-6.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-6.c
new file mode 100644
index 00000000000..60fefd01da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-6.c
@@ -0,0 +1,26 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -fno-trapping-math -fdump-tree-recip" } */
+/* { dg-do compile } */
+
+/* Test inserting in a block that does not contain a division. */
+
+extern int f2();
+
+double f1(double y, double z, double w)
+{
+ double b, c, d, e, f;
+
+ if (g ())
+ b = 1 / y, c = z / y;
+ else
+ b = 3 / y, c = w / y;
+
+ d = b / y;
+ e = c / y;
+ f = 1 / y;
+
+ return d + e + f;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/recip-7.c b/gcc/testsuite/gcc.dg/tree-ssa/recip-7.c
new file mode 100644
index 00000000000..af1bf3c008b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/recip-7.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O1 -funsafe-math-optimizations -fno-trapping-math -fdump-tree-recip" } */
+/* { 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, f;
+ double y = h ();
+
+ if (x)
+ b = 1 / y, c = z / y;
+ else
+ b = 3 / y, c = w / y;
+
+ d = b / y;
+ e = c / y;
+ f = 1 / y;
+
+ return d + e + f;
+}
+
+/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */
+/* { dg-final { cleanup-tree-dump "recip" } } */
+