tree-optimization/106226 - move vectorizer virtual SSA update

When we knowingly have broken virtual SSA form we need to update
it before we eventually perform slpeel manual updating which will
call delete_update_ssa.  Currently that's done on-demand but
communicating whether it's a known unavoidable case is broken
there.  The following makes that a synchronous operation but
instead of actually performing the update we instead recod the
need, clear the update SSA sub-state and force virtual renaming
at the very end of the vectorization pass.

	PR tree-optimization/106226
	* tree-vect-loop-manip.cc (vect_do_peeling): Assert that
	no SSA update is needed.  Move virtual SSA update ...
	* tree-vectorizer.cc (pass_vectorize::execute): ... here,
	via forced virtual renaming when TODO_update_ssa_only_virtuals
	is queued.
	(vect_transform_loops): Return TODO_update_ssa_only_virtuals
	when virtual SSA update is required.
	(try_vectorize_loop_1): Adjust.
	* tree-vect-stmts.cc (vectorizable_simd_clone_call): Allow
	virtual renaming if the ABI forces an aggregate return
	but the original call did not have a virtual definition.

	* gfortran.dg/pr106226.f: New testcase.
This commit is contained in:
Richard Biener 2022-07-08 10:41:59 +02:00
parent 95a234f5cb
commit cf3a120084
4 changed files with 76 additions and 9 deletions

View File

@ -0,0 +1,37 @@
! { dg-do compile }
! { dg-options "-O3 -std=legacy" }
SUBROUTINE EFTORD(DM,CHDINT,L4)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (MXPT=100, MXFRG=50, MXFGPT=MXPT*MXFRG)
DIMENSION DM(*),CHDINT(L4)
COMMON /FGRAD / DEF0,DEFT0,TORQ0
* ,ATORQ(3,MXFRG)
COMMON /CSSTV / CX,CY,CZ
* EFBTRM(MXFGPT),EFATRM2(MXFGPT),EFBTRM2(MXFGPT),
* EFDIP(3,MXFGPT),EFQAD(6,MXFGPT),
* EFOCT(10,MXFGPT),FRGNME(MXFGPT)
IF(NROOTS.EQ.5) CALL ROOT5
IF(NROOTS.EQ.6) CALL ROOT6
IF(NROOTS.GE.7) THEN
CALL ABRT
END IF
DO 403 I = 1,IJ
CHDINT(ICC)=CHDINT(ICC)-DUM*DUMY
ICC=ICC+1
403 CONTINUE
CHDINT(ICC)=CHDINT(ICC)-DUM*DUMY
DO 550 J=MINJ,MAX
LJ=LOCJ+J
IF (LI-LJ) 920,940,940
920 ID = LJ
GO TO 960
940 ID = LI
960 NN = (ID*(ID-1))/2+JD
DUM = DM(NN)
ATORQ(1,INF)=ATORQ(1,INF)-DUM*(CHDINT(ICC+1)*EFDIP(3,IC)
$ -CHDINT(ICC+2)*EFDIP(2,IC))
ICC=ICC+1
ICC=ICC+1
550 CONTINUE
END

View File

@ -2696,12 +2696,11 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
class loop *first_loop = loop;
bool irred_flag = loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP;
/* We should not have to update virtual SSA form here but some
transforms involve creating new virtual definitions which makes
updating difficult. */
gcc_assert (!need_ssa_update_p (cfun)
|| loop_vinfo->any_known_not_updated_vssa);
update_ssa (TODO_update_ssa_only_virtuals);
/* SSA form needs to be up-to-date since we are going to manually
update SSA form in slpeel_tree_duplicate_loop_to_edge_cfg and delete all
update SSA state after that, so we have to make sure to not lose any
pending update needs. */
gcc_assert (!need_ssa_update_p (cfun));
create_lcssa_for_virtual_phi (loop);

View File

@ -4247,6 +4247,14 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
if (!vec_stmt) /* transformation not required. */
{
/* When the original call is pure or const but the SIMD ABI dictates
an aggregate return we will have to use a virtual definition and
in a loop eventually even need to add a virtual PHI. That's
not straight-forward so allow to fix this up via renaming. */
if (gimple_call_lhs (stmt)
&& !gimple_vdef (stmt)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (bestn->decl))) == ARRAY_TYPE)
vinfo->any_known_not_updated_vssa = true;
STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (bestn->decl);
for (i = 0; i < nargs; i++)
if ((bestn->simdclone->args[i].arg_type

View File

@ -82,6 +82,7 @@ along with GCC; see the file COPYING3. If not see
#include "opt-problem.h"
#include "internal-fn.h"
#include "tree-ssa-sccvn.h"
#include "tree-into-ssa.h"
/* Loop or bb location, with hotness information. */
dump_user_location_t vect_location;
@ -982,7 +983,7 @@ set_uid_loop_bbs (loop_vec_info loop_vinfo, gimple *loop_vectorized_call,
/* Generate vectorized code for LOOP and its epilogues. */
static void
static unsigned
vect_transform_loops (hash_table<simduid_to_vf> *&simduid_to_vf_htab,
loop_p loop, gimple *loop_vectorized_call,
function *fun)
@ -1020,9 +1021,25 @@ vect_transform_loops (hash_table<simduid_to_vf> *&simduid_to_vf_htab,
= simduid_to_vf_data;
}
/* We should not have to update virtual SSA form here but some
transforms involve creating new virtual definitions which makes
updating difficult.
We delay the actual update to the end of the pass but avoid
confusing ourselves by forcing need_ssa_update_p () to false. */
unsigned todo = 0;
if (need_ssa_update_p (cfun))
{
gcc_assert (loop_vinfo->any_known_not_updated_vssa);
fun->gimple_df->ssa_renaming_needed = false;
todo |= TODO_update_ssa_only_virtuals;
}
gcc_assert (!need_ssa_update_p (cfun));
/* Epilogue of vectorized loop must be vectorized too. */
if (new_loop)
vect_transform_loops (simduid_to_vf_htab, new_loop, NULL, fun);
todo |= vect_transform_loops (simduid_to_vf_htab, new_loop, NULL, fun);
return todo;
}
/* Try to vectorize LOOP. */
@ -1133,7 +1150,8 @@ try_vectorize_loop_1 (hash_table<simduid_to_vf> *&simduid_to_vf_htab,
(*num_vectorized_loops)++;
/* Transform LOOP and its epilogues. */
vect_transform_loops (simduid_to_vf_htab, loop, loop_vectorized_call, fun);
ret |= vect_transform_loops (simduid_to_vf_htab, loop,
loop_vectorized_call, fun);
if (loop_vectorized_call)
{
@ -1332,6 +1350,11 @@ pass_vectorize::execute (function *fun)
if (num_vectorized_loops > 0)
{
/* We are collecting some corner cases where we need to update
virtual SSA form via the TODO but delete the queued update-SSA
state. Force renaming if we think that might be necessary. */
if (ret & TODO_update_ssa_only_virtuals)
mark_virtual_operands_for_renaming (cfun);
/* If we vectorized any loop only virtual SSA form needs to be updated.
??? Also while we try hard to update loop-closed SSA form we fail
to properly do this in some corner-cases (see PR56286). */