diff options
author | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-11 13:02:18 +0000 |
---|---|---|
committer | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-11 13:02:18 +0000 |
commit | ac70caaded6c0f5df39f9bd7e2ed9c7f82a8dbd4 (patch) | |
tree | 727cbd4df49eeb348d4444be887d342d20481475 /gcc/testsuite/gcc.dg | |
parent | e011eba9edce426cbde12b0b43cd4b274b2172d0 (diff) | |
download | gcc-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.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23234.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-2.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-3.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-4.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-5.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-6.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/recip-7.c | 27 |
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" } } */ + |