tree-optimization/116241 - ICE with SLP condition reduction

Message ID 20240806104814.4998713770@imap1.dmz-prg2.suse.org
State Committed
Commit 31efd46ad8a16aa671f4502816b6b1f9946027ae
Headers
Series tree-optimization/116241 - ICE with SLP condition reduction |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

Richard Biener Aug. 6, 2024, 10:48 a.m. UTC
  When there's a conversion in front of a SLP condition reduction the
code following the reduc-idx SLP chain fails because it assumes
there's only COND_EXPRs.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/116241
	* tree-vect-loop.cc (vect_create_epilog_for_reduction): Handle
	non-COND_EXPR nodes in SLP reduction chain following.

	* g++.dg/vect/pr116241.cc: New testcase.
---
 gcc/testsuite/g++.dg/vect/pr116241.cc | 13 +++++++++++++
 gcc/tree-vect-loop.cc                 | 15 +++++++++------
 2 files changed, 22 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/vect/pr116241.cc
  

Patch

diff --git a/gcc/testsuite/g++.dg/vect/pr116241.cc b/gcc/testsuite/g++.dg/vect/pr116241.cc
new file mode 100644
index 00000000000..7ab1ade2533
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr116241.cc
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+short var_27;
+long test_var_5;
+int test_var_6;
+void test(short arr_11[][4][24])
+{
+  for (bool i_6 = 0;;)
+    for (int i_7; i_7;)
+      for (int i_8; i_8 < test_var_5; i_8 += 1)
+        var_27 *= test_var_6 && arr_11[2][1][i_8];
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 856ce491c3e..6456220cdc9 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6075,6 +6075,7 @@  vect_create_epilog_for_reduction (loop_vec_info loop_vinfo,
 	  while (cond_node != slp_node_instance->reduc_phis)
 	    {
 	      stmt_vec_info cond_info = SLP_TREE_REPRESENTATIVE (cond_node);
+	      int slp_reduc_idx;
 	      if (gimple_assign_rhs_code (cond_info->stmt) == COND_EXPR)
 		{
 		  gimple *vec_stmt
@@ -6083,13 +6084,15 @@  vect_create_epilog_for_reduction (loop_vec_info loop_vinfo,
 		  ccompares.safe_push
 		    (std::make_pair (gimple_assign_rhs1 (vec_stmt),
 				     STMT_VINFO_REDUC_IDX (cond_info) == 2));
-		}
-	      /* ???  We probably want to have REDUC_IDX on the SLP node?
-		 We have both three and four children COND_EXPR nodes
-		 dependent on whether the comparison is still embedded
-		 as GENERIC.  So work backwards.  */
-	      int slp_reduc_idx = (SLP_TREE_CHILDREN (cond_node).length () - 3
+		  /* ???  We probably want to have REDUC_IDX on the SLP node?
+		     We have both three and four children COND_EXPR nodes
+		     dependent on whether the comparison is still embedded
+		     as GENERIC.  So work backwards.  */
+		  slp_reduc_idx = (SLP_TREE_CHILDREN (cond_node).length () - 3
 				   + STMT_VINFO_REDUC_IDX (cond_info));
+		}
+	      else
+		slp_reduc_idx = STMT_VINFO_REDUC_IDX (cond_info);
 	      cond_node = SLP_TREE_CHILDREN (cond_node)[slp_reduc_idx];
 	    }
 	}