]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/43560 (possible wrong code bug)
authorRichard Guenther <rguenther@suse.de>
Mon, 29 Mar 2010 15:20:07 +0000 (15:20 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 29 Mar 2010 15:20:07 +0000 (15:20 +0000)
2010-03-29  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/43560
* tree-ssa-loop-im.c (ref_always_accessed_p): Add store_p
parameter.
(can_sm_ref_p): Treat stores to readonly locations as
trapping.

* gcc.dg/torture/pr43560.c: New testcase.

From-SVN: r157799

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr43560.c [new file with mode: 0644]
gcc/tree-ssa-loop-im.c

index f3b75676a0235bfb1a504b20ec8b79cab4692c1d..73f102db9f7057873bd1073c6a2c3b8502103010 100644 (file)
@@ -1,3 +1,11 @@
+2010-03-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43560
+       * tree-ssa-loop-im.c (ref_always_accessed_p): Add store_p
+       parameter.
+       (can_sm_ref_p): Treat stores to readonly locations as
+       trapping.
+
 2010-03-29  Jie Zhang  <jie@codesourcery.com>
 
        PR 43564
index e2fd72efee587dd32ef9d573db376406bfcc11e9..5fe5fc94a76f057b8afafc16d6e75683cae15456 100644 (file)
@@ -1,3 +1,8 @@
+2010-03-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43560
+       * gcc.dg/torture/pr43560.c: New testcase.
+
 2010-03-29  Jason Merrill  <jason@redhat.com>
 
        N3077
diff --git a/gcc/testsuite/gcc.dg/torture/pr43560.c b/gcc/testsuite/gcc.dg/torture/pr43560.c
new file mode 100644 (file)
index 0000000..44abb80
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-require-weak "" } */
+
+int g_6[1][2] = {{1,1}};
+int g_34 = 0;
+int *const g_82 = &g_6[0][1];
+int *g_85[2][1] __attribute__((weak));
+
+void __attribute__((noinline))
+func_4 (int x)
+{
+  int i;
+  for (i = 0; i <= x; i++) {
+      if (g_6[0][1]) {
+         *g_82 = 1;
+      } else {
+         int **l_109 = &g_85[1][0];
+         if (&g_82 != l_109) {
+         } else {
+             *l_109 = &g_6[0][1];
+         }
+         *g_82 = 1;
+      }
+  }
+}
+
+int main (void)
+{
+  g_85[0][0] = &g_34;
+  g_85[1][0] = &g_34;
+  func_4(1);
+  return 0;
+} 
+
index 528db6505705b5a29594505650959a3bbc91b039..825fb71760a09c10fefb36ed0b40f4549f8b34ab 100644 (file)
@@ -1900,16 +1900,22 @@ hoist_memory_references (struct loop *loop, bitmap mem_refs,
     }
 }
 
-/* Returns true if REF is always accessed in LOOP.  */
+/* Returns true if REF is always accessed in LOOP.  If STORED_P is true
+   make sure REF is always stored to in LOOP.  */
 
 static bool
-ref_always_accessed_p (struct loop *loop, mem_ref_p ref)
+ref_always_accessed_p (struct loop *loop, mem_ref_p ref, bool stored_p)
 {
   VEC (mem_ref_loc_p, heap) *locs = NULL;
   unsigned i;
   mem_ref_loc_p loc;
   bool ret = false;
   struct loop *must_exec;
+  tree base;
+
+  base = get_base_address (ref->mem);
+  if (INDIRECT_REF_P (base))
+    base = TREE_OPERAND (base, 0);
 
   get_all_locs_in_loop (loop, ref, &locs);
   for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++)
@@ -1917,6 +1923,22 @@ ref_always_accessed_p (struct loop *loop, mem_ref_p ref)
       if (!get_lim_data (loc->stmt))
        continue;
 
+      /* If we require an always executed store make sure the statement
+         stores to the reference.  */
+      if (stored_p)
+       {
+         tree lhs;
+         if (!gimple_get_lhs (loc->stmt))
+           continue;
+         lhs = get_base_address (gimple_get_lhs (loc->stmt));
+         if (!lhs)
+           continue;
+         if (INDIRECT_REF_P (lhs))
+           lhs = TREE_OPERAND (lhs, 0);
+         if (lhs != base)
+           continue;
+       }
+
       must_exec = get_lim_data (loc->stmt)->always_executed_in;
       if (!must_exec)
        continue;
@@ -2054,6 +2076,8 @@ ref_indep_loop_p (struct loop *loop, mem_ref_p ref)
 static bool
 can_sm_ref_p (struct loop *loop, mem_ref_p ref)
 {
+  tree base;
+
   /* Unless the reference is stored in the loop, there is nothing to do.  */
   if (!bitmap_bit_p (ref->stored, loop->num))
     return false;
@@ -2064,9 +2088,14 @@ can_sm_ref_p (struct loop *loop, mem_ref_p ref)
       || !for_each_index (&ref->mem, may_move_till, loop))
     return false;
 
-  /* If it can trap, it must be always executed in LOOP.  */
-  if (tree_could_trap_p (ref->mem)
-      && !ref_always_accessed_p (loop, ref))
+  /* If it can trap, it must be always executed in LOOP.
+     Readonly memory locations may trap when storing to them, but
+     tree_could_trap_p is a predicate for rvalues, so check that
+     explicitly.  */
+  base = get_base_address (ref->mem);
+  if ((tree_could_trap_p (ref->mem)
+       || (DECL_P (base) && TREE_READONLY (base)))
+      && !ref_always_accessed_p (loop, ref, true))
     return false;
 
   /* And it must be independent on all other memory references