This diagnostic message is emitted from Intel(R) C++ Compiler 15.0 and above
remark #15520: loop was not vectorized: loop with multiple exits cannot be vectorized unless it meets search loop idiom criteria
Cause:
More than one exit point in the loop. In most cases, a loop must have a single entry and a single exit point in order to be auto-vectorized.
Example:
int no_vec(float a[], float b[], float c[]) { int i = 0.; while (i < 100) { a[i] = b[i] * c[i]; // this is a data-dependent exit condition: if (a[i] < 0.0) break; ++i; } return i; }
$ icc -c -qopt-report-file=stderr -qopt-report-phase=vec d15520.c
...
LOOP BEGIN at d15520.c(4,9)
remark #15520: loop was not vectorized: loop with multiple exits cannot be vectorized unless it meets search loop idiom criteria [ d15520.c(7,11) ]
LOOP END
===========================================================================
Workarounds:
Simple search loops are recognized by the compiler and can be vectorized if they are written as a "for" loop, e.g.:
int foo(float *a, int n){ int i; for (i=0;i<n;i++){ if (a[i] == 0){ break; } } return i; }
$ icc -c -qopt-report-file=stderr -qopt-report-phase=vec d15524.c
...
LOOP BEGIN at d15524.c(3,3)
remark #15300: LOOP WAS VECTORIZED
LOOP END
More complicated loops such as the original example can be vectorized using a "for" loop preceded by an OpenMP SIMD directive along with an early_exit clause:
int no_vec(float a[], float b[], float c[]) { int i; #pragma omp simd early_exit for(i=0; i<100; i++) { a[i] = b[i] * c[i]; // this is a data-dependent exit condition: if (a[i] < 0.0) break; } return i; }
$ icc -c -qopt-report-file=stderr -qopt-report-phase=vec d15520_b.c
...
LOOP BEGIN at d15520_b.c(5,13)
remark #15301: OpenMP SIMD LOOP WAS VECTORIZED
LOOP END