tree-ssa-sccvn.c (visit_phi): Merge undefined values similar to VN_TOP.
authorRichard Biener <rguenther@suse.de>
Thu, 14 Sep 2017 11:57:08 +0000 (11:57 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 14 Sep 2017 11:57:08 +0000 (11:57 +0000)
2017-09-14  Richard Biener  <rguenther@suse.de>

* tree-ssa-sccvn.c (visit_phi): Merge undefined values similar
to VN_TOP.

* gcc.dg/tree-ssa/ssa-fre-59.c: New testcase.
* gcc.dg/uninit-suppress_2.c: Adjust.
* gcc.dg/tree-ssa/ssa-sccvn-2.c: Likewise.

From-SVN: r252756

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-59.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-sccvn-2.c
gcc/testsuite/gcc.dg/uninit-suppress_2.c
gcc/tree-ssa-sccvn.c

index 537005b..3925e46 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-14  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-sccvn.c (visit_phi): Merge undefined values similar
+       to VN_TOP.
+
 2017-09-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        * dwarf2out.c (dwarf2out_source_line): Remove superfluous test.
index 77dae41..fe3cfa4 100644 (file)
@@ -1,3 +1,9 @@
+2017-09-14  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/ssa-fre-59.c: New testcase.
+       * gcc.dg/uninit-suppress_2.c: Adjust.
+       * gcc.dg/tree-ssa/ssa-sccvn-2.c: Likewise.
+
 2017-09-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR tree-optimization/80996
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-59.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-59.c
new file mode 100644 (file)
index 0000000..952934b
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+int i;
+int foo (int b)
+{
+  int j;
+  i = 1;
+  if (b)
+    j = i;
+  return i - j;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
index 2fe0dc8..ab75825 100644 (file)
@@ -21,4 +21,4 @@ int vnum_test8(int *data)
 } 
 /* We should eliminate m - n, and set n = n + k into n = m, and
    set p to 0 */
-/* { dg-final { scan-tree-dump-times "Eliminated: 4" 1 "fre1"} } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 5" 1 "fre1"} } */
index a4371ec..af0f192 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fno-tree-ccp -fno-tree-vrp -O2 -Wuninitialized -Werror=uninitialized -Wno-error=maybe-uninitialized" } */
+/* { dg-options "-fno-tree-ccp -fno-tree-vrp -fno-tree-fre -fno-tree-pre -fno-code-hoisting -O2 -Wuninitialized -Werror=uninitialized -Wno-error=maybe-uninitialized" } */
 void blah();
 void bar (int);
 int gflag;
index 93342c0..44618da 100644 (file)
@@ -3860,11 +3860,11 @@ visit_reference_op_store (tree lhs, tree op, gimple *stmt)
 static bool
 visit_phi (gimple *phi)
 {
-  bool changed = false;
-  tree result;
-  tree sameval = VN_TOP;
-  bool allsame = true;
+  tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
   unsigned n_executable = 0;
+  bool allsame = true;
+  edge_iterator ei;
+  edge e;
 
   /* TODO: We could check for this in init_sccvn, and replace this
      with a gcc_assert.  */
@@ -3873,8 +3873,6 @@ visit_phi (gimple *phi)
 
   /* See if all non-TOP arguments have the same value.  TOP is
      equivalent to everything, so we can ignore it.  */
-  edge_iterator ei;
-  edge e;
   FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds)
     if (e->flags & EDGE_EXECUTABLE)
       {
@@ -3884,8 +3882,12 @@ visit_phi (gimple *phi)
        if (TREE_CODE (def) == SSA_NAME)
          def = SSA_VAL (def);
        if (def == VN_TOP)
-         continue;
-       if (sameval == VN_TOP)
+         ;
+       /* Ignore undefined defs for sameval but record one.  */
+       else if (TREE_CODE (def) == SSA_NAME
+                && ssa_undefined_value_p (def, false))
+         seen_undef = def;
+       else if (sameval == VN_TOP)
          sameval = def;
        else if (!expressions_equal_p (def, sameval))
          {
@@ -3893,30 +3895,39 @@ visit_phi (gimple *phi)
            break;
          }
       }
-  
-  /* If none of the edges was executable or all incoming values are
-     undefined keep the value-number at VN_TOP.  If only a single edge
-     is exectuable use its value.  */
-  if (sameval == VN_TOP
-      || n_executable == 1)
-    return set_ssa_val_to (PHI_RESULT (phi), sameval);
 
+
+  /* If none of the edges was executable keep the value-number at VN_TOP,
+     if only a single edge is exectuable use its value.  */
+  if (n_executable <= 1)
+    result = seen_undef ? seen_undef : sameval;
+  /* If we saw only undefined values create a new undef SSA name to
+     avoid false equivalences.  */
+  else if (sameval == VN_TOP)
+    {
+      gcc_assert (seen_undef);
+      result = seen_undef;
+    }
   /* First see if it is equivalent to a phi node in this block.  We prefer
      this as it allows IV elimination - see PRs 66502 and 67167.  */
-  result = vn_phi_lookup (phi);
-  if (result)
-    changed = set_ssa_val_to (PHI_RESULT (phi), result);
-  /* Otherwise all value numbered to the same value, the phi node has that
-     value.  */
-  else if (allsame)
-    changed = set_ssa_val_to (PHI_RESULT (phi), sameval);
+  else if ((result = vn_phi_lookup (phi)))
+    ;
+  /* If all values are the same use that, unless we've seen undefined
+     values as well and the value isn't constant.
+     CCP/copyprop have the same restriction to not remove uninit warnings.  */
+  else if (allsame
+          && (! seen_undef || is_gimple_min_invariant (sameval)))
+    result = sameval;
   else
     {
-      vn_phi_insert (phi, PHI_RESULT (phi));
-      changed = set_ssa_val_to (PHI_RESULT (phi), PHI_RESULT (phi));
+      result = PHI_RESULT (phi);
+      /* Only insert PHIs that are varying, for constant value numbers
+         we mess up equivalences otherwise as we are only comparing
+        the immediate controlling predicates.  */
+      vn_phi_insert (phi, result);
     }
 
-  return changed;
+  return set_ssa_val_to (PHI_RESULT (phi), result);
 }
 
 /* Try to simplify RHS using equivalences and constant folding.  */