diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 16 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/brokensqrt.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sse-recip-vec.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sse-recip.c | 3 | ||||
-rw-r--r-- | gcc/tree-pass.h | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 92 |
9 files changed, 58 insertions, 104 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b0a07e2..e6c56b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-10-29 Michael Matz <matz@suse.de> + + * tree-ssa-math-opts.c (execute_convert_to_rsqrt): Remove. + (gate_convert_to_rsqrt): Ditto. + (pass_convert_to_rsqrt): Ditto. + * tree-pass.h (pass_convert_to_rsqrt): Don't declare. + * passes.c (init_optimization_passes): Don't add pass_convert_to_rsqrt + to pass list. + + * config/i386/i386.c (ix86_emit_swdivsf): Change evaluation order. + 2009-10-29 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> * config/arm/arm.c (find_best_start): Fix type of remainder to be diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index fd1dad6..349df7a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -28626,18 +28626,18 @@ void ix86_emit_swdivsf (rtx res, rtx a, rtx b, enum machine_mode mode) emit_insn (gen_rtx_SET (VOIDmode, x0, gen_rtx_UNSPEC (mode, gen_rtvec (1, b), UNSPEC_RCP))); - /* e0 = x0 * b */ + /* e0 = x0 * a */ emit_insn (gen_rtx_SET (VOIDmode, e0, - gen_rtx_MULT (mode, x0, b))); - /* e1 = 2. - e0 */ + gen_rtx_MULT (mode, x0, a))); + /* e1 = x0 * b */ emit_insn (gen_rtx_SET (VOIDmode, e1, - gen_rtx_MINUS (mode, two, e0))); - /* x1 = x0 * e1 */ + gen_rtx_MULT (mode, x0, b))); + /* x1 = 2. - e1 */ emit_insn (gen_rtx_SET (VOIDmode, x1, - gen_rtx_MULT (mode, x0, e1))); - /* res = a * x1 */ + gen_rtx_MINUS (mode, two, e1))); + /* res = e0 * x1 */ emit_insn (gen_rtx_SET (VOIDmode, res, - gen_rtx_MULT (mode, a, x1))); + gen_rtx_MULT (mode, e0, x1))); } /* Output code to perform a Newton-Rhapson approximation of a diff --git a/gcc/passes.c b/gcc/passes.c index db368f0..8022549 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -880,7 +880,6 @@ init_optimization_passes (void) NEXT_PASS (pass_tree_loop_done); } NEXT_PASS (pass_cse_reciprocals); - NEXT_PASS (pass_convert_to_rsqrt); NEXT_PASS (pass_reassoc); NEXT_PASS (pass_vrp); NEXT_PASS (pass_dominator); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1255e8f..e382b96 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-10-29 Michael Matz <matz@suse.de> + + * gcc.target/i386/sse-recip.c: Use fabsf instead of != . + * gcc.target/i386/sse-recip-vec.c: Ditto. + * gcc.target/i386/brokensqrt.c: New test. + 2009-10-29 Tobias Burnus <burnus@net-b.de> PR fortran/41777 diff --git a/gcc/testsuite/gcc.target/i386/brokensqrt.c b/gcc/testsuite/gcc.target/i386/brokensqrt.c new file mode 100644 index 0000000..19a59d8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/brokensqrt.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ffast-math -msse -mfpmath=sse -mrecip" } */ +#include "sse-check.h" + +extern float sqrtf (float); +float __attribute__((noinline)) broken (float a, float b) +{ + return sqrtf (a / b); +} + +extern void abort (void); +extern void *memcpy (void *, const void *, __SIZE_TYPE__); +static void +sse_test (void) +{ + int i; + float x; + char buf[sizeof (float)]; + x = broken (0.0f, 10000.0f); + /* A convoluted way to check for the correct result (zero) for all + floating point formats. + We can't use ==, !=, or range checks, or isinf/isnan/isunordered, + because all of these will not do the right thing under -ffast-math, + as they can assume that neither nan nor inf are returned. */ + memcpy (&buf, &x, sizeof (float)); + for (i = 0; i < sizeof (float); i++) + if (buf[i] != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/sse-recip-vec.c b/gcc/testsuite/gcc.target/i386/sse-recip-vec.c index 2f90ec8..202351d 100644 --- a/gcc/testsuite/gcc.target/i386/sse-recip-vec.c +++ b/gcc/testsuite/gcc.target/i386/sse-recip-vec.c @@ -4,6 +4,7 @@ #include "sse-check.h" extern float sqrtf (float); +extern float fabsf (float); #define N 8 @@ -26,7 +27,7 @@ sse_test (void) /* check results: */ for (i = 0; i < N; i++) { - if (r[i] != rc[i]) + if (fabsf (r[i] - rc[i]) > 0.0001) abort(); } } diff --git a/gcc/testsuite/gcc.target/i386/sse-recip.c b/gcc/testsuite/gcc.target/i386/sse-recip.c index b673f40..d88eb7f 100644 --- a/gcc/testsuite/gcc.target/i386/sse-recip.c +++ b/gcc/testsuite/gcc.target/i386/sse-recip.c @@ -4,6 +4,7 @@ #include "sse-check.h" extern float sqrtf (float); +extern float fabsf (float); #define N 8 @@ -26,7 +27,7 @@ sse_test (void) /* check results: */ for (i = 0; i < N; i++) { - if (r[i] != rc[i]) + if (fabsf (r[i] - rc[i]) > 0.0001) abort(); } } diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 8b8b3c4..e8d6fae 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -401,7 +401,6 @@ extern struct gimple_opt_pass pass_early_warn_uninitialized; extern struct gimple_opt_pass pass_late_warn_uninitialized; extern struct gimple_opt_pass pass_cse_reciprocals; extern struct gimple_opt_pass pass_cse_sincos; -extern struct gimple_opt_pass pass_convert_to_rsqrt; extern struct gimple_opt_pass pass_optimize_bswap; extern struct gimple_opt_pass pass_warn_function_return; extern struct gimple_opt_pass pass_warn_function_noreturn; diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 11ce546..f0fcc2b 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -791,98 +791,6 @@ struct gimple_opt_pass pass_cse_sincos = } }; -/* Find all expressions in the form of sqrt(a/b) and - convert them to rsqrt(b/a). */ - -static unsigned int -execute_convert_to_rsqrt (void) -{ - basic_block bb; - - FOR_EACH_BB (bb) - { - gimple_stmt_iterator gsi; - - for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - tree fndecl; - - if (is_gimple_call (stmt) - && gimple_call_lhs (stmt) - && (fndecl = gimple_call_fndecl (stmt)) - && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)) - { - enum built_in_function code; - bool md_code; - tree arg1; - gimple stmt1; - - code = DECL_FUNCTION_CODE (fndecl); - md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD; - - fndecl = targetm.builtin_reciprocal (code, md_code, true); - if (!fndecl) - continue; - - arg1 = gimple_call_arg (stmt, 0); - - if (TREE_CODE (arg1) != SSA_NAME) - continue; - - stmt1 = SSA_NAME_DEF_STMT (arg1); - - if (is_gimple_assign (stmt1) - && gimple_assign_rhs_code (stmt1) == RDIV_EXPR) - { - tree arg10, arg11; - - arg10 = gimple_assign_rhs1 (stmt1); - arg11 = gimple_assign_rhs2 (stmt1); - - /* Swap operands of RDIV_EXPR. */ - gimple_assign_set_rhs1 (stmt1, arg11); - gimple_assign_set_rhs2 (stmt1, arg10); - fold_stmt_inplace (stmt1); - update_stmt (stmt1); - - gimple_call_set_fndecl (stmt, fndecl); - update_stmt (stmt); - } - } - } - } - - return 0; -} - -static bool -gate_convert_to_rsqrt (void) -{ - return flag_unsafe_math_optimizations && optimize; -} - -struct gimple_opt_pass pass_convert_to_rsqrt = -{ - { - GIMPLE_PASS, - "rsqrt", /* name */ - gate_convert_to_rsqrt, /* gate */ - execute_convert_to_rsqrt, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_dump_func | TODO_update_ssa | TODO_verify_ssa - | TODO_verify_stmts /* todo_flags_finish */ - } -}; - /* A symbolic number is used to detect byte permutation and selection patterns. Therefore the field N contains an artificial number consisting of byte size markers: |