re PR tree-optimization/49115 (invalid return value optimization (?) when exception...
authorRichard Guenther <rguenther@suse.de>
Mon, 23 May 2011 12:08:41 +0000 (12:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 23 May 2011 12:08:41 +0000 (12:08 +0000)
2011-05-23  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/49115
* tree-ssa-alias.c (stmt_kills_ref_p_1): If the assignment
is not necessarily carried out, do not claim it kills the ref.
* tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.

* g++.dg/torture/pr49115.C: New testcase.

From-SVN: r174066

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr49115.C [new file with mode: 0644]
gcc/tree-ssa-alias.c
gcc/tree-ssa-dce.c

index 25b569eefa4b10b231264434326960295ea85a1f..62990819dbf316d34cbfc907ab3ecec9b0f8bab1 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49115
+       * tree-ssa-alias.c (stmt_kills_ref_p_1): If the assignment
+       is not necessarily carried out, do not claim it kills the ref.
+       * tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Likewise.
+
 2011-05-23  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/15419
index c41d32448bbc07fd836967f849e0d9ab47d136be..e647cb571452dbee00b9634482086299e350da4c 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-23  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/49115
+       * g++.dg/torture/pr49115.C: New testcase.
+
 2011-05-23  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/15419
diff --git a/gcc/testsuite/g++.dg/torture/pr49115.C b/gcc/testsuite/g++.dg/torture/pr49115.C
new file mode 100644 (file)
index 0000000..c4cce21
--- /dev/null
@@ -0,0 +1,25 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+struct MyException {};
+struct Data {
+    int nr;
+    Data() : nr(66) {}
+};
+Data __attribute__((noinline,noclone)) getData(int i)
+{
+  if (i) throw MyException();
+  Data data;
+  data.nr = i;
+  return data;
+}
+int main(int, char **)
+{
+  Data data;
+  try {
+      data = getData(1);
+  } catch (MyException& e) {
+      if (data.nr != 66)
+       abort ();
+  }
+}
index 315a252fadcee7a310b9a259d6f31cdac9451d3d..ba76ae10ab1214448bdb29537fa3d9ba5be1da5f 100644 (file)
@@ -1633,7 +1633,14 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
     return false;
 
   if (gimple_has_lhs (stmt)
-      && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME)
+      && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
+      /* The assignment is not necessarily carried out if it can throw
+        and we can catch it in the current function where we could inspect
+        the previous value.
+        ???  We only need to care about the RHS throwing.  For aggregate
+        assignments or similar calls and non-call exceptions the LHS
+        might throw as well.  */
+      && !stmt_can_throw_internal (stmt))
     {
       tree base, lhs = gimple_get_lhs (stmt);
       HOST_WIDE_INT size, offset, max_size;
index 6dc8a57f5c8078b4ccc074ca194e0168d49a2055..b13ef59af491b51a9b49470678b5e3bda5e400a8 100644 (file)
@@ -521,7 +521,14 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data)
 
   /* If the stmt lhs kills ref, then we can stop walking.  */
   if (gimple_has_lhs (def_stmt)
-      && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME)
+      && TREE_CODE (gimple_get_lhs (def_stmt)) != SSA_NAME
+      /* The assignment is not necessarily carried out if it can throw
+         and we can catch it in the current function where we could inspect
+        the previous value.
+         ???  We only need to care about the RHS throwing.  For aggregate
+        assignments or similar calls and non-call exceptions the LHS
+        might throw as well.  */
+      && !stmt_can_throw_internal (def_stmt))
     {
       tree base, lhs = gimple_get_lhs (def_stmt);
       HOST_WIDE_INT size, offset, max_size;