diff mbox series

tree-optimization/113494 - Fix two observed regressions with r14-8206

Message ID 20240119094219.9523C1388C@imap1.dmz-prg2.suse.org
State New
Headers show
Series tree-optimization/113494 - Fix two observed regressions with r14-8206 | expand

Commit Message

Richard Biener Jan. 19, 2024, 9:42 a.m. UTC
The following handles the situation where we lack a loop-closed
PHI for a virtual operand because a loop exit goes to a code
region not having any virtual use (an endless loop).  It also
handles the situation of edge redirection re-allocating a PHI node
in the destination block so we have to re-lookup that before
populating the new PHI argument.

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

	PR tree-optimization/113494
	* tree-vect-loop-manip.cc (slpeel_tree_duplicate_loop_to_edge_cfg):
	Handle endless loop on exit.  Handle re-allocated PHI.
---
 gcc/tree-vect-loop-manip.cc | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 983ed2e9b1f..1477906e96e 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -1629,11 +1629,17 @@  slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
 		  alt_loop_exit_block = split_edge (exit);
 		if (!need_virtual_phi)
 		  continue;
-		if (vphi_def && !vphi)
-		  vphi = create_phi_node (copy_ssa_name (vphi_def),
-					  alt_loop_exit_block);
 		if (vphi_def)
-		  add_phi_arg (vphi, vphi_def, exit, UNKNOWN_LOCATION);
+		  {
+		    if (!vphi)
+		      vphi = create_phi_node (copy_ssa_name (vphi_def),
+					      alt_loop_exit_block);
+		    else
+		      /* Edge redirection might re-allocate the PHI node
+			 so we have to rediscover it.  */
+		      vphi = get_virtual_phi (alt_loop_exit_block);
+		    add_phi_arg (vphi, vphi_def, exit, UNKNOWN_LOCATION);
+		  }
 	      }
 
 	  set_immediate_dominator (CDI_DOMINATORS, new_preheader,
@@ -1748,7 +1754,17 @@  slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop, edge loop_exit,
 		  if (virtual_operand_p (alt_arg))
 		    {
 		      gphi *vphi = get_virtual_phi (alt_loop_exit_block);
-		      alt_arg = gimple_phi_result (vphi);
+		      /* ???  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.c-torture/execute/20150611-1.c  */
+		      if (vphi)
+			alt_arg = gimple_phi_result (vphi);
 		    }
 		  edge main_e = single_succ_edge (alt_loop_exit_block);
 		  SET_PHI_ARG_DEF_ON_EDGE (to_phi, main_e, alt_arg);