https://gcc.gnu.org/g:9d775818e30e73c28ef5743ca8b6ed4ae8ef1383

commit r16-5866-g9d775818e30e73c28ef5743ca8b6ed4ae8ef1383
Author: Tamar Christina <[email protected]>
Date:   Wed Dec 3 14:10:36 2025 +0000

    vect: fix ICE when duplicate dummy IV PHIs are still in CFG [PR122969]
    
    All the no-options result in duplicate PHI nodes that use the same values 
just
    have different RHS
    
    >>> p debug (loop->header)
    
        <bb 21> [local count: 958878292]:
        # a.2_29 = PHI <0(18), _34(25)>
        # a_lsm.8_31 = PHI <0(18), _34(25)>
        _34 = a.2_29 + -1;
        if (_34 != 1)
          goto <bb 25>; [94.50%]
        else
          goto <bb 32>; [5.50%]
    
        $11 = void
    
    >>> p debug (update_bb)
    
        <bb 33> [local count: 958878292]:
        # a.2_6 = PHI <a_lsm.8_36(32), _41(34)>
        # a_lsm.8_18 = PHI <a_lsm.8_36(32), _41(34)>
        _41 = a.2_6 + -1;
        if (_41 != 1)
          goto <bb 34>; [94.50%]
        else
          goto <bb 26>; [5.50%]
    
        $12 = void
    
    So one of the PHIs is completely useless. But that makes the update loop 
visit
    the PHI twice, but the first time we already updated them so we end up with 
a
    non-SSA_NAME there.
    
    In the old code we'd just re-update the PHI with the same statement. So 
I've put
    back that code as fallback.  I'm almost 100% sure you can't get here with 
any
    divergent PHI as an inviant has to be a variable before we rewrite it.  But 
as
    I'm not 100% sure I've put the update fallback instead of skipping the 
update.
    
    gcc/ChangeLog:
    
            PR tree-optimization/122969
            * tree-vect-loop-manip.cc (vect_update_ivs_after_vectorizer): handle
            non-ssa name IV var args.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/122969
            * gcc.dg/vect/pr122969.c: New test.

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr122969.c | 16 ++++++++++++++++
 gcc/tree-vect-loop-manip.cc          | 13 +++++++++----
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr122969.c 
b/gcc/testsuite/gcc.dg/vect/pr122969.c
new file mode 100644
index 000000000000..47699fd0a1d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr122969.c
@@ -0,0 +1,16 @@
+/* { dg-add-options vect_early_break } */
+/* { dg-require-effective-target vect_early_break } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-w -O3 -fno-tree-dominator-opts -fno-code-hoisting 
-fno-tree-pre -fno-tree-dce" } */
+
+/* { dg-final { scan-tree-dump "loop vectorized" "vect" } } */
+
+int a, b;
+int main() {
+  while (a)
+    for (a = 0; a != 1; a--)
+      if (b)
+        break;
+  return 0;
+}
+
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 18af6a1811ac..cdcfc8d0015d 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -2439,10 +2439,15 @@ vect_update_ivs_after_vectorizer (loop_vec_info 
loop_vinfo,
       gimple *use_stmt;
       use_operand_p use_p;
       tree ic_var = PHI_ARG_DEF_FROM_EDGE (phi1, update_e);
-      FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, ic_var)
-       if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
-         FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-           SET_USE (use_p, ni_name);
+      if (TREE_CODE (ic_var) == SSA_NAME)
+       {
+         FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, ic_var)
+           if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
+             FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+               SET_USE (use_p, ni_name);
+       }
+      else
+       adjust_phi_and_debug_stmts (phi1, update_e, ni_name);
     }
 }

Reply via email to