From 39a27bb01aa223ce89946f0a4de6b60c4c0b03d2 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 29 Sep 2020 15:02:47 +0200 Subject: [PATCH] tree-optimization/97241 - fix ICE in reduction vectorization The following moves an ad-hoc attempt at discovering the SLP node for a stmt to the place where we can find it in lock-step when we find the stmt itself. 2020-09-29 Richard Biener PR tree-optimization/97241 * tree-vect-loop.c (vectorizable_reduction): Move finding the SLP node for the reduction stmt to a better place. * gcc.dg/vect/pr97241.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr97241.c | 19 +++++++++++++++++++ gcc/tree-vect-loop.c | 17 +++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr97241.c diff --git a/gcc/testsuite/gcc.dg/vect/pr97241.c b/gcc/testsuite/gcc.dg/vect/pr97241.c new file mode 100644 index 00000000000..d4be8f60940 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr97241.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 --param max-loop-header-insns=2" } */ + +short int *ev; +int l4; + +short int +a7 (void) +{ + short int uo = ev[0], ie = uo; + + for (int kp = 0; kp < l4; kp += 4) + { + uo += ev[kp + 1]; + ie += ev[kp]; + } + + return uo + ie; +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index f1d6bdde412..ce5d95d7277 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6357,12 +6357,14 @@ vectorizable_reduction (loop_vec_info loop_vinfo, gphi *reduc_def_phi = as_a (phi_info->stmt); /* Verify following REDUC_IDX from the latch def leads us back to the PHI - and compute the reduction chain length. */ + and compute the reduction chain length. Discover the real + reduction operation stmt on the way (stmt_info and slp_for_stmt_info). */ tree reduc_def = PHI_ARG_DEF_FROM_EDGE (reduc_def_phi, loop_latch_edge (loop)); unsigned reduc_chain_length = 0; bool only_slp_reduc_chain = true; stmt_info = NULL; + slp_tree slp_for_stmt_info = slp_node ? slp_node_instance->root : NULL; while (reduc_def != PHI_RESULT (reduc_def_phi)) { stmt_vec_info def = loop_vinfo->lookup_def (reduc_def); @@ -6405,6 +6407,8 @@ vectorizable_reduction (loop_vec_info loop_vinfo, stmt_info = vdef; reduc_def = gimple_op (vdef->stmt, 1 + STMT_VINFO_REDUC_IDX (vdef)); reduc_chain_length++; + if (!stmt_info && slp_node) + slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; } /* PHIs should not participate in patterns. */ gcc_assert (!STMT_VINFO_RELATED_STMT (phi_info)); @@ -6491,17 +6495,6 @@ vectorizable_reduction (loop_vec_info loop_vinfo, The last use is the reduction variable. In case of nested cycle this assumption is not true: we use reduc_index to record the index of the reduction variable. */ - /* ??? To get at invariant/constant uses on the SLP node we have to - get to it here, slp_node is still the reduction PHI. */ - slp_tree slp_for_stmt_info = NULL; - if (slp_node) - { - slp_for_stmt_info = slp_node_instance->root; - /* And then there's reduction chain with a conversion ... */ - if (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) != stmt_info) - slp_for_stmt_info = SLP_TREE_CHILDREN (slp_for_stmt_info)[0]; - gcc_assert (SLP_TREE_REPRESENTATIVE (slp_for_stmt_info) == stmt_info); - } slp_tree *slp_op = XALLOCAVEC (slp_tree, op_type); /* We need to skip an extra operand for COND_EXPRs with embedded comparison. */ -- 2.30.2