[llvm] r271415 - Claim NoAlias if two GEPs index different fields of the same struct
Ahmed Bougacha via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 1 12:59:11 PDT 2016
On Wed, Jun 1, 2016 at 11:12 AM, Daniel Berlin via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: dannyb
> Date: Wed Jun 1 13:12:01 2016
> New Revision: 271415
>
> URL: http://llvm.org/viewvc/llvm-project?rev=271415&view=rev
> Log:
> Claim NoAlias if two GEPs index different fields of the same struct
>
> Patch by Taewook Oh
>
> Summary: Patch for Bug 27478. Make BasicAliasAnalysis claims NoAlias if two GEPs index different fields of the same structure.
>
> Reviewers: hfinkel, dberlin
>
> Subscribers: dberlin, mcrosier, llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D20665
>
> Added:
> llvm/trunk/test/Analysis/BasicAA/noalias-structure.ll
> Modified:
> llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
> llvm/trunk/test/Transforms/LoopVectorize/global_alias.ll
>
> Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=271415&r1=271414&r2=271415&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original)
> +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Jun 1 13:12:01 2016
> @@ -834,8 +834,42 @@ static AliasResult aliasSameBasePointerG
> // Try to determine whether GEP1 and GEP2 index through arrays, into structs,
> // such that the struct field accesses provably cannot alias.
> // We also need at least two indices (the pointer, and the struct field).
> - if (GEP1->getNumIndices() != GEP2->getNumIndices() ||
> - GEP1->getNumIndices() < 2)
> + if (GEP1->getNumIndices() < 2)
> + return MayAlias;
> +
> + // If both GEP1 and GEP2 have the inbounds keyword but index different fields
> + // of the same struct, they do not alias.
> + if (GEP1->isInBounds() && GEP2->isInBounds()) {
> + auto Opi1 = GEP1->op_begin() + 1;
> + auto Opi2 = GEP2->op_begin() + 1;
> + auto Ope1 = GEP1->op_end();
> + auto Ope2 = GEP2->op_end();
> +
> + SmallVector<Value *, 8> IntermediateIndices;
> + ConstantInt *C1 = nullptr;
> + ConstantInt *C2 = nullptr;
> + while (Opi1 != Ope1 && Opi2 != Ope2 &&
> + (C1 = dyn_cast<ConstantInt>(*Opi1)) &&
> + (C2 = dyn_cast<ConstantInt>(*Opi2))) {
> + if (C1 == C2) {
Hey Dan, Taewook,
I know this has been reverted, but this comparison might be a problem
when the GEPs have differently typed indices. Vedant fixed a similar
bug in the below code in r269197.
HTH,
-Ahmed
> + IntermediateIndices.push_back(C1);
> + ++Opi1;
> + ++Opi2;
> + } else {
> + // Both GEPs share the same pointer operand and access through the same
> + // indices up to this point, but now they are having different index
> + // values. At this point, if the indexed type is a StructType, this means
> + // that two GEPs are for two different fields in the same structure.
> + auto *Ty = GetElementPtrInst::getIndexedType(
> + GEP1->getSourceElementType(), IntermediateIndices);
> + if (isa<StructType>(Ty))
> + return NoAlias;
> + break;
> + }
> + }
> + }
> +
> + if (GEP1->getNumIndices() != GEP2->getNumIndices())
> return MayAlias;
>
> // If we don't know the size of the accesses through both GEPs, we can't
>
More information about the llvm-commits
mailing list