The compiler is able to vectorize loops containing pointers
if it can determine that the loop is safe. Both array references
and pointer references in loops are analyzed to see if there is
any vector access to memory. In some cases, the compiler creates
a run-time test, and executes a vector version or scalar version
of the loop depending on the result of the test.
Often, function arguments are passed as pointers. If several
pointer variables are passed to a function, it is possible that
pointing to overlapping sections of memory can occur. Often, at runtime,
this is not the case but the compiler always follows the safe method
and avoids optimizing loops that involve pointers appearing on both
the left and right sides of an assignment operator. For example,
consider the following function.
void func (int *pa, int *pb, int x)
for (i = 0; i < 100; i++)
*(pa + i) = *(pb + i) + x;
In this example, if
in memory in a way that causes results from one loop pass to feed
back to a subsequent loop pass, then vectorization of the loop can
give incorrect results. If the function is called with the following
arguments, vectorization might be ambiguous:
func (a, a-1);
The compiler performs a runtime test to see if pointer aliasing
occurs. If pointer aliasing does not occur, it executes a vectorized
version of the code. If pointer aliasing occurs, the original nonvectorized
code executes instead. This leads to a small cost in runtime efficiency
and code size.
In practice, it is very rare for data dependence to exist
because of function arguments. Programs that pass overlapping pointers
are very hard to understand and debug, apart from any vectorization
In the example above, adding
sufficient to avoid the runtime test.