[gcc r17-3285] tree-optimization/126862 - fix live lane extract dominance check for PHIs

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:2026474385dc23e9896577db08d963bc3a96f256

commit r17-3285-g2026474385dc23e9896577db08d963bc3a96f256
Author: Richard Biener <[email protected]>
Date:   Fri Aug 14 11:14:00 2026 +0200

    tree-optimization/126862 - fix live lane extract dominance check for PHIs
    
    We were not correctly verifying dominance of the vector definition
    with the scalar use in case of PHI use stmts.  We have to ensure
    the respective PHI edge source can reach the definition.
    
            PR tree-optimization/126862
            * tree-vect-slp.cc (vect_bb_slp_mark_live_stmts): For PHI
            uses verify dominance to the PHI use edge source.
    
            * gcc.dg/vect/bb-slp-pr126862.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c | 30 ++++++++++++++++
 gcc/tree-vect-slp.cc                        | 55 +++++++++++++++++------------
 2 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c
new file mode 100644
index 000000000000..da54b941d799
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr126862.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+#include <stdint.h>
+static uint16_t
+(safe_mod_func_uint16_t_u_u)(uint16_t ui1, uint16_t ui2 ){
+  return
+    (ui2 == 0) ?
+    ((ui1)) :
+    (ui1 % ui2);
+}
+struct a {};
+int32_t b[4][5];
+int16_t c[5];
+uint16_t d;
+int32_t *e(struct a, uint16_t, uint32_t, int32_t *, int64_t);
+uint32_t f() {
+  int32_t g[4][5];
+  for (b[3][3] = 0; b[3][3] <= 3; b[3][3]++) {
+    struct a h;
+    e(h, 0, g[2][4], &b[3][3], b[9][4]);
+  }
+}
+int32_t *e(struct a, uint16_t, uint32_t, int32_t *k, int64_t) {
+  int32_t i[4];
+  uint16_t *j = &d;
+  if (c[4] ^= safe_mod_func_uint16_t_u_u(++*j, 0), *i)
+    *j = 0;
+  return k;
+}
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index 985aa4281b31..ebddec49b912 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -9269,32 +9269,43 @@ vect_bb_slp_mark_live_stmts (bb_vec_info bb_vinfo, slp_tree node,
 	     during code-generation, simply not replacing uses for those
 	     hopefully rare cases.  */
 	  imm_use_iterator use_iter;
-	  gimple *use_stmt;
-	  stmt_vec_info use_stmt_info;
 
 	  bool live_p = false;
 	  bool can_insert = true;
-	  FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, DEF_FROM_PTR (def_p))
-	    if (!is_gimple_debug (use_stmt)
-		&& (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt))
-		    || !PURE_SLP_STMT (use_stmt_info)))
-	      {
-		live_p = true;
-		if (!last_stmt)
-		  last_stmt
-		    = (node->si ? node->si
-		       : vect_find_last_scalar_stmt_in_slp (node)->stmt);
-		if (!vect_stmt_dominates_stmt_p (last_stmt, use_stmt))
-		  {
-		    if (dump_enabled_p ())
-		      dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-				       "Cannot determine insertion place for "
-				       "lane extract of %T at node %p\n",
-				       DEF_FROM_PTR (def_p), (void *)node);
+	  use_operand_p use_p;
+	  FOR_EACH_IMM_USE_FAST (use_p, use_iter, DEF_FROM_PTR (def_p))
+	    {
+	      gimple *use_stmt = USE_STMT (use_p);
+	      stmt_vec_info use_stmt_info;
+	      if (!(!is_gimple_debug (use_stmt)
+		    && (!(use_stmt_info = bb_vinfo->lookup_stmt (use_stmt))
+			|| !PURE_SLP_STMT (use_stmt_info))))
+		continue;
+	      live_p = true;
+	      if (!last_stmt)
+		last_stmt
+		  = (node->si ? node->si
+		     : vect_find_last_scalar_stmt_in_slp (node)->stmt);
+	      if (is_a <gphi *> (use_stmt))
+		{
+		  if (!dominated_by_p (CDI_DOMINATORS,
+				       phi_arg_edge_from_use (use_p)->src,
+				       gimple_bb (last_stmt)))
 		    can_insert = false;
-		    break;
-		  }
-	      }
+		}
+	      else if (!vect_stmt_dominates_stmt_p (last_stmt, use_stmt))
+		can_insert = false;
+	      if (!can_insert)
+		{
+		  if (dump_enabled_p ())
+		    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+				     "Cannot determine insertion place for "
+				     "lane extract of %T at node %p\n",
+				     DEF_FROM_PTR (def_p), (void *)node);
+		  can_insert = false;
+		  break;
+		}
+	    }
 	  if (live_p && can_insert)
 	    {
 	      /* Only record a live stmt when we can replace all uses.  We
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.