[RFC] GCC vectorizer misses an opportunity to hoist loop invariant load after loop versioning.
Richard Biener
richard.guenther@gmail.com
Fri Sep 20 07:57:00 GMT 2013
On Wed, Sep 18, 2013 at 10:59 PM, Xinliang David Li <davidxl@google.com> wrote:
> On Wed, Sep 18, 2013 at 1:23 PM, Cong Hou <congh@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
More information about the Gcc
mailing list