The compiler has detected a potential backward dependency between loop iterations that could make vectorization unsafe. The compiler will not auto-vectorize a loop if there are any data values for which vectorization could lead to an incorrect result. Two common examples are:
1. reading from an array element after writing to it in a preceding iteration;
2. writing data using pointers that might be aliased to other data that is also being accessed in the loop. (That is, the data might overlap).
subroutine d_15046_1(a,b,n1,n2,offset) implicit none real, intent(inout), dimension(:) :: a real, intent(in ), dimension(:) :: b integer :: i integer, intent(in) :: n1, n2, offset do i=n1,n2 a(i) = a(i+offset) + log(b(i)) enddo end subroutine d_15046_1
> ifort -c -vec-report2 d_15046_1.f90
d_15046_1.f90(8): (col. 3) remark: loop was not vectorized: existence of vector dependence
module mymod real, pointer, contiguous, dimension(:) :: a, b, c, d, e end module mymod subroutine d_15046_2 use mymod implicit none integer :: i do i=1,10000 e(i) = a(i) + b(i)**2/c(i)**3 + d(i)**4 enddo end subroutine d_15046_2
> ifort -c -vec-report2 d_15046_2.f90
d_15046_2.f90(11): (col. 13) remark: loop was not vectorized: existence of vector dependence
Try to remove the dependency between loop iterations.
1. Vectorization may be unsafe if offset<0. For example, if offset=-1, each iteration depends on the result of the preceding one, so it is not possible to simultaneously execute multiple iterations correctly using SIMD instructions. If you know that offset >= 0, you may tell the compiler that it is safe to vectorize by inserting a directive immediately before the loop. Either the OpenMP 4.0 directive !$OMP SIMD or the Intel compiler directives !DIR$ IVDEP or !DIR$ SIMD may be used. For this example, you would see either a "LOOP WAS VECTORIZED" or a "SIMD LOOP WAS VECTORIZED" message.
2. There could be a read/write dependency making vectorization unsafe if there is overlap between the data pointed to by the output pointer e and data pointed to by one of the other pointers. For a small number of pointers, the compiler may be able to test for dependencies at run-time, but as the number of pointers increases, the cost becomes prohibitive and the compiler does not vectorize. If you know that there is no overlap (sometimes known as pointer aliasing) between the data pointed to by the output pointer and the data pointed to by any of the input pointers, you may tell the compiler that it is safe to vectorize by using one of the directives described above. You could also do this by using the construct DO CONCURRENT from the Fortran 2008 language standard, which tells the compiler that it is safe to execute the iterations of the loop in any order.