aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.c16
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/brokensqrt.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-recip-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-recip.c3
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-ssa-math-opts.c92
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: