[gcc r17-3502] tree-optimization/126979 - fix SLP pattern representative checks

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

commit r17-3502-gc3c082917c72ccf2928a39dc5e54a65245f46568
Author: Richard Biener <[email protected]>
Date:   Fri Aug 21 10:17:02 2026 +0200

    tree-optimization/126979 - fix SLP pattern representative checks
    
    The following makes sure to special-case VEC_PERM nodes when
    comparing complex nodes.  When they still had a representative
    we ended up comparing random operations (oops).
    
            PR tree-optimization/126979
            * tree-vect-slp-patterns.cc (compatible_complex_nodes_p):
            Special case VEC_PERM nodes.

Diff:
---
 gcc/tree-vect-slp-patterns.cc | 113 ++++++++++++++++++++++--------------------
 1 file changed, 60 insertions(+), 53 deletions(-)

diff --git a/gcc/tree-vect-slp-patterns.cc b/gcc/tree-vect-slp-patterns.cc
index 2ff7ce2699fd..bf9efacf161f 100644
--- a/gcc/tree-vect-slp-patterns.cc
+++ b/gcc/tree-vect-slp-patterns.cc
@@ -763,70 +763,77 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache,
       return true;
     }
 
-  auto a_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (a));
-  auto b_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (b));
-
-  if (gimple_code (a_stmt) != gimple_code (b_stmt))
-    return false;
-
-  /* code, children, type, externals, loads, constants  */
-  if (gimple_num_args (a_stmt) != gimple_num_args (b_stmt))
-    return false;
-
-  /* At this point, a and b are known to be the same gimple operations.  */
-  if (is_gimple_call (a_stmt))
-    {
-	if (!compatible_calls_p (dyn_cast <gcall *> (a_stmt),
-				 dyn_cast <gcall *> (b_stmt), false))
-	  return false;
-    }
-  else if (!is_gimple_assign (a_stmt))
+  if (SLP_TREE_PERMUTE_P (a) != SLP_TREE_PERMUTE_P (b))
     return false;
+  else if (SLP_TREE_PERMUTE_P (a))
+    ;
   else
     {
-      tree_code acode = gimple_assign_rhs_code (a_stmt);
-      tree_code bcode = gimple_assign_rhs_code (b_stmt);
-      if ((acode == REALPART_EXPR || acode == IMAGPART_EXPR)
-	  && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR)
-	  && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1 (a_stmt), 0),
-			      TREE_OPERAND (gimple_assign_rhs1 (b_stmt), 0)))
-	return true;
-
-      if (acode != bcode)
+      auto a_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (a));
+      auto b_stmt = STMT_VINFO_STMT (SLP_TREE_REPRESENTATIVE (b));
+
+      if (gimple_code (a_stmt) != gimple_code (b_stmt))
 	return false;
-    }
 
-  if (!STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a))
-      || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b)))
-    {
-      for (unsigned i = 0; i < gimple_num_args (a_stmt); i++)
+      /* code, children, type, externals, loads, constants  */
+      if (gimple_num_args (a_stmt) != gimple_num_args (b_stmt))
+	return false;
+
+      /* At this point, a and b are known to be the same gimple operations.  */
+      if (is_gimple_call (a_stmt))
 	{
-	  tree t1 = gimple_arg (a_stmt, i);
-	  tree t2 = gimple_arg (b_stmt, i);
-	  if (TREE_CODE (t1) != TREE_CODE (t2))
+	  if (!compatible_calls_p (dyn_cast <gcall *> (a_stmt),
+				   dyn_cast <gcall *> (b_stmt), false))
 	    return false;
+	}
+      else if (!is_gimple_assign (a_stmt))
+	return false;
+      else
+	{
+	  tree_code acode = gimple_assign_rhs_code (a_stmt);
+	  tree_code bcode = gimple_assign_rhs_code (b_stmt);
+	  if ((acode == REALPART_EXPR || acode == IMAGPART_EXPR)
+	      && (bcode == REALPART_EXPR || bcode == IMAGPART_EXPR)
+	      && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1 (a_stmt), 0),
+				  TREE_OPERAND (gimple_assign_rhs1 (b_stmt), 0)))
+	    return true;
+
+	  if (acode != bcode)
+	    return false;
+	}
 
-	  /* If SSA name then we will need to inspect the children
-	     so we can punt here.  */
-	  if (TREE_CODE (t1) == SSA_NAME)
-	    continue;
-
-	  if (!operand_equal_p (t1, t2, 0))
+      if (!STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a))
+	  || !STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b)))
+	{
+	  for (unsigned i = 0; i < gimple_num_args (a_stmt); i++)
+	    {
+	      tree t1 = gimple_arg (a_stmt, i);
+	      tree t2 = gimple_arg (b_stmt, i);
+	      if (TREE_CODE (t1) != TREE_CODE (t2))
+		return false;
+
+	      /* If SSA name then we will need to inspect the children
+		 so we can punt here.  */
+	      if (TREE_CODE (t1) == SSA_NAME)
+		continue;
+
+	      if (!operand_equal_p (t1, t2, 0))
+		return false;
+	    }
+	}
+      else
+	{
+	  auto dr1 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a));
+	  auto dr2 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b));
+	  /* Don't check the last dimension as that's checked by the lineary
+	     checks.  This check is also much stricter than what we need
+	     because it doesn't consider loading from adjacent elements
+	     in the same struct as loading from the same base object.
+	     But for now, I'll play it safe.  */
+	  if (!same_data_refs (dr1, dr2, 1))
 	    return false;
 	}
     }
-  else
-    {
-      auto dr1 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (a));
-      auto dr2 = STMT_VINFO_DATA_REF (SLP_TREE_REPRESENTATIVE (b));
-      /* Don't check the last dimension as that's checked by the lineary
-	 checks.  This check is also much stricter than what we need
-	 because it doesn't consider loading from adjacent elements
-	 in the same struct as loading from the same base object.
-	 But for now, I'll play it safe.  */
-      if (!same_data_refs (dr1, dr2, 1))
-	return false;
-    }
 
   for (unsigned i = 0; i < SLP_TREE_CHILDREN (a).length (); i++)
     {
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.