]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/111397 - missed copy propagation involving abnormal dest
authorRichard Biener <rguenther@suse.de>
Wed, 13 Sep 2023 07:28:34 +0000 (09:28 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 10 Nov 2023 13:21:15 +0000 (14:21 +0100)
The following extends the previous enhancement to copy propagation
involving abnormals.  We can easily replace abnormal uses by not
abnormal uses and only need to preserve the abnormals in PHI arguments
flowing in from abnormal edges.  This changes the may_propagate_copy
argument indicating we are not propagating into a PHI node to indicate
whether we know we are not propagating into a PHI argument from an
abnormal PHI instead.

PR tree-optimization/111397
* tree-ssa-propagate.cc (may_propagate_copy): Change optional
argument to specify whether the PHI destination doesn't flow in
from an abnormal PHI.
(propagate_value): Adjust.
* tree-ssa-forwprop.cc (pass_forwprop::execute): Indicate abnormal
PHI dest.
* tree-ssa-sccvn.cc (eliminate_dom_walker::before_dom_children):
Likewise.
(process_bb): Likewise.

* gcc.dg/uninit-pr111397.c: New testcase.

(cherry picked from commit 92ea12ea99fce546772a40b7bbc2ea850db9b1be)

gcc/testsuite/gcc.dg/uninit-pr111397.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.cc
gcc/tree-ssa-propagate.cc
gcc/tree-ssa-sccvn.cc

diff --git a/gcc/testsuite/gcc.dg/uninit-pr111397.c b/gcc/testsuite/gcc.dg/uninit-pr111397.c
new file mode 100644 (file)
index 0000000..ec12f9d
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+int globalVar = 1;
+int __attribute__ ((__returns_twice__)) test_setjmpex(void *context);
+
+void testfn()
+{
+  int localVar = globalVar;
+  while (!localVar) {
+      test_setjmpex(__builtin_frame_address (0)); // { dg-bogus "uninitialized" }
+      if (globalVar)
+       break;
+  }
+}
index 9b567440ba4f1cb40f1507984e5d4e023623f834..862a7f2b92a7e11531ec787879bcc47b64c4a944 100644 (file)
@@ -4040,7 +4040,7 @@ pass_forwprop::execute (function *fun)
              continue;
            tree val = fwprop_ssa_val (arg);
            if (val != arg
-               && may_propagate_copy (arg, val))
+               && may_propagate_copy (arg, val, !(e->flags & EDGE_ABNORMAL)))
              propagate_value (use_p, val);
          }
 
index 76708ca185f601d1297c163da905c8c6e69c7587..594fdbff211d465facf4ef086447478b3b1ee30a 100644 (file)
@@ -1029,11 +1029,12 @@ substitute_and_fold_engine::substitute_and_fold (basic_block block)
 
 
 /* Return true if we may propagate ORIG into DEST, false otherwise.
-   If DEST_NOT_PHI_ARG_P is true then assume the propagation does
-   not happen into a PHI argument which relaxes some constraints.  */
+   If DEST_NOT_ABNORMAL_PHI_EDGE_P is true then assume the propagation does
+   not happen into a PHI argument which flows in from an abnormal edge
+   which relaxes some constraints.  */
 
 bool
-may_propagate_copy (tree dest, tree orig, bool dest_not_phi_arg_p)
+may_propagate_copy (tree dest, tree orig, bool dest_not_abnormal_phi_edge_p)
 {
   tree type_d = TREE_TYPE (dest);
   tree type_o = TREE_TYPE (orig);
@@ -1053,9 +1054,9 @@ may_propagate_copy (tree dest, tree orig, bool dest_not_phi_arg_p)
           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
     return false;
   /* Similarly if DEST flows in from an abnormal edge then the copy cannot be
-     propagated.  If we know we do not propagate into a PHI argument this
+     propagated.  If we know we do not propagate into such a PHI argument this
      does not apply.  */
-  else if (!dest_not_phi_arg_p
+  else if (!dest_not_abnormal_phi_edge_p
           && TREE_CODE (dest) == SSA_NAME
           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest))
     return false;
@@ -1159,8 +1160,13 @@ void
 propagate_value (use_operand_p op_p, tree val)
 {
   if (flag_checking)
-    gcc_assert (may_propagate_copy (USE_FROM_PTR (op_p), val,
-                                   !is_a <gphi *> (USE_STMT (op_p))));
+    {
+      bool ab = (is_a <gphi *> (USE_STMT (op_p))
+                && (gimple_phi_arg_edge (as_a <gphi *> (USE_STMT (op_p)),
+                                         PHI_ARG_INDEX_FROM_USE (op_p))
+                    ->flags & EDGE_ABNORMAL));
+      gcc_assert (may_propagate_copy (USE_FROM_PTR (op_p), val, !ab));
+    }
   replace_exp (op_p, val);
 }
 
index 9692911e31b2567f112aa97f5a7e2e94112f5b4b..b20a002a14466caca475c23c2c0377dbc2e50917 100644 (file)
@@ -7319,7 +7319,8 @@ eliminate_dom_walker::before_dom_children (basic_block b)
              || virtual_operand_p (arg))
            continue;
          tree sprime = eliminate_avail (b, arg);
-         if (sprime && may_propagate_copy (arg, sprime))
+         if (sprime && may_propagate_copy (arg, sprime,
+                                           !(e->flags & EDGE_ABNORMAL)))
            propagate_value (use_p, sprime);
        }
 
@@ -8112,7 +8113,7 @@ process_bb (rpo_elim &avail, basic_block bb,
                                            arg);
          if (sprime
              && sprime != arg
-             && may_propagate_copy (arg, sprime))
+             && may_propagate_copy (arg, sprime, !(e->flags & EDGE_ABNORMAL)))
            propagate_value (use_p, sprime);
        }