https://gcc.gnu.org/g:b9457ed89cd84c609482a6d808e1bbdbe2cd84ac

commit r16-5039-gb9457ed89cd84c609482a6d808e1bbdbe2cd84ac
Author: Richard Biener <[email protected]>
Date:   Mon Nov 3 13:59:36 2025 +0100

    Fix unsafe stmt modifications in FOR_EACH_IMM_USE_STMT
    
    The following fixes path isolation changing the immediate use list of
    an SSA name that is currently iterated over via FOR_EACH_IMM_USE_STMT.
    This happens when it duplicates a BB within this and creates/modifies
    stmts that contain SSA uses of the name and calls update_stmt which
    re-builds SSA operands, including removal of SSA uses and re-inserting
    them.  This is not safe as that might cause missed iterated uses but
    more importantly could cause the 'next' use to be removed.
    
    For the case in question the fix is to collect interesting uses in
    a vec and do the processing outside of the FOR_EACH_IMM_USE_STMT
    iteration.
    
            * gimple-ssa-isolate-paths.cc (check_loadstore): Set
            the volatile flag on the stmt manually.
            (find_implicit_erroneous_behavior): Move code transform
            outside of FOR_EACH_IMM_USE_STMT iteration.

Diff:
---
 gcc/gimple-ssa-isolate-paths.cc | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/gcc/gimple-ssa-isolate-paths.cc b/gcc/gimple-ssa-isolate-paths.cc
index ca1daf1d1683..ffa04d150524 100644
--- a/gcc/gimple-ssa-isolate-paths.cc
+++ b/gcc/gimple-ssa-isolate-paths.cc
@@ -56,7 +56,7 @@ check_loadstore (gimple *stmt, tree op, tree, void *data)
     {
       TREE_THIS_VOLATILE (op) = 1;
       TREE_SIDE_EFFECTS (op) = 1;
-      update_stmt (stmt);
+      gimple_set_has_volatile_ops (stmt, true);
       return true;
     }
   return false;
@@ -762,6 +762,7 @@ find_implicit_erroneous_behavior (void)
 
              /* We've got a NULL PHI argument.  Now see if the
                 PHI's result is dereferenced within BB.  */
+             auto_vec <gimple *, 4> uses_in_bb;
              FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
                {
                  /* We only care about uses in BB.  Catching cases in
@@ -774,18 +775,23 @@ find_implicit_erroneous_behavior (void)
                    ? gimple_location (use_stmt)
                    : phi_arg_loc;
 
-                 if (stmt_uses_name_in_undefined_way (use_stmt, lhs, loc)
-                     && (duplicate || can_duplicate_block_p (bb)))
+                 if (stmt_uses_name_in_undefined_way (use_stmt, lhs, loc))
                    {
-                     duplicate = isolate_path (bb, duplicate, e,
-                                               use_stmt, lhs, false);
-
-                     /* When we remove an incoming edge, we need to
-                        reprocess the Ith element.  */
-                     next_i = i;
-                     cfg_altered = true;
+                     if (!can_duplicate_block_p (bb))
+                       break;
+                     uses_in_bb.safe_push (use_stmt);
                    }
                }
+             for (gimple *use_stmt : uses_in_bb)
+               {
+                 duplicate = isolate_path (bb, duplicate, e,
+                                           use_stmt, lhs, false);
+
+                 /* When we remove an incoming edge, we need to
+                    reprocess the Ith element.  */
+                 next_i = i;
+                 cfg_altered = true;
+               }
            }
        }
     }

Reply via email to