re PR middle-end/41963 (177.mesa in SPEC CPU 2K is miscompiled)
authorMichael Matz <matz@suse.de>
Fri, 6 Nov 2009 15:05:20 +0000 (15:05 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Fri, 6 Nov 2009 15:05:20 +0000 (15:05 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr41963.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.c

index 6e1086a..d0df7de 100644 (file)
@@ -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
index 04ce939..60159c1 100644 (file)
@@ -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 (file)
index 0000000..f8bf4a1
--- /dev/null
@@ -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;
+}
index f0fcc2b..c0ddc8a 100644 (file)
@@ -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);
+                   }
                }
            }
        }