Hi All,

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.

Bootstrapped Regtested on aarch64-none-linux-gnu and
x86_64-pc-linux-gnu no issues.

Ok for master?

Thanks,
Tamar

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.

--- inline copy of patch -- 
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 
0000000000000000000000000000000000000000..5c339fa7a348fac5527bbbf456a535da96b5c1ed
--- /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 
190df9ec7741fd05aa0b9abe150baf06b2ca9a57..eed2268e9bae7e7ad36d13da03e0b54eab26ef6f
 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;




-- 
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 
0000000000000000000000000000000000000000..5c339fa7a348fac5527bbbf456a535da96b5c1ed
--- /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 
190df9ec7741fd05aa0b9abe150baf06b2ca9a57..eed2268e9bae7e7ad36d13da03e0b54eab26ef6f
 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;



Reply via email to