aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-split.cc
diff options
context:
space:
mode:
authorLewis Hyatt <lhyatt@gmail.com>2024-12-06 19:01:27 -0500
committerLewis Hyatt <lhyatt@gcc.gnu.org>2024-12-06 19:01:28 -0500
commit568b3b30218715ff0b2b8f6404fc8bce819d6153 (patch)
tree49f5c2f0c5c33286c18a5c694f996c70185aea12 /gcc/tree-ssa-loop-split.cc
parentc7fd6c4369ef1a009b40c1787ea9d2dad2cf449f (diff)
downloadgcc-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.cc7
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