For multi-exit loops where the IV value used outside of the loop is
may differ depending on which exit is taken, with it being updated
prior to some exits, as per the example given below, we find that its
value is not properly reset upon entering the epilog loop if the IV is
updated prior to the exit due to the the following condition for
setting the `early_break_first_element_p' predicate in the function
`vectorizable_live_operation':
STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def
Consider, for example:
while(c[i] != 0)
{
i += 1;
if (c[i] == a)
break;
if (c[i] == b)
break;
d[i] = i;
}
return i;
If we break out of the loop on while (c[i] != 0), the condition is
satisfied.
If, however, we break on any of the other 2 further conditions, the
variable that is used outside of the loop is no longer classified as
`vect_induction_def' but rather as the `vect_internal_def' argument
passed to the phi-node via the loop latch.
Irrespective of this, in resetting the loop values in preparation for
the epilog loop, we still wish to rest its value to the zeroth value
of the BITFIELD_REF of the the relevant vector.
Therefore, we remove this condition from
`early_break_first_element_p', leaving only `all_exits_as_early_p ||
!main_exit_edge' as sufficient conditions for setting
`early_break_first_element_p'.
---
gcc/tree-vect-loop.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 3b038169c95..35fa01548df 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -10337,8 +10337,7 @@ vectorizable_live_operation (vec_info *vinfo,
stmt_vec_info stmt_info,
to the latch then we're restarting the iteration in the
scalar loop. So get the first live value. */
bool early_break_first_element_p
- = (all_exits_as_early_p || !main_exit_edge)
- && STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def;
+ = (all_exits_as_early_p || !main_exit_edge);
if (early_break_first_element_p)
{
tmp_vec_lhs = vec_lhs0;
--
2.43.0