re PR tree-optimization/77745 (Inconsistent application of aliasing rules)
authorRichard Biener <rguenther@suse.de>
Tue, 27 Sep 2016 12:56:38 +0000 (12:56 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 27 Sep 2016 12:56:38 +0000 (12:56 +0000)
2016-09-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/77745
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
When removing redundant stores make sure to check compatibility
of the TBAA state for downstream accesses.
* tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when
value-numbering virtual operands for store matches.

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

From-SVN: r240534

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr77745.C [new file with mode: 0644]
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c

index 0255b93..15346af 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/77745
+       * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
+       When removing redundant stores make sure to check compatibility
+       of the TBAA state for downstream accesses.
+       * tree-ssa-sccvn.c (visit_reference_op_store): Likewise for when
+       value-numbering virtual operands for store matches.
+
 2016-09-27  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/51244
index 20680cb..8b6c7d6 100644 (file)
@@ -1,5 +1,10 @@
 2016-09-27  Richard Biener  <rguenther@suse.de>
 
+       PR tree-optimization/77745
+       * g++.dg/torture/pr77745.C: New testcase.
+
+2016-09-27  Richard Biener  <rguenther@suse.de>
+
        PR tree-optimization/77478
        * gcc.dg/torture/pr77478.c: New testcase.
 
diff --git a/gcc/testsuite/g++.dg/torture/pr77745.C b/gcc/testsuite/g++.dg/torture/pr77745.C
new file mode 100644 (file)
index 0000000..59d86b5
--- /dev/null
@@ -0,0 +1,24 @@
+// { dg-do run }
+
+inline void* operator new(__SIZE_TYPE__, void* __p) noexcept { return __p; }
+
+long foo(char *c1, char *c2)
+{
+  long *p1 = new (c1) long;
+  *p1 = 100;
+  long long *p2 = new (c2) long long;
+  *p2 = 200;
+  long *p3 = new (c2) long;
+  *p3 = 200;
+  return *p1;
+}
+int main()
+{
+  union {
+      char c;
+      long l;
+      long long ll;
+  } c;
+  if (foo(&c.c, &c.c) != 200)
+    __builtin_abort();
+}
index 0c6f820..3675fb9 100644 (file)
@@ -4431,26 +4431,34 @@ eliminate_dom_walker::before_dom_children (basic_block b)
          && !is_gimple_reg (gimple_assign_lhs (stmt))
          && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
              || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
-        {
-          tree val;
+       {
+         tree val;
          tree rhs = gimple_assign_rhs1 (stmt);
-          val = vn_reference_lookup (gimple_assign_lhs (stmt),
-                                     gimple_vuse (stmt), VN_WALK, NULL, false);
-          if (TREE_CODE (rhs) == SSA_NAME)
-            rhs = VN_INFO (rhs)->valnum;
-          if (val
-              && operand_equal_p (val, rhs, 0))
-            {
-              if (dump_file && (dump_flags & TDF_DETAILS))
-                {
-                  fprintf (dump_file, "Deleted redundant store ");
-                  print_gimple_stmt (dump_file, stmt, 0, 0);
-                }
+         vn_reference_t vnresult;
+         val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALKREWRITE,
+                                    &vnresult, false);
+         if (TREE_CODE (rhs) == SSA_NAME)
+           rhs = VN_INFO (rhs)->valnum;
+         if (val
+             && operand_equal_p (val, rhs, 0))
+           {
+             /* We can only remove the later store if the former aliases
+                at least all accesses the later one does.  */
+             alias_set_type set = get_alias_set (lhs);
+             if (vnresult->set == set
+                 || alias_set_subset_of (set, vnresult->set))
+               {
+                 if (dump_file && (dump_flags & TDF_DETAILS))
+                   {
+                     fprintf (dump_file, "Deleted redundant store ");
+                     print_gimple_stmt (dump_file, stmt, 0, 0);
+                   }
 
-              /* Queue stmt for removal.  */
-              el_to_remove.safe_push (stmt);
-             continue;
-            }
+                 /* Queue stmt for removal.  */
+                 el_to_remove.safe_push (stmt);
+                 continue;
+               }
+           }
        }
 
       /* If this is a control statement value numbering left edges
index 7f44ec8..94fd66a 100644 (file)
@@ -3599,13 +3599,21 @@ visit_reference_op_store (tree lhs, tree op, gimple *stmt)
      Otherwise, the vdefs for the store are used when inserting into
      the table, since the store generates a new memory state.  */
 
-  result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL, false);
-
+  result = vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
   if (result)
     {
       if (TREE_CODE (result) == SSA_NAME)
        result = SSA_VAL (result);
       resultsame = expressions_equal_p (result, op);
+      if (resultsame)
+       {
+         /* If the TBAA state isn't compatible for downstream reads
+            we cannot value-number the VDEFs the same.  */
+         alias_set_type set = get_alias_set (lhs);
+         if (vnresult->set != set
+             && ! alias_set_subset_of (set, vnresult->set))
+           resultsame = false;
+       }
     }
 
   if ((!result || !resultsame)