[llvm-dev] Not able to vectorize struct members

Ryan Taylor via llvm-dev llvm-dev at lists.llvm.org
Thu Jul 15 10:24:02 PDT 2021


So it looks like AA is being too conservative in aliasSameBasePointerGEPs.

For example:
#define N 10
struct foo {
  float a[N];//[N];
  float b[N];
};

void compute(struct foo *p )
{
  for (int i = 0; i < N; i++) {
      p->a[i] += 0.1f * p->b[i];
  }
}

vectorizes.

There is this code:

if (GEP1->getNumIndices() != GEP2->getNumIndices() ||
      GEP1->getNumIndices() < 2)
  {
    errs()<<"1\n";
    return MayAlias;
  }

which appears to return MayAlias anytime the numder of indices don't equal
each other, why? This doesn't seem right.

Seems like this is being overly conservative. Anytime any GEPs have the
same base pointer with different indices this is going to return MayAlias.

Thanks,

Ryan







On Thu, Jul 15, 2021 at 9:19 AM Ryan Taylor <ryta1203 at gmail.com> wrote:

> I see Roman has commented on the ticket. The issue is alias analysis it
> looks like, we have a partial fix in place in BasicAliasAnalysis.cpp:
>
>     unsigned MinNumIndex = std::min(GEP1->getNumIndices(),
>                                     GEP2->getNumIndices());
>     if (MinNumIndex < 2)
>       return MayAlias;
>     SmallVector<Value *, 8> IntermediateIndices;
>     IntermediateIndices.push_back(GEP1->getOperand(1));
>     // Note,
>     // 1. The index to struct field can only be literal constant.
>     // 2. So far all the struct field indexes are the same respectively.
>     // 3. The array indexes could be different, but they don't matter here.
>     // 4. The types should be the same, say, different array indexes don't
>     //    matter, and the struct indexes be the same respectively.
>     // If current type is StructType, and the pair of corresponding indexes
>     // are not equal, NoAlias
>     for (unsigned i = 1; i != MinNumIndex - 1; ++i) {
>       if (isa<StructType>(GetElementPtrInst::getIndexedType(
>               GEP1->getSourceElementType(), IntermediateIndices))) {
>         ConstantInt *C1 = dyn_cast<ConstantInt>(GEP1->getOperand(i + 1));
>         ConstantInt *C2 = dyn_cast<ConstantInt>(GEP2->getOperand(i + 1));
>         if (C1 && C2 && C1->getSExtValue() != C2->getSExtValue())
>           return NoAlias;
>       }
>       IntermediateIndices.push_back(GEP1->getOperand(i + 1));
>     }
>   }
>   // Note that we fall back the original logic here, there are still some
> thing
>   // not covered like p->a[2].x v.s. p->a[1].x.b[2]
>
> but this seems to break some cases and isn't generalized.
>
> -Ryan
>
> On Thu, Jul 15, 2021 at 5:05 AM Simon Pilgrim via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> I've reported this here: https://bugs.llvm.org/show_bug.cgi?id=51103
>> On 15/07/2021 04:04, Ryan Taylor via llvm-dev wrote:
>>
>> Given a test case:
>>
>> #define N 10
>> struct foo {
>>   float a[N][N];
>>   float b[N];
>> };
>>
>> void compute(struct foo *p)
>> {
>>   for (int i = 0; i < N; i++) {
>>     for (int j = 0; j < N; j++) {
>>       p->a[i][j] += 0.1f * p->b[i];
>>     }
>>   }
>> }
>>
>> LLVM isn't able to vectorize this code. I'm not sure what the issue is
>> here as it seems to vectorize this code:
>>
>> #define N 10
>> struct foo {
>>   float a[N];
>>   float b[N];
>> };
>>
>> void compute(struct foo *p)
>> {
>>   for (int i = 0; i < N; i++) {
>>       p->a[i] += 0.1f * p->b[i];
>>   }
>> }
>>
>> Is this a known issue?
>>
>> -Ryan
>>
>> _______________________________________________
>> LLVM Developers mailing listllvm-dev at lists.llvm.orghttps://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210715/f35454b9/attachment.html>


More information about the llvm-dev mailing list