mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 23:29:51 +00:00
Teach BasicAA to return PartialAlias in cases where both pointers
are pointing to the same object, one pointer is accessing the entire object, and the other is access has a non-zero size. This prevents TBAA from kicking in and saying NoAlias in such cases. llvm-svn: 123775
This commit is contained in:
parent
c0ff5356d4
commit
df668227fb
@ -97,38 +97,53 @@ static bool isEscapeSource(const Value *V) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isObjectSmallerThan - Return true if we can prove that the object specified
|
||||
/// by V is smaller than Size.
|
||||
static bool isObjectSmallerThan(const Value *V, uint64_t Size,
|
||||
const TargetData &TD) {
|
||||
/// getObjectSize - Return the size of the object specified by V, or
|
||||
/// UnknownSize if unknown.
|
||||
static uint64_t getObjectSize(const Value *V, const TargetData &TD) {
|
||||
const Type *AccessTy;
|
||||
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
||||
if (!GV->hasDefinitiveInitializer())
|
||||
return false;
|
||||
return AliasAnalysis::UnknownSize;
|
||||
AccessTy = GV->getType()->getElementType();
|
||||
} else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
|
||||
if (!AI->isArrayAllocation())
|
||||
AccessTy = AI->getType()->getElementType();
|
||||
else
|
||||
return false;
|
||||
return AliasAnalysis::UnknownSize;
|
||||
} else if (const CallInst* CI = extractMallocCall(V)) {
|
||||
if (!isArrayMalloc(V, &TD))
|
||||
// The size is the argument to the malloc call.
|
||||
if (const ConstantInt* C = dyn_cast<ConstantInt>(CI->getArgOperand(0)))
|
||||
return (C->getZExtValue() < Size);
|
||||
return false;
|
||||
return C->getZExtValue();
|
||||
return AliasAnalysis::UnknownSize;
|
||||
} else if (const Argument *A = dyn_cast<Argument>(V)) {
|
||||
if (A->hasByValAttr())
|
||||
AccessTy = cast<PointerType>(A->getType())->getElementType();
|
||||
else
|
||||
return false;
|
||||
return AliasAnalysis::UnknownSize;
|
||||
} else {
|
||||
return false;
|
||||
return AliasAnalysis::UnknownSize;
|
||||
}
|
||||
|
||||
if (AccessTy->isSized())
|
||||
return TD.getTypeAllocSize(AccessTy) < Size;
|
||||
return false;
|
||||
return TD.getTypeAllocSize(AccessTy);
|
||||
return AliasAnalysis::UnknownSize;
|
||||
}
|
||||
|
||||
/// isObjectSmallerThan - Return true if we can prove that the object specified
|
||||
/// by V is smaller than Size.
|
||||
static bool isObjectSmallerThan(const Value *V, uint64_t Size,
|
||||
const TargetData &TD) {
|
||||
uint64_t ObjectSize = getObjectSize(V, TD);
|
||||
return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize < Size;
|
||||
}
|
||||
|
||||
/// isObjectSize - Return true if we can prove that the object specified
|
||||
/// by V has size Size.
|
||||
static bool isObjectSize(const Value *V, uint64_t Size,
|
||||
const TargetData &TD) {
|
||||
uint64_t ObjectSize = getObjectSize(V, TD);
|
||||
return ObjectSize != AliasAnalysis::UnknownSize && ObjectSize == Size;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1142,6 +1157,14 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
|
||||
if (Result != MayAlias) return Result;
|
||||
}
|
||||
|
||||
// If both pointers are pointing into the same object and one of them
|
||||
// accesses is accessing the entire object, then the accesses must
|
||||
// overlap in some way.
|
||||
if (TD && O1 == O2)
|
||||
if ((V1Size != UnknownSize && isObjectSize(O1, V1Size, *TD)) ||
|
||||
(V2Size != UnknownSize && isObjectSize(O2, V2Size, *TD)))
|
||||
return PartialAlias;
|
||||
|
||||
return AliasAnalysis::alias(Location(V1, V1Size, V1TBAAInfo),
|
||||
Location(V2, V2Size, V2TBAAInfo));
|
||||
}
|
||||
|
33
test/Analysis/BasicAA/full-store-partial-alias.ll
Normal file
33
test/Analysis/BasicAA/full-store-partial-alias.ll
Normal file
@ -0,0 +1,33 @@
|
||||
; RUN: opt -S -tbaa -basicaa -gvn < %s | grep {ret i32 %}
|
||||
; RUN: opt -S -tbaa -gvn < %s | grep {ret i32 0}
|
||||
; rdar://8875631
|
||||
|
||||
; BasicAA should notice that the store stores to the entire %u object,
|
||||
; so the %tmp5 load is PartialAlias with the store and suppress TBAA.
|
||||
; Without BasicAA, TBAA should say that %tmp5 is NoAlias with the store.
|
||||
|
||||
target datalayout = "e-p:64:64:64"
|
||||
|
||||
%union.anon = type { double }
|
||||
|
||||
@u = global %union.anon { double -2.500000e-01 }, align 8
|
||||
@endianness_test = global i64 1, align 8
|
||||
|
||||
define i32 @signbit(double %x) nounwind {
|
||||
entry:
|
||||
%u = alloca %union.anon, align 8
|
||||
%tmp9 = getelementptr inbounds %union.anon* %u, i64 0, i32 0
|
||||
store double %x, double* %tmp9, align 8, !tbaa !0
|
||||
%tmp2 = load i32* bitcast (i64* @endianness_test to i32*), align 8, !tbaa !3
|
||||
%idxprom = sext i32 %tmp2 to i64
|
||||
%tmp4 = bitcast %union.anon* %u to [2 x i32]*
|
||||
%arrayidx = getelementptr inbounds [2 x i32]* %tmp4, i64 0, i64 %idxprom
|
||||
%tmp5 = load i32* %arrayidx, align 4, !tbaa !3
|
||||
%tmp5.lobit = lshr i32 %tmp5, 31
|
||||
ret i32 %tmp5.lobit
|
||||
}
|
||||
|
||||
!0 = metadata !{metadata !"double", metadata !1}
|
||||
!1 = metadata !{metadata !"omnipotent char", metadata !2}
|
||||
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
|
||||
!3 = metadata !{metadata !"int", metadata !1}
|
Loading…
Reference in New Issue
Block a user