aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2009-11-06 15:05:20 +0000
committerMichael Matz <matz@gcc.gnu.org>2009-11-06 15:05:20 +0000
commit79af7c1f6d8a41e7d2c9f8c3c4541eceddef0284 (patch)
tree90670b8a9be6e2de19fdb86e0077119c3c77ffd0 /gcc
parent9cd4e79ba8e43b27273f27874ecd5142c60cc338 (diff)
downloadgcc-79af7c1f6d8a41e7d2c9f8c3c4541eceddef0284.zip
gcc-79af7c1f6d8a41e7d2c9f8c3c4541eceddef0284.tar.gz
gcc-79af7c1f6d8a41e7d2c9f8c3c4541eceddef0284.tar.bz2
re PR middle-end/41963 (177.mesa in SPEC CPU 2K is miscompiled)
PR middle-end/41963 * tree-ssa-math-opts.c (execute_cse_reciprocals): Check all uses of a potential reciprocal to really be reciprocals. testsuite/ * gcc.dg/pr41963.c: New test. From-SVN: r153971
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr41963.c36
-rw-r--r--gcc/tree-ssa-math-opts.c34
4 files changed, 77 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6e1086a..d0df7de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-06 Michael Matz <matz@suse.de>
+
+ PR middle-end/41963
+ * tree-ssa-math-opts.c (execute_cse_reciprocals): Check all uses
+ of a potential reciprocal to really be reciprocals.
+
2009-11-06 Jakub Jelinek <jakub@redhat.com>
* config/i386/x86intrin.h: Include fma4intrin.h, xopintrin.h and
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 04ce939..60159c1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-06 Michael Matz <matz@suse.de>
+
+ PR middle-end/41963
+ * gcc.dg/pr41963.c: New test.
+
2009-11-06 Jakub Jelinek <jakub@redhat.com>
PR middle-end/41935
diff --git a/gcc/testsuite/gcc.dg/pr41963.c b/gcc/testsuite/gcc.dg/pr41963.c
new file mode 100644
index 0000000..f8bf4a1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr41963.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -ffast-math" } */
+#include <math.h>
+
+extern float sqrtf(float);
+
+static __attribute__((noinline)) void f (float *dst, float *src)
+{
+ int i, j;
+ for (i = 0; i < 2; i++)
+ {
+ float len;
+ dst[0] = src[0];
+ dst[1] = src[1];
+ len = sqrtf (dst[0] * dst[0] + dst[1] * dst[1]);
+ if (len > 0.5f)
+ {
+ len = 1.0f / len;
+ dst[0] *= len;
+ dst[1] *= len;
+ }
+ }
+}
+
+extern void abort (void);
+
+int main()
+{
+ float dst[2], src[2];
+ src[0] = 2.0f;
+ src[1] = 5.0f;
+ f (dst, src);
+ if (fabsf (dst[0] * dst[0] + dst[1] * dst[1] - 1.0f) > 0.01f)
+ abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index f0fcc2b..c0ddc8a 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -531,7 +531,9 @@ execute_cse_reciprocals (void)
|| DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
{
enum built_in_function code;
- bool md_code;
+ bool md_code, fail;
+ imm_use_iterator ui;
+ use_operand_p use_p;
code = DECL_FUNCTION_CODE (fndecl);
md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
@@ -540,12 +542,36 @@ execute_cse_reciprocals (void)
if (!fndecl)
continue;
+ /* Check that all uses of the SSA name are divisions,
+ otherwise replacing the defining statement will do
+ the wrong thing. */
+ fail = false;
+ FOR_EACH_IMM_USE_FAST (use_p, ui, arg1)
+ {
+ gimple stmt2 = USE_STMT (use_p);
+ if (is_gimple_debug (stmt2))
+ continue;
+ if (!is_gimple_assign (stmt2)
+ || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
+ || gimple_assign_rhs1 (stmt2) == arg1
+ || gimple_assign_rhs2 (stmt2) != arg1)
+ {
+ fail = true;
+ break;
+ }
+ }
+ if (fail)
+ continue;
+
gimple_call_set_fndecl (stmt1, fndecl);
update_stmt (stmt1);
- gimple_assign_set_rhs_code (stmt, MULT_EXPR);
- fold_stmt_inplace (stmt);
- update_stmt (stmt);
+ FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
+ {
+ gimple_assign_set_rhs_code (stmt, MULT_EXPR);
+ fold_stmt_inplace (stmt);
+ update_stmt (stmt);
+ }
}
}
}