]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/115528 - fix vect alignment analysis for outer loop vect
authorRichard Biener <rguenther@suse.de>
Fri, 21 Jun 2024 11:19:26 +0000 (13:19 +0200)
committerRichard Biener <rguenther@suse.de>
Mon, 24 Jun 2024 11:28:26 +0000 (13:28 +0200)
For outer loop vectorization of a data reference in the inner loop
we have to look at both steps to see if they preserve alignment.

What is special for this testcase is that the outer loop step is
one element but the inner loop step four and that we now use SLP
and the vectorization factor is one.

PR tree-optimization/115528
* tree-vect-data-refs.cc (vect_compute_data_ref_alignment):
Make sure to look at both the inner and outer loop step
behavior.

* gfortran.dg/vect/pr115528.f: New testcase.

gcc/testsuite/gfortran.dg/vect/pr115528.f [new file with mode: 0644]
gcc/tree-vect-data-refs.cc

diff --git a/gcc/testsuite/gfortran.dg/vect/pr115528.f b/gcc/testsuite/gfortran.dg/vect/pr115528.f
new file mode 100644 (file)
index 0000000..764a4b9
--- /dev/null
@@ -0,0 +1,27 @@
+! { dg-additional-options "-fno-inline" }
+
+      subroutine init(COEF1,FORM1,AA)
+      double precision COEF1,X
+      double complex FORM1
+      double precision AA(4,4)
+      COEF1=0
+      FORM1=0
+      AA=0
+      end
+      subroutine curr(HADCUR)
+      double precision COEF1
+      double complex HADCUR(4),FORM1
+      double precision AA(4,4)
+      call init(COEF1,FORM1,AA)
+      do i = 1,4
+         do j = 1,4
+            HADCUR(I)=
+     $         HADCUR(I)+CMPLX(COEF1)*FORM1*AA(I,J)
+         end do
+      end do
+      end
+      program test
+        double complex HADCUR(4)
+        hadcur=0
+        call curr(hadcur)
+      end
index ae237407672c670bbf9801ca0e29668fefda7371..959e127c385383d5bf3b7b5d9c7716b603ec620b 100644 (file)
@@ -1356,42 +1356,43 @@ vect_compute_data_ref_alignment (vec_info *vinfo, dr_vec_info *dr_info,
       step_preserves_misalignment_p = true;
     }
 
-  /* In case the dataref is in an inner-loop of the loop that is being
-     vectorized (LOOP), we use the base and misalignment information
-     relative to the outer-loop (LOOP).  This is ok only if the misalignment
-     stays the same throughout the execution of the inner-loop, which is why
-     we have to check that the stride of the dataref in the inner-loop evenly
-     divides by the vector alignment.  */
-  else if (nested_in_vect_loop_p (loop, stmt_info))
-    {
-      step_preserves_misalignment_p
-       = (DR_STEP_ALIGNMENT (dr_info->dr) % vect_align_c) == 0;
-
-      if (dump_enabled_p ())
-       {
-         if (step_preserves_misalignment_p)
-           dump_printf_loc (MSG_NOTE, vect_location,
-                            "inner step divides the vector alignment.\n");
-         else
-           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                            "inner step doesn't divide the vector"
-                            " alignment.\n");
-       }
-    }
-
-  /* Similarly we can only use base and misalignment information relative to
-     an innermost loop if the misalignment stays the same throughout the
-     execution of the loop.  As above, this is the case if the stride of
-     the dataref evenly divides by the alignment.  */
   else
     {
+      /* We can only use base and misalignment information relative to
+        an innermost loop if the misalignment stays the same throughout the
+        execution of the loop.  As above, this is the case if the stride of
+        the dataref evenly divides by the alignment.  */
       poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
       step_preserves_misalignment_p
-       = multiple_p (DR_STEP_ALIGNMENT (dr_info->dr) * vf, vect_align_c);
+       = multiple_p (drb->step_alignment * vf, vect_align_c);
 
       if (!step_preserves_misalignment_p && dump_enabled_p ())
        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                         "step doesn't divide the vector alignment.\n");
+
+      /* In case the dataref is in an inner-loop of the loop that is being
+        vectorized (LOOP), we use the base and misalignment information
+        relative to the outer-loop (LOOP).  This is ok only if the
+        misalignment stays the same throughout the execution of the
+        inner-loop, which is why we have to check that the stride of the
+        dataref in the inner-loop evenly divides by the vector alignment.  */
+      if (step_preserves_misalignment_p
+         && nested_in_vect_loop_p (loop, stmt_info))
+       {
+         step_preserves_misalignment_p
+           = (DR_STEP_ALIGNMENT (dr_info->dr) % vect_align_c) == 0;
+
+         if (dump_enabled_p ())
+           {
+             if (step_preserves_misalignment_p)
+               dump_printf_loc (MSG_NOTE, vect_location,
+                                "inner step divides the vector alignment.\n");
+             else
+               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                                "inner step doesn't divide the vector"
+                                " alignment.\n");
+           }
+       }
     }
 
   unsigned int base_alignment = drb->base_alignment;