Cause:
1. More than one exit point in the loop. A loop must have a single entry and a single exit point. Multiple exit points in a loop can generate this message.
2. This remark is also reported when C++ exception handling and OpenMP critical construct are used in a SIMD loop.
3. Third example demonstrates a case where compiler has no way to narrow down which function is passed as a function parameter. When this passed function is invoked inside the loop body, this vectorization diagnostic is generated.
4. Another case is documented which demonstrates how a loop body which is seen as a non-standard loop for vectorization can be made a suitable candidate for vectorization just by enabling the ANSI alias rule during compilation using compiler option -ansi-alias.
Below are examples for all the scenarios.
Examples:
void 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; } }
>icl -c -Qvec-report2 example1.cpp
Intel® C++ Compiler for applications running on Intel® 64, Version 12.0.0.063 Build 20100721
Copyright (C) 1985-2010 Intel Corporation. All rights reserved.
example1.cpp
example1.cpp(4) (col. 9): remark: loop was not vectorized: nonstandard loop is not a vectorization candidate.
#include <stdio.h> #include <stdlib.h> #define N 1000 int vecmsg_testcore001() { #pragma omp simd for (int i=0; i<N; i++) { try { printf ( "throw exception 11n" ); throw 11; } catch (int t) { printf ( "caught exception %dn", t ); if ( t != 11 ) { #pragma omp critical { printf ( "TEST FAILEDn" ); exit( 0); }; }; } }; printf ( "TEST PASSEDn"); exit(0); }
>icl -c -Qvec-report2 example2.cpp -Qopenmp -EHsc
example2.cpp(7): (col. 4) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
example2.cpp(7): (col. 4) warning #13379: loop was not vectorized with "simd"
#include<iostream> int a[100]; int b[100]; int g(int i, int y){ return b[i]+y; } __declspec(noinline) void doit1(int x(int,int), int y){ int i; #pragma parallel for(i = 0; i < 100; i++) a[i] = x(i,y); }
$ icpc -c -vec-report2 example3.cc
example3.cc(12): (col. 1) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
typedef struct PREV_PR_o { float *px_l1; float *px_l2; float *px_r1; float *px_r2; float *pz_t1; float *pz_t2; float *pz_b1; float *pz_b2; } PREV_PR_o; typedef struct PREV_PR_o *PREV_PR_p; typedef struct PROPAG_PARMS { int nx; int nz; float dx; float dz; float dt; float dom_freq; float rec_length; int first_snap; int freq_snap; int nx_l; int nz_l; int nx_l_beg; int nz_l_beg; int nx_l_end; int nz_l_end; int output; } PROPAG_PARMS; typedef struct PROPAG_PARMS *PROPAG_PARMS_p; int FD_Scheme( PROPAG_PARMS_p model, int t_step, float **p0, PREV_PR_p prev ) { int return_value = 0; int ixm; int i; ixm = model->nx_l + 2; for( i=0 ; i<model->nz_l ; i++ ) { prev->px_l1[i] = p0[3][i+2]; prev->px_l2[i] = p0[4][i+2]; prev->px_r1[i] = p0[ixm-2][i+2]; prev->px_r2[i] = p0[ixm-3][i+2]; } return return_value; }
$ icpc -c -vec-report2 example4.c
example4.c.c(45): (col. 2) remark: loop was not vectorized: nonstandard loop is not a vectorization candidate
Resolution Status:
1. For the first example, change the loop to have a single entry and a single exit point.
2. For the second example, change the loop not to have C++ exception handling and OpenMP criticial sections
3. No resolution unless we can let compiler know during compile time, which function will be called within the loop body
4. By using compiler option -ansi-alias and #pragma simd on the loop will vectorize this loop. By mentioning the compiler option -ansi-alias compiler option, the compiler will stick ISO C standard aliasing rules. Since this loop's bound is an integer and all the updates inside the loop body is on float data type, the compiler can be certain that the loop's bound is not changing inside the loop body (-ansi-alias assertion implies type-based disambiguation). Now with -ansi-alias option, the following vectorization report is generated which states there is a data dependency:
$ icpc test.c -c -vec-report2 -ansi-alias
rakesh1.c(45): (col. 2) remark: loop was not vectorized: existence of vector dependence
Since the developer is aware in this case that there is no data dependency in the loop across iterations, the developer can annotate the loop with #pragma simd (compiler neglects the heuristic information which suggest there is a data dependency) and the loop gets vectorized:
$ icpc test.c -c -vec-report2 -ansi-alias
test.c(45): (col. 2) remark: SIMD LOOP WAS VECTORIZED