From cf3a120084e94614a4917f71940325cd4b537f24 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 8 Jul 2022 10:41:59 +0200 Subject: [PATCH] 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. --- gcc/testsuite/gfortran.dg/pr106226.f | 37 ++++++++++++++++++++++++++++ gcc/tree-vect-loop-manip.cc | 11 ++++----- gcc/tree-vect-stmts.cc | 8 ++++++ gcc/tree-vectorizer.cc | 29 +++++++++++++++++++--- 4 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr106226.f diff --git a/gcc/testsuite/gfortran.dg/pr106226.f b/gcc/testsuite/gfortran.dg/pr106226.f new file mode 100644 index 00000000000..19237bc5a71 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr106226.f @@ -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 diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index d7410d7b4bd..2c2b4f7bd53 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -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); diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 3db6620dd42..01d982eea98 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -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 diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc index 53dc4520963..6ec49511d74 100644 --- a/gcc/tree-vectorizer.cc +++ b/gcc/tree-vectorizer.cc @@ -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_htab, loop_p loop, gimple *loop_vectorized_call, function *fun) @@ -1020,9 +1021,25 @@ vect_transform_loops (hash_table *&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_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). */