summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-19 13:28:35 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-19 13:28:35 +0000
commitc75add39618130b6e7f7e0debe2b4415399605b4 (patch)
treed1606dd653bef02ed1c44555e1bf88b1429b3874
parent3cb3fce5a62678369b7d9d5054f6cd8a99c323bd (diff)
downloadgcc-c75add39618130b6e7f7e0debe2b4415399605b4.tar.gz
2013-11-19 Richard Biener <rguenther@suse.de>
PR middle-end/58956 * tree-ssa-ter.c (find_replaceable_in_bb): Avoid forwarding loads into stmts that may clobber it. * gcc.dg/torture/pr58956.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205026 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58956.c30
-rw-r--r--gcc/tree-ssa-ter.c7
4 files changed, 44 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9931a0b3216..fdfb2ef64bd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-19 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/58956
+ * tree-ssa-ter.c (find_replaceable_in_bb): Avoid forwarding
+ loads into stmts that may clobber it.
+
2013-11-19 Bernd Schmidt <bernds@codesourcery.com>
* cgraphunit.c (symtab_terminator): New variable.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7fd31dfa3d9..89776eaab1a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-19 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/58956
+ * gcc.dg/torture/pr58956.c: New testcase.
+
2013-11-19 Marek Polacek <polacek@redhat.com>
* c-c++-common/ubsan/null-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr58956.c b/gcc/testsuite/gcc.dg/torture/pr58956.c
new file mode 100644
index 00000000000..7576ba7fb5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58956.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+struct S
+{
+ int f0;
+} a = {1}, b, g, *c = &b, **f = &c;
+
+int *d, **e = &d, h;
+
+struct S
+foo ()
+{
+ *e = &h;
+ if (!d)
+ __builtin_unreachable ();
+ *f = &g;
+ return a;
+}
+
+int
+main ()
+{
+ struct S *i = c;
+ *i = foo ();
+ if (b.f0 != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index 883f950c11a..9b9e655b726 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -602,8 +602,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
/* If the stmt does a memory store and the replacement
is a load aliasing it avoid creating overlapping
assignments which we cannot expand correctly. */
- if (gimple_vdef (stmt)
- && gimple_assign_single_p (stmt))
+ if (gimple_vdef (stmt))
{
gimple def_stmt = SSA_NAME_DEF_STMT (use);
while (is_gimple_assign (def_stmt)
@@ -612,8 +611,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
= SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
if (gimple_vuse (def_stmt)
&& gimple_assign_single_p (def_stmt)
- && refs_may_alias_p (gimple_assign_lhs (stmt),
- gimple_assign_rhs1 (def_stmt)))
+ && stmt_may_clobber_ref_p (stmt,
+ gimple_assign_rhs1 (def_stmt)))
same_root_var = true;
}