]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Biener <rguenther@suse.de>
Thu, 26 Jan 2017 08:16:37 +0000 (08:16 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 26 Jan 2017 08:16:37 +0000 (08:16 +0000)
2017-01-26  Richard Biener  <rguenther@suse.de>

Backport from mainline
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.

2016-09-29  Richard Biener  <rguenther@suse.de>

PR tree-optimization/77768
* tree-ssa-sccvn.c (visit_reference_op_store): Properly deal
with stores to a place we know has a constant value.
* tree-vrp.c (set_defs_to_varying): New helper avoiding
writing to vr_const_varying.
(vrp_initialize): Call it.
(vrp_visit_stmt): Likewise.
(evrp_dom_walker::before_dom_children): Likewise.
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Handle stores to readonly memory when removing redundant stores.

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

From-SVN: r244918

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

index b241a85663e2e420ea2598565957a6e69b6f77ed..84f84e528bcc10edfa8a405c741f1268179be5a5 100644 (file)
@@ -1,3 +1,28 @@
+2017-01-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       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-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/77768
+       * tree-ssa-sccvn.c (visit_reference_op_store): Properly deal
+       with stores to a place we know has a constant value.
+       * tree-vrp.c (set_defs_to_varying): New helper avoiding
+       writing to vr_const_varying.
+       (vrp_initialize): Call it.
+       (vrp_visit_stmt): Likewise.
+       (evrp_dom_walker::before_dom_children): Likewise.
+       * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
+       Handle stores to readonly memory when removing redundant stores.
+
 2017-01-24  Wilco Dijkstra  <wdijkstr@arm.com>
 
        Backport from mainline
index f20224e4e252cca5200d28be93480ef3dadb1595..a9c135a08778f1cf27211ec9ccc939d13fa77487 100644 (file)
@@ -1,3 +1,16 @@
+2017-01-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2016-09-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/77745
+       * g++.dg/torture/pr77745.C: New testcase.
+
+       2016-09-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/77768
+       * gcc.dg/torture/pr77768.c: New testcase.
+
 2017-01-24  Wilco Dijkstra  <wdijkstr@arm.com>
 
        Backport from mainline
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..dfba7e4
--- /dev/null
@@ -0,0 +1,25 @@
+// { dg-do run }
+// { dg-additional-options "-std=gnu++14" }
+
+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();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr77768.c b/gcc/testsuite/gcc.dg/torture/pr77768.c
new file mode 100644 (file)
index 0000000..47e1484
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+static const int a;
+int b;
+int *c, *d;
+int main()
+{
+  c = (int *)&a;
+  c == d ?: __builtin_exit(0); 
+  for (; b; b++ >= (*d = a))
+    ;
+  return 0;
+}
index 459d8e3cf5f02275f96c616e86ff2e7394c3ee35..32cee65d29eb7e5494a54701fb523cbf13ba0f35 100644 (file)
@@ -4320,26 +4320,36 @@ 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);
-                }
-
-              /* Queue stmt for removal.  */
-              el_to_remove.safe_push (stmt);
-             continue;
-            }
+         vn_reference_t vnresult;
+         val = vn_reference_lookup (lhs, gimple_vuse (stmt), VN_WALK,
+                                    &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 or if the store
+                was to readonly memory storing the same value.  */
+             alias_set_type set = get_alias_set (lhs);
+             if (! vnresult
+                 || 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;
+               }
+           }
         }
 
       bool can_make_abnormal_goto = stmt_can_make_abnormal_goto (stmt);
index 349bae7b0e430148374d8a612789e8a7728312d2..5007a993fb0a235648b7e9919533fbec1d522b5f 100644 (file)
@@ -3132,7 +3132,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
 {
   bool changed = false;
   vn_reference_t vnresult = NULL;
-  tree result, assign;
+  tree assign;
   bool resultsame = false;
   tree vuse = gimple_vuse (stmt);
   tree vdef = gimple_vdef (stmt);
@@ -3156,31 +3156,40 @@ 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);
-
-  if (result)
+  vn_reference_lookup (lhs, vuse, VN_NOWALK, &vnresult, false);
+  if (vnresult
+      && vnresult->result)
     {
+      tree result = vnresult->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)
+  if (!resultsame)
+    {
       /* Only perform the following when being called from PRE
         which embeds tail merging.  */
-      && default_vn_walk_kind == VN_WALK)
-    {
-      assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
-      vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
-      if (vnresult)
+      if (default_vn_walk_kind == VN_WALK)
        {
-         VN_INFO (vdef)->use_processed = true;
-         return set_ssa_val_to (vdef, vnresult->result_vdef);
+         assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
+         vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
+         if (vnresult)
+           {
+             VN_INFO (vdef)->use_processed = true;
+             return set_ssa_val_to (vdef, vnresult->result_vdef);
+           }
        }
-    }
 
-  if (!result || !resultsame)
-    {
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
          fprintf (dump_file, "No store match\n");
@@ -3193,9 +3202,7 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt)
       /* Have to set value numbers before insert, since insert is
         going to valueize the references in-place.  */
       if (vdef)
-       {
-         changed |= set_ssa_val_to (vdef, vdef);
-       }
+       changed |= set_ssa_val_to (vdef, vdef);
 
       /* Do not insert structure copies into the tables.  */
       if (is_gimple_min_invariant (op)
index e8a87c4830c38418905dcc2c44bd86a7bcaccbd2..b25783830c8372a27f75602e591876d6be9b290f 100644 (file)
@@ -807,6 +807,23 @@ get_value_range (const_tree var)
   return vr;
 }
 
+/* Set value-ranges of all SSA names defined by STMT to varying.  */
+
+static void
+set_defs_to_varying (gimple stmt)
+{
+  ssa_op_iter i;
+  tree def;
+  FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
+    {
+      value_range_t *vr = get_value_range (def);
+      /* Avoid writing to vr_const_varying get_value_range may return.  */
+      if (vr->type != VR_VARYING)
+       set_value_range_to_varying (vr);
+    }
+}
+
+
 /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
 
 static inline bool
@@ -7061,10 +7078,7 @@ vrp_initialize (void)
            prop_set_simulate_again (stmt, true);
          else if (!stmt_interesting_for_vrp (stmt))
            {
-             ssa_op_iter i;
-             tree def;
-             FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
-               set_value_range_to_varying (get_value_range (def));
+             set_defs_to_varying (stmt);
              prop_set_simulate_again (stmt, false);
            }
          else
@@ -7117,8 +7131,7 @@ vrp_valueize_1 (tree name)
 static enum ssa_prop_result
 vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
 {
-  tree def, lhs;
-  ssa_op_iter iter;
+  tree lhs;
   enum gimple_code code = gimple_code (stmt);
   lhs = gimple_get_lhs (stmt);
 
@@ -7235,8 +7248,7 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
       }
 
   /* Every other statement produces no useful ranges.  */
-  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
-    set_value_range_to_varying (get_value_range (def));
+  set_defs_to_varying (stmt);
 
   return SSA_PROP_VARYING;
 }
@@ -8009,9 +8021,6 @@ vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
 static enum ssa_prop_result
 vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
 {
-  tree def;
-  ssa_op_iter iter;
-
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "\nVisiting statement:\n");
@@ -8029,8 +8038,7 @@ vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
 
   /* All other statements produce nothing of interest for VRP, so mark
      their outputs varying and prevent further simulation.  */
-  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
-    set_value_range_to_varying (get_value_range (def));
+  set_defs_to_varying (stmt);
 
   return SSA_PROP_VARYING;
 }