aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2016-06-01 18:12:01 +0000
committerDaniel Berlin <dberlin@dberlin.org>2016-06-01 18:12:01 +0000
commite846c9dc525046699ab993c8a4bd3d6e5e6c11f2 (patch)
tree9ff08cfea026350ce7da258569817f49d586a248 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parent9efec1f11d432d9e82b3ee36e41a74e7906aafc0 (diff)
downloadllvm-e846c9dc525046699ab993c8a4bd3d6e5e6c11f2.zip
llvm-e846c9dc525046699ab993c8a4bd3d6e5e6c11f2.tar.gz
llvm-e846c9dc525046699ab993c8a4bd3d6e5e6c11f2.tar.bz2
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 llvm-svn: 271415
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp38
1 files changed, 36 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index cfb7354..b136c08 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -834,8 +834,42 @@ static AliasResult aliasSameBasePointerGEPs(const GEPOperator *GEP1,
// 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) {
+ 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