diff options
author | Lewis Hyatt <lhyatt@gmail.com> | 2024-12-06 19:01:27 -0500 |
---|---|---|
committer | Lewis Hyatt <lhyatt@gcc.gnu.org> | 2024-12-06 19:01:28 -0500 |
commit | 568b3b30218715ff0b2b8f6404fc8bce819d6153 (patch) | |
tree | 49f5c2f0c5c33286c18a5c694f996c70185aea12 /gcc/tree-ssa-loop-split.cc | |
parent | c7fd6c4369ef1a009b40c1787ea9d2dad2cf449f (diff) | |
download | gcc-568b3b30218715ff0b2b8f6404fc8bce819d6153.zip gcc-568b3b30218715ff0b2b8f6404fc8bce819d6153.tar.gz gcc-568b3b30218715ff0b2b8f6404fc8bce819d6153.tar.bz2 |
middle-end: Handle resized PHI nodes in loop_version()
While testing upcoming support for 64-bit location_t, I came across some
test failures on sparc (32-bit) that trigger when location_t is changed to
be 64-bit. The reason is that several call sites that make use of
loop_version() for performing loop optimizations assume that a gphi*
obtained prior to calling loop_version() will remain valid afterwards, but
this is not the case for a PHI that needs to be resized. It doesn't happen
usually, because PHI nodes usually have room for at least 4 arguments and
this is usually more than are needed, but this is not guaranteed.
Fix the affected callers by avoiding the assumption that a PHI node pointer
remains valid. For most cases, this is done by remembering instead the
gphi->result pointer, which contains a pointer back to the PHI node that is
kept up to date when the PHI is moved to a new address.
gcc/ChangeLog:
* tree-parloops.cc (struct reduction_info): Store the result of the
reduction PHI rather than the PHI itself.
(reduction_info::reduc_phi): New member function.
(reduction_hasher::equal): Adapt to the change in struct reduction_info.
(reduction_phi): Likewise.
(initialize_reductions): Likewise.
(create_call_for_reduction_1): Likewise.
(transform_to_exit_first_loop_alt): Likewise.
(transform_to_exit_first_loop): Likewise.
(build_new_reduction): Likewise.
(set_reduc_phi_uids): Likewise.
(try_create_reduction_list): Likewise.
* tree-ssa-loop-split.cc (split_loop): Remember the PHI result
variable so that the PHI can be found in case it is resized and move
to a new address.
* tree-vect-loop-manip.cc (vect_loop_versioning): After calling
loop_version(), fix up stored PHI pointers in case they have
changed.
* tree-vectorizer.cc (vec_info::resync_stmt_addr): New function.
* tree-vectorizer.h (vec_info::resync_stmt_addr): Declare.
Diffstat (limited to 'gcc/tree-ssa-loop-split.cc')
-rw-r--r-- | gcc/tree-ssa-loop-split.cc | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/gcc/tree-ssa-loop-split.cc b/gcc/tree-ssa-loop-split.cc index 48d153d..a64066a 100644 --- a/gcc/tree-ssa-loop-split.cc +++ b/gcc/tree-ssa-loop-split.cc @@ -622,6 +622,7 @@ split_loop (class loop *loop1) gphi *phi = find_or_create_guard_phi (loop1, guard_iv, &iv); if (!phi) continue; + const tree phi_result = gimple_phi_result (phi); gcond *guard_stmt = as_a<gcond *> (*gsi_last_bb (bbs[i])); tree guard_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop1)); @@ -703,6 +704,12 @@ split_loop (class loop *loop1) profile_probability::very_likely (), true); gcc_assert (loop2); + + /* The phi address may have changed due to being resized in + loop_version (), so reobtain it. */ + phi = as_a<gphi *> (SSA_NAME_DEF_STMT (phi_result)); + gcc_checking_assert (gimple_bb (phi) == loop1->header); + /* Correct probability of edge cond_bb->preheader_of_loop2. */ single_pred_edge (loop_preheader_edge (loop2)->src)->probability |