aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-03-29 15:20:07 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-03-29 15:20:07 +0000
commit58adb739eff82cda929295c909e70be78f81ffbe (patch)
treef88e6ff40be54449b7f60f480ca30300c46d4eb3
parent521506258fa5b6b57a50b0570d8208894ed19f79 (diff)
downloadgcc-58adb739eff82cda929295c909e70be78f81ffbe.zip
gcc-58adb739eff82cda929295c909e70be78f81ffbe.tar.gz
gcc-58adb739eff82cda929295c909e70be78f81ffbe.tar.bz2
re PR tree-optimization/43560 (possible wrong code bug)
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr43560.c34
-rw-r--r--gcc/tree-ssa-loop-im.c39
4 files changed, 81 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3b7567..73f102d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e2fd72e..5fe5fc9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..44abb80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr43560.c
@@ -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;
+}
+
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 528db65..825fb71 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -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