tree-optimization/113659 - early exit vectorization and missing VUSE

The following handles the case of the main exit going to a path without
virtual use and handles it similar to the alternate exit handling.

	PR tree-optimization/113659
	* tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
	Handle main exit without virtual use.

	* gcc.dg/pr113659.c: New testcase.
This commit is contained in:
Richard Biener 2024-01-30 09:42:08 +01:00
parent 87ed338808
commit 4c2169d2f4
2 changed files with 31 additions and 3 deletions

View file

@ -0,0 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fno-tree-sra" } */
/* { dg-additional-options "-msse4.1" { target { x86_64-*-* i?86-*-* } } } */
struct Foo {
int *ptr;
};
int Baz(struct Foo first)
{
while (first.ptr)
if (*first.ptr++)
return 0;
__builtin_unreachable ();
}

View file

@ -1708,9 +1708,23 @@ slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
LC PHI node to feed the merge PHI. */
tree *res;
if (virtual_operand_p (new_arg))
/* Use the existing virtual LC SSA from exit block. */
new_arg = gimple_phi_result
(get_virtual_phi (main_loop_exit_block));
{
/* Use the existing virtual LC SSA from exit block. */
gphi *vphi = get_virtual_phi (main_loop_exit_block);
/* ??? When the exit yields to a path without
any virtual use we can miss a LC PHI for the
live virtual operand. Simply choosing the
one live at the start of the loop header isn't
correct, but we should get here only with
early-exit vectorization which will move all
defs after the main exit, so leave a temporarily
wrong virtual operand in place. This happens
for gcc.dg/pr113659.c. */
if (vphi)
new_arg = gimple_phi_result (vphi);
else
new_arg = gimple_phi_result (from_phi);
}
else if ((res = new_phi_args.get (new_arg)))
new_arg = *res;
else