aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2024-02-08 10:43:13 +0000
committerTamar Christina <tamar.christina@arm.com>2024-02-08 10:43:13 +0000
commit3f69db1812106cb5bab203e17a60300ac51cdc68 (patch)
tree5bd81c7f1c003fe3f32d1a118b07b9a3dde8f778
parente515d813f080fb4c4e70d3c7b01815a909893688 (diff)
downloadgcc-3f69db1812106cb5bab203e17a60300ac51cdc68.zip
gcc-3f69db1812106cb5bab203e17a60300ac51cdc68.tar.gz
gcc-3f69db1812106cb5bab203e17a60300ac51cdc68.tar.bz2
middle-end: don't cache restart_loop in vectorizable_live_operations [PR113808]
There's a bug in vectorizable_live_operation that restart_loop is defined outside the loop. This variable is supposed to indicate whether we are doing a first or last index reduction. The problem is that by defining it outside the loop it becomes dependent on the order we visit the USE/DEFs. In the given example, the loop isn't PEELED, but we visit the early exit uses first. This then sets the boolean to true and it can't get to false again. So when we visit the main exit we still treat it as an early exit for that SSA name. This cleans it up and renames the variables to something that's hopefully clearer to their intention. gcc/ChangeLog: PR tree-optimization/113808 * tree-vect-loop.cc (vectorizable_live_operation): Don't cache the value cross iterations. gcc/testsuite/ChangeLog: PR tree-optimization/113808 * gfortran.dg/vect/vect-early-break_1-PR113808.f90: New test.
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f9021
-rw-r--r--gcc/tree-vect-loop.cc5
2 files changed, 23 insertions, 3 deletions
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90 b/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90
new file mode 100644
index 0000000..5c339fa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/vect/vect-early-break_1-PR113808.f90
@@ -0,0 +1,21 @@
+! { dg-add-options vect_early_break }
+! { dg-require-effective-target vect_early_break }
+! { dg-require-effective-target vect_long_long }
+! { dg-additional-options "-fopenmp-simd" }
+
+! { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } }
+
+program main
+ integer :: n, i,k
+ n = 11
+ do i = 1, n,2
+ !$omp simd lastprivate(k)
+ do k = 1, i + 41
+ if (k > 11 + 41 .or. k < 1) error stop
+ end do
+ end do
+ if (k /= 53) then
+ print *, k, 53
+ error stop
+ endif
+end
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index 190df9e..eed2268 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -10950,7 +10950,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info,
did. For the live values we want the value at the start of the iteration
rather than at the end. */
edge main_e = LOOP_VINFO_IV_EXIT (loop_vinfo);
- bool restart_loop = LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo);
+ bool all_exits_as_early_p = LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo);
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
if (!is_gimple_debug (use_stmt)
&& !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
@@ -10966,8 +10966,7 @@ vectorizable_live_operation (vec_info *vinfo, stmt_vec_info stmt_info,
/* For early exit where the exit is not in the BB that leads
to the latch then we're restarting the iteration in the
scalar loop. So get the first live value. */
- restart_loop = restart_loop || !main_exit_edge;
- if (restart_loop
+ if ((all_exits_as_early_p || !main_exit_edge)
&& STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
{
tmp_vec_lhs = vec_lhs0;