Re: [PATCH 2/2] avoid SLP_TREE_REPRESENTATIVE for permutes

Richard Biener <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
On Tue, 18 Aug 2026, Richard Biener wrote:

> The following consistently keeps SLP_TREE_REPRESENTATIVE cleared
> for VEC_PERM_EXPR SLP nodes and verifies this.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, now also
> testing on aarch64-linux-gnu.

aarch64-linux-gnu testing showed I missed two spots in SLP pattern
detection.

The following is what I pushed.

From 233480c124149585b60631b2323a49d409d3f344 Mon Sep 17 00:00:00 2001
From: Richard Biener <[email protected]>
Date: Tue, 18 Aug 2026 13:19:30 +0200
Subject: [PATCH] avoid SLP_TREE_REPRESENTATIVE for permutes
To: [email protected]

The following consistently keeps SLP_TREE_REPRESENTATIVE cleared
for VEC_PERM_EXPR SLP nodes and verifies this.

	* tree-vect-slp.cc (vect_slp_build_two_operator_nodes):
	Set SLP_TREE_REPRESENTATIVE to NULL for the permute nodes.
	(vect_build_slp_tree_2): Likewise.
	(vect_build_slp_store_interleaving): Likewise.
	(vect_lower_load_permutations): Likewise.
	(vect_optimize_slp_pass::get_result_with_layout): Likewise.
	(vect_cse_slp_node_parts): Deal with NULL SLP_TREE_REPRESENTATIVE
	for VEC_PERM nodes.
	(vect_slp_analyze_node_operations_1): Assert permute nodes
	do not have SLP_TREE_REPRESENTATIVE set.
	* tree-vect-slp-patterns.cc (complex_pattern::build): Adjust.
	(vect_build_swap_evenodd_node): Do not set SLP_TREE_REPRESENTATIVE.
	(vect_build_combine_node): Likewise.
---
 gcc/tree-vect-slp-patterns.cc |  7 +------
 gcc/tree-vect-slp.cc          | 18 ++++++++++--------
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc
index 8a03a25475d..2ff7ce2699f 100644
--- a/gcc/tree-vect-slp-patterns.cc
+++ b/gcc/tree-vect-slp-patterns.cc
@@ -277,7 +277,6 @@ vect_build_swap_evenodd_node (slp_tree node)
   SLP_TREE_CHILDREN (vnode).quick_push (node);
   SLP_TREE_REF_COUNT (vnode) = 1;
   SLP_TREE_LANES (vnode) = SLP_TREE_LANES (node);
-  SLP_TREE_REPRESENTATIVE (vnode) = SLP_TREE_REPRESENTATIVE (node);
   SLP_TREE_REF_COUNT (node)++;
   return vnode;
 }
@@ -535,7 +534,7 @@ complex_pattern::build (vec_info *vinfo)
   FOR_EACH_VEC_ELT (this->m_workset, ix, node)
     {
       /* Calculate the location of the statement in NODE to replace.  */
-      stmt_info = SLP_TREE_REPRESENTATIVE (node);
+      stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
       gimple* old_stmt = STMT_VINFO_STMT (stmt_info);
       tree lhs_old_stmt = gimple_get_lhs (old_stmt);
       tree type = TREE_TYPE (lhs_old_stmt);
@@ -1006,10 +1005,6 @@ vect_build_combine_node (slp_tree even, slp_tree odd, slp_tree rep)
 
   SLP_TREE_LANES (vnode) = SLP_TREE_LANES (rep);
   gcc_assert (perm.length () == SLP_TREE_LANES (vnode));
-  /* Representation is set to that of the current node as the vectorizer
-     can't deal with VEC_PERMs with no representation, as would be the
-     case with invariants.  */
-  SLP_TREE_REPRESENTATIVE (vnode) = SLP_TREE_REPRESENTATIVE (rep);
   SLP_TREE_VECTYPE (vnode) = SLP_TREE_VECTYPE (rep);
   return vnode;
 }
diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
index b2f14e6528a..5b602bcfc71 100644
--- a/gcc/tree-vect-slp.cc
+++ b/gcc/tree-vect-slp.cc
@@ -2095,8 +2095,7 @@ vect_slp_build_two_operator_nodes (slp_tree perm, tree vectype,
   SLP_TREE_CODE (perm) = VEC_PERM_EXPR;
   SLP_TREE_VECTYPE (perm) = vectype;
   SLP_TREE_LANES (perm) = group_size;
-  /* ???  We should set this NULL but that's not expected.  */
-  SLP_TREE_REPRESENTATIVE (perm) = oper1;
+  SLP_TREE_REPRESENTATIVE (perm) = NULL;
   SLP_TREE_LANE_PERMUTATION (perm) = lperm;
   SLP_TREE_CHILDREN (perm).quick_push (child1);
   SLP_TREE_CHILDREN (perm).quick_push (child2);
@@ -2309,6 +2308,7 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
 		      SLP_TREE_CODE (node) = VEC_PERM_EXPR;
 		      SLP_TREE_CHILDREN (node).safe_push (unperm_load);
 		      SLP_TREE_LANE_PERMUTATION (node) = lperm;
+		      SLP_TREE_REPRESENTATIVE (node) = NULL;
 		      load_permutation.release ();
 		      return node;
 		    }
@@ -2386,6 +2386,7 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node,
       SLP_TREE_LANE_PERMUTATION (node) = lperm;
       SLP_TREE_VECTYPE (node) = vectype;
       SLP_TREE_CHILDREN (node).quick_push (vnode);
+      SLP_TREE_REPRESENTATIVE (node) = NULL;
       return node;
     }
   /* When discovery reaches an associatable operation see whether we can
@@ -3316,6 +3317,7 @@ fail:
 	      SLP_TREE_VECTYPE (pnode) = vectype;
 	      SLP_TREE_CHILDREN (pnode).quick_push (child);
 	      SLP_TREE_CHILDREN (pnode).quick_push (child);
+	      SLP_TREE_REPRESENTATIVE (pnode) = NULL;
 	      lane_permutation_t& perm = SLP_TREE_LANE_PERMUTATION (pnode);
 	      children.safe_push (pnode);
 
@@ -3345,6 +3347,7 @@ fail:
       SLP_TREE_CODE (node) = VEC_PERM_EXPR;
       SLP_TREE_CHILDREN (node).quick_push (one);
       SLP_TREE_CHILDREN (node).quick_push (two);
+      SLP_TREE_REPRESENTATIVE (node) = NULL;
       enum tree_code code0 = ERROR_MARK;
       enum tree_code ocode = ERROR_MARK;
       if (gassign *stmt = dyn_cast <gassign *> (stmts[0]->stmt))
@@ -4108,9 +4111,7 @@ vect_build_slp_store_interleaving (vec<slp_tree> &rhs_nodes,
       SLP_TREE_VECTYPE (perm) = SLP_TREE_VECTYPE (node);
       perm->max_nunits = max_nunits;
       SLP_TREE_LANES (perm) = group_size;
-      /* ???  We should set this NULL but that's not expected.  */
-      SLP_TREE_REPRESENTATIVE (perm)
-	= SLP_TREE_REPRESENTATIVE (SLP_TREE_CHILDREN (rhs_nodes[0])[l]);
+      SLP_TREE_REPRESENTATIVE (perm) = NULL;
       for (unsigned j = 0; j < rhs_nodes.length (); ++j)
 	{
 	  SLP_TREE_CHILDREN (perm)
@@ -5918,7 +5919,6 @@ vect_lower_load_permutations (loop_vec_info loop_vinfo,
 	  SLP_TREE_LANE_PERMUTATION (p) = perm;
 	  SLP_TREE_VECTYPE (p) = SLP_TREE_VECTYPE (load);
 	  SLP_TREE_LANES (p) = perm.length ();
-	  SLP_TREE_REPRESENTATIVE (p) = SLP_TREE_REPRESENTATIVE (load);
 	  /* ???  As we have scalar stmts for this intermediate permute we
 	     could CSE it via bst_map but we do not want to pick up
 	     another SLP node with a load permutation.  We instead should
@@ -5937,6 +5937,7 @@ vect_lower_load_permutations (loop_vec_info loop_vinfo,
       SLP_TREE_LANE_PERMUTATION (load) = final_perm;
       SLP_TREE_CHILDREN (load).create (1);
       SLP_TREE_CHILDREN (load).quick_push (l0);
+      SLP_TREE_REPRESENTATIVE (load) = NULL;
     }
 }
 
@@ -8077,7 +8078,6 @@ vect_optimize_slp_pass::get_result_with_layout (slp_tree node,
 	  if (to_layout_i != 0)
 	    vect_slp_permute (m_perms[to_layout_i], stmts, true);
 	}
-      SLP_TREE_REPRESENTATIVE (result) = SLP_TREE_REPRESENTATIVE (node);
       SLP_TREE_LANES (result) = num_lanes;
       SLP_TREE_VECTYPE (result) = SLP_TREE_VECTYPE (node);
       result->vertex = -1;
@@ -8659,7 +8659,8 @@ vect_cse_slp_node_parts (hash_set<slp_tree> &visited,
       && SLP_TREE_SCALAR_STMTS (node)[0]
       /* Avoid touching loads which need care with load permutations
 	 and specialities like load-lane representations.  */
-      && !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (node)))
+      && (SLP_TREE_PERMUTE_P (node)
+	  || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (node))))
     for (slp_tree cand
 	 : part_starts[gimple_uid (SLP_TREE_SCALAR_STMTS (node)[0]->stmt)])
       /* ???  There is a possible ordering/optimality problem in that
@@ -8960,6 +8961,7 @@ vect_slp_analyze_node_operations_1 (vec_info *vinfo, slp_tree node,
   /* Handle purely internal nodes.  */
   if (SLP_TREE_PERMUTE_P (node))
     {
+      gcc_checking_assert (!SLP_TREE_REPRESENTATIVE (node));
       if (!vectorizable_slp_permutation (vinfo, NULL, node, cost_vec))
 	return false;
 
-- 
2.51.0
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.