middle-end: thread through existing LCSSA variable for alternative exits too [PR113237]

Builing on top of the previous patch, similar to when we have a single exit if
we have a case where all exits are considered early exits and there are existing
non virtual phi then in order to maintain LCSSA we have to use the existing PHI
variables.  We can't simply clear them and just rebuild them because the order
of the PHIs in the main exit must match the original exit for when we add the
skip_epilog guard.

But the infrastructure is already in place to maintain them, we just have to use
the right value.

gcc/ChangeLog:

	PR tree-optimization/113237
	* tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg): Use
	existing LCSSA variable for exit when all exits are early break.

gcc/testsuite/ChangeLog:

	PR tree-optimization/113237
	* gcc.dg/vect/vect-early-break_98-pr113237.c: New test.
This commit is contained in:
Tamar Christina 2024-01-12 15:25:58 +00:00
parent 411de96dbf
commit 99c0a540d6
2 changed files with 27 additions and 2 deletions

View file

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-add-options vect_early_break } */
/* { dg-require-effective-target vect_early_break } */
/* { dg-require-effective-target vect_int } */
long Perl_pp_split_limit;
int Perl_block_gimme();
int Perl_pp_split() {
char strend;
long iters;
int gimme = Perl_block_gimme();
while (--Perl_pp_split_limit) {
if (gimme)
iters++;
if (strend)
break;
}
if (iters)
return 0;
}

View file

@ -1697,10 +1697,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
virtual operands we have to keep the original link. Virtual
operands don't all become the same because we'll corrupt the
vUSE chains among others. */
if (peeled_iters && !virtual_operand_p (new_arg))
if (peeled_iters)
{
tree tmp_arg = gimple_phi_result (from_phi);
if (!new_phi_args.get (tmp_arg))
/* Similar to the single exit case, If we have an existing
LCSSA variable thread through the original value otherwise
skip it and directly use the final value. */
if (tree *res = new_phi_args.get (tmp_arg))
new_arg = *res;
else if (!virtual_operand_p (new_arg))
new_arg = tmp_arg;
}