On Wed, Sep 18, 2013 at 10:59 PM, Xinliang David Li <davi...@google.com> wrote: > On Wed, Sep 18, 2013 at 1:23 PM, Cong Hou <co...@google.com> wrote: >> First, look as the code below. >> >> >> void foo(int* a, int* b, int n) { >> int i; >> for (i = 0; i < n; ++i) >> a[i] = *b; >> } >> >> >> This loop contains possible aliasing between a[i] and *b, and in order >> to vectorize this loop, GCC produces two versions of the loop, and >> only vectorizes the one in which there is no aliasing between a[i] and >> *b. In this version we can assert *b is a loop variant and thereby can >> hoist the load and shuffle operations outside of the loop. But the >> current implementation does not do this. >> >> If we replace *b by a stack variable then during the vectorization >> pass the load and shuffle are already hoisted. So I think we can just >> do it during the vectorization pass without passing additional >> information to other passes (e.g. pass_lim). Is it safe for us to >> assume that there is no aliasing between a variable accessed via an >> address which is a loop invariant and any other variable modified in >> the loop (the version to be vectorized)? >> > > For 0-stride read accesses, it should be safe to do. If vectorizer > does not already do this hoisting for non-aliased scalars, it might be > tricky to pass the info to the aliaser or the following LIM pass.
The vectorizer already considers *b not aliasing a[i] in the vectorized body (I've added this check) - do you say I forgot to handle it in versioning for alias? Yes, I didn't bother implementing the hoisting, it seemed less important than getting the vectorization itself done ;) (happens frequently with fortran and scalars passed by reference). Please file missed-optimization bugreports. Richard. > David > >> >> thanks, >> Cong