[AA] Split up LocationSize::unknown()

Currently, we have some confusion in the codebase regarding the
meaning of LocationSize::unknown(): Some parts (including most of
BasicAA) assume that LocationSize::unknown() only allows accesses
after the base pointer. Some parts (various callers of AA) assume
that LocationSize::unknown() allows accesses both before and after
the base pointer (but within the underlying object).

This patch splits up LocationSize::unknown() into
LocationSize::afterPointer() and LocationSize::beforeOrAfterPointer()
to make this completely unambiguous. I tried my best to determine
which one is appropriate for all the existing uses.

The test changes in cs-cs.ll in particular illustrate a previously
clearly incorrect AA result: We were effectively assuming that
argmemonly functions were only allowed to access their arguments
after the passed pointer, but not before it. I'm pretty sure that
this was not intentional, and it's certainly not specified by
LangRef that way.

Differential Revision: https://reviews.llvm.org/D91649
This commit is contained in:
Nikita Popov 2020-11-17 20:11:09 +01:00
parent 668da8c361
commit 4df8efce80
36 changed files with 179 additions and 130 deletions

View File

@ -407,7 +407,8 @@ public:
/// A convenience wrapper around the primary \c alias interface.
AliasResult alias(const Value *V1, const Value *V2) {
return alias(V1, LocationSize::unknown(), V2, LocationSize::unknown());
return alias(MemoryLocation::getBeforeOrAfter(V1),
MemoryLocation::getBeforeOrAfter(V2));
}
/// A trivial helper function to check to see if the specified pointers are
@ -424,8 +425,8 @@ public:
/// A convenience wrapper around the \c isNoAlias helper interface.
bool isNoAlias(const Value *V1, const Value *V2) {
return isNoAlias(MemoryLocation(V1, LocationSize::unknown()),
MemoryLocation(V2, LocationSize::unknown()));
return isNoAlias(MemoryLocation::getBeforeOrAfter(V1),
MemoryLocation::getBeforeOrAfter(V2));
}
/// A trivial helper function to check to see if the specified pointers are
@ -447,8 +448,7 @@ public:
/// A convenience wrapper around the primary \c pointsToConstantMemory
/// interface.
bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
return pointsToConstantMemory(MemoryLocation(P, LocationSize::unknown()),
OrLocal);
return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
}
/// @}

View File

@ -302,7 +302,7 @@ private:
/// The maximum size of the dereferences of the pointer.
///
/// May be UnknownSize if the sizes are unknown.
LocationSize Size = LocationSize::unknown();
LocationSize Size = LocationSize::afterPointer();
/// The AA tags associated with dereferences of the pointer.
///
/// The members may be null if there are no tags or conflicting tags.

View File

@ -64,10 +64,11 @@ class VAArgInst;
// None.
class LocationSize {
enum : uint64_t {
Unknown = ~uint64_t(0),
BeforeOrAfterPointer = ~uint64_t(0),
AfterPointer = BeforeOrAfterPointer - 1,
MapEmpty = BeforeOrAfterPointer - 2,
MapTombstone = BeforeOrAfterPointer - 3,
ImpreciseBit = uint64_t(1) << 63,
MapEmpty = Unknown - 1,
MapTombstone = Unknown - 2,
// The maximum value we can represent without falling back to 'unknown'.
MaxValue = (MapTombstone - 1) & ~ImpreciseBit,
@ -81,7 +82,11 @@ class LocationSize {
constexpr LocationSize(uint64_t Raw, DirectConstruction): Value(Raw) {}
static_assert(Unknown & ImpreciseBit, "Unknown is imprecise by definition.");
static_assert(AfterPointer & ImpreciseBit,
"AfterPointer is imprecise by definition.");
static_assert(BeforeOrAfterPointer & ImpreciseBit,
"BeforeOrAfterPointer is imprecise by definition.");
public:
// FIXME: Migrate all users to construct via either `precise` or `upperBound`,
// to make it more obvious at the callsite the kind of size that they're
@ -90,12 +95,12 @@ public:
// Since the overwhelming majority of users of this provide precise values,
// this assumes the provided value is precise.
constexpr LocationSize(uint64_t Raw)
: Value(Raw > MaxValue ? Unknown : Raw) {}
: Value(Raw > MaxValue ? AfterPointer : Raw) {}
static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
static LocationSize precise(TypeSize Value) {
if (Value.isScalable())
return unknown();
return afterPointer();
return precise(Value.getFixedSize());
}
@ -104,17 +109,25 @@ public:
if (LLVM_UNLIKELY(Value == 0))
return precise(0);
if (LLVM_UNLIKELY(Value > MaxValue))
return unknown();
return afterPointer();
return LocationSize(Value | ImpreciseBit, Direct);
}
static LocationSize upperBound(TypeSize Value) {
if (Value.isScalable())
return unknown();
return afterPointer();
return upperBound(Value.getFixedSize());
}
constexpr static LocationSize unknown() {
return LocationSize(Unknown, Direct);
/// Any location after the base pointer (but still within the underlying
/// object).
constexpr static LocationSize afterPointer() {
return LocationSize(AfterPointer, Direct);
}
/// Any location before or after the base pointer (but still within the
/// underlying object).
constexpr static LocationSize beforeOrAfterPointer() {
return LocationSize(BeforeOrAfterPointer, Direct);
}
// Sentinel values, generally used for maps.
@ -131,20 +144,24 @@ public:
if (Other == *this)
return *this;
if (!hasValue() || !Other.hasValue())
return unknown();
if (Value == BeforeOrAfterPointer || Other.Value == BeforeOrAfterPointer)
return beforeOrAfterPointer();
if (Value == AfterPointer || Other.Value == AfterPointer)
return afterPointer();
return upperBound(std::max(getValue(), Other.getValue()));
}
bool hasValue() const { return Value != Unknown; }
bool hasValue() const {
return Value != AfterPointer && Value != BeforeOrAfterPointer;
}
uint64_t getValue() const {
assert(hasValue() && "Getting value from an unknown LocationSize!");
return Value & ~ImpreciseBit;
}
// Returns whether or not this value is precise. Note that if a value is
// precise, it's guaranteed to not be `unknown()`.
// precise, it's guaranteed to not be unknown.
bool isPrecise() const {
return (Value & ImpreciseBit) == 0;
}
@ -152,6 +169,9 @@ public:
// Convenience method to check if this LocationSize's value is 0.
bool isZero() const { return hasValue() && getValue() == 0; }
/// Whether accesses before the base pointer are possible.
bool mayBeBeforePointer() const { return Value == BeforeOrAfterPointer; }
bool operator==(const LocationSize &Other) const {
return Value == Other.Value;
}
@ -242,13 +262,28 @@ public:
return getForArgument(Call, ArgIdx, &TLI);
}
/// Return a location that may access any location after Ptr, while remaining
/// within the underlying object.
static MemoryLocation getAfter(const Value *Ptr,
const AAMDNodes &AATags = AAMDNodes()) {
return MemoryLocation(Ptr, LocationSize::afterPointer(), AATags);
}
/// Return a location that may access any location before or after Ptr, while
/// remaining within the underlying object.
static MemoryLocation
getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags = AAMDNodes()) {
return MemoryLocation(Ptr, LocationSize::beforeOrAfterPointer(), AATags);
}
// Return the exact size if the exact size is known at compiletime,
// otherwise return MemoryLocation::UnknownSize.
static uint64_t getSizeOrUnknown(const TypeSize &T) {
return T.isScalable() ? UnknownSize : T.getFixedSize();
}
MemoryLocation() : Ptr(nullptr), Size(LocationSize::unknown()), AATags() {}
MemoryLocation()
: Ptr(nullptr), Size(LocationSize::beforeOrAfterPointer()), AATags() {}
explicit MemoryLocation(const Value *Ptr, LocationSize Size,
const AAMDNodes &AATags = AAMDNodes())

View File

@ -1248,7 +1248,8 @@ private:
// catch loop carried dependences.
if (Location.Ptr &&
!IsGuaranteedLoopInvariant(const_cast<Value *>(Location.Ptr)))
CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
CurrentPair.second =
Location.getWithNewSize(LocationSize::beforeOrAfterPointer());
PHITransAddr Translator(
const_cast<Value *>(Location.Ptr),
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
@ -1262,8 +1263,8 @@ private:
if (TransAddr &&
!IsGuaranteedLoopInvariant(const_cast<Value *>(TransAddr)))
CurrentPair.second =
CurrentPair.second.getWithNewSize(LocationSize::unknown());
CurrentPair.second = CurrentPair.second.getWithNewSize(
LocationSize::beforeOrAfterPointer());
if (PerformedPhiTranslation)
*PerformedPhiTranslation = true;

View File

@ -239,7 +239,7 @@ namespace {
llvm::TargetLibraryInfo TLI(TLII);
llvm::AliasAnalysis AA(TLI);
llvm::AliasSetTracker X(AA);
X.add(nullptr, llvm::LocationSize::unknown(),
X.add(nullptr, llvm::LocationSize::beforeOrAfterPointer(),
llvm::AAMDNodes()); // for -print-alias-sets
(void) llvm::AreStatisticsEnabled();
(void) llvm::sys::RunningOnValgrind();

View File

@ -140,13 +140,13 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
// iterate over the worklist, and run the full (n^2)/2 disambiguations
for (SetVector<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
I1 != E; ++I1) {
auto I1Size = LocationSize::unknown();
auto I1Size = LocationSize::afterPointer();
Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
if (I1ElTy->isSized())
I1Size = LocationSize::precise(DL.getTypeStoreSize(I1ElTy));
for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
auto I2Size = LocationSize::unknown();
auto I2Size = LocationSize::afterPointer();
Type *I2ElTy = cast<PointerType>((*I2)->getType())->getElementType();
if (I2ElTy->isSized())
I2Size = LocationSize::precise(DL.getTypeStoreSize(I2ElTy));
@ -231,7 +231,7 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
// Mod/ref alias analysis: compare all pairs of calls and values
for (CallBase *Call : Calls) {
for (auto Pointer : Pointers) {
auto Size = LocationSize::unknown();
auto Size = LocationSize::afterPointer();
Type *ElTy = cast<PointerType>(Pointer->getType())->getElementType();
if (ElTy->isSized())
Size = LocationSize::precise(DL.getTypeStoreSize(ElTy));

View File

@ -671,8 +671,10 @@ void AliasSet::print(raw_ostream &OS) const {
for (iterator I = begin(), E = end(); I != E; ++I) {
if (I != begin()) OS << ", ";
I.getPointer()->printAsOperand(OS << "(");
if (I.getSize() == LocationSize::unknown())
OS << ", unknown)";
if (I.getSize() == LocationSize::afterPointer())
OS << ", unknown after)";
else if (I.getSize() == LocationSize::beforeOrAfterPointer())
OS << ", unknown before-or-after)";
else
OS << ", " << I.getSize() << ")";
}

View File

@ -877,8 +877,8 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
// If this is a no-capture pointer argument, see if we can tell that it
// is impossible to alias the pointer we're checking.
AliasResult AR = getBestAAResults().alias(
MemoryLocation(*CI, LocationSize::unknown()),
MemoryLocation(Object, LocationSize::unknown()), AAQI);
MemoryLocation::getBeforeOrAfter(*CI),
MemoryLocation::getBeforeOrAfter(Object), AAQI);
if (AR != MustAlias)
IsMustAlias = false;
// Operand doesn't alias 'Object', continue looking for other aliases
@ -924,7 +924,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
if (isMallocOrCallocLikeFn(Call, &TLI)) {
// Be conservative if the accessed pointer may alias the allocation -
// fallback to the generic handling below.
if (getBestAAResults().alias(MemoryLocation(Call, LocationSize::unknown()),
if (getBestAAResults().alias(MemoryLocation::getBeforeOrAfter(Call),
Loc, AAQI) == NoAlias)
return ModRefInfo::NoModRef;
}
@ -1245,9 +1245,9 @@ AliasResult BasicAAResult::aliasGEP(
if (isGEPBaseAtNegativeOffset(GEP2, DecompGEP2, DecompGEP1, V1Size))
return NoAlias;
// Do the base pointers alias?
AliasResult BaseAlias =
aliasCheck(UnderlyingV1, LocationSize::unknown(), AAMDNodes(),
UnderlyingV2, LocationSize::unknown(), AAMDNodes(), AAQI);
AliasResult BaseAlias = aliasCheck(
UnderlyingV1, LocationSize::beforeOrAfterPointer(), AAMDNodes(),
UnderlyingV2, LocationSize::beforeOrAfterPointer(), AAMDNodes(), AAQI);
// For GEPs with identical offsets, we can preserve the size and AAInfo
// when performing the alias check on the underlying objects.
@ -1295,9 +1295,9 @@ AliasResult BasicAAResult::aliasGEP(
if (!V1Size.hasValue() && !V2Size.hasValue())
return MayAlias;
AliasResult R = aliasCheck(UnderlyingV1, LocationSize::unknown(),
AAMDNodes(), V2, LocationSize::unknown(),
V2AAInfo, AAQI, nullptr, UnderlyingV2);
AliasResult R = aliasCheck(
UnderlyingV1, LocationSize::beforeOrAfterPointer(), AAMDNodes(),
V2, V2Size, V2AAInfo, AAQI, nullptr, UnderlyingV2);
if (R != MustAlias) {
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
// If V2 is known not to alias GEP base pointer, then the two values
@ -1588,7 +1588,11 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, LocationSize PNSize,
// unknown to represent all the possible values the GEP could advance the
// pointer to.
if (isRecursive)
PNSize = LocationSize::unknown();
// TODO: We are checking above that the addrec GEP has a positive offset
// and can thus assume that all accesses happen after the base pointer.
// It might be better to drop the offset requirement and use
// beforeOrAfterPointer().
PNSize = LocationSize::afterPointer();
// In the recursive alias queries below, we may compare values from two
// different loop iterations. Keep track of visited phi blocks, which will
@ -1726,6 +1730,18 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, LocationSize V1Size,
TLI, NullIsValidLocation)))
return NoAlias;
// If one the accesses may be before the accessed pointer, canonicalize this
// by using unknown after-pointer sizes for both accesses. This is
// equivalent, because regardless of which pointer is lower, one of them
// will always came after the other, as long as the underlying objects aren't
// disjoint. We do this so that the rest of BasicAA does not have to deal
// with accesses before the base pointer, and to improve cache utilization by
// merging equivalent states.
if (V1Size.mayBeBeforePointer() || V2Size.mayBeBeforePointer()) {
V1Size = LocationSize::afterPointer();
V2Size = LocationSize::afterPointer();
}
// Check the cache before climbing up use-def chains. This also terminates
// otherwise infinitely recursive queries.
AAQueryInfo::LocPair Locs(MemoryLocation(V1, V1Size, V1AAInfo),

View File

@ -653,8 +653,10 @@ static AliasResult underlyingObjectsAlias(AAResults *AA,
const MemoryLocation &LocB) {
// Check the original locations (minus size) for noalias, which can happen for
// tbaa, incompatible underlying object locations, etc.
MemoryLocation LocAS(LocA.Ptr, LocationSize::unknown(), LocA.AATags);
MemoryLocation LocBS(LocB.Ptr, LocationSize::unknown(), LocB.AATags);
MemoryLocation LocAS =
MemoryLocation::getBeforeOrAfter(LocA.Ptr, LocA.AATags);
MemoryLocation LocBS =
MemoryLocation::getBeforeOrAfter(LocB.Ptr, LocB.AATags);
if (AA->alias(LocAS, LocBS) == NoAlias)
return NoAlias;

View File

@ -921,8 +921,8 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(const CallBase *Call,
if (!all_of(Objects, isIdentifiedObject) &&
// Try ::alias to see if all objects are known not to alias GV.
!all_of(Objects, [&](const Value *V) {
return this->alias(MemoryLocation(V, LocationSize::unknown()),
MemoryLocation(GV, LocationSize::unknown()),
return this->alias(MemoryLocation::getBeforeOrAfter(V),
MemoryLocation::getBeforeOrAfter(GV),
AAQI) == NoAlias;
}))
return ConservativeResult;

View File

@ -190,8 +190,8 @@ void Lint::visitFunction(Function &F) {
void Lint::visitCallBase(CallBase &I) {
Value *Callee = I.getCalledOperand();
visitMemoryReference(I, MemoryLocation(Callee, LocationSize::unknown()),
None, nullptr, MemRef::Callee);
visitMemoryReference(I, MemoryLocation::getAfter(Callee), None, nullptr,
MemRef::Callee);
if (Function *F = dyn_cast<Function>(findValue(Callee,
/*OffsetOk=*/false))) {
@ -295,7 +295,7 @@ void Lint::visitCallBase(CallBase &I) {
// Check that the memcpy arguments don't overlap. The AliasAnalysis API
// isn't expressive enough for what we really want to do. Known partial
// overlap is not distinguished from the case where nothing is known.
auto Size = LocationSize::unknown();
auto Size = LocationSize::afterPointer();
if (const ConstantInt *Len =
dyn_cast<ConstantInt>(findValue(MCI->getLength(),
/*OffsetOk=*/false)))
@ -586,9 +586,8 @@ void Lint::visitVAArgInst(VAArgInst &I) {
}
void Lint::visitIndirectBrInst(IndirectBrInst &I) {
visitMemoryReference(
I, MemoryLocation(I.getAddress(), LocationSize::unknown()),
None, nullptr, MemRef::Branchee);
visitMemoryReference(I, MemoryLocation::getAfter(I.getAddress()), None,
nullptr, MemRef::Branchee);
Assert(I.getNumDestinations() != 0,
"Undefined behavior: indirectbr with no destinations", &I);

View File

@ -514,7 +514,7 @@ public:
/// Register a load and whether it is only read from.
void addLoad(MemoryLocation &Loc, bool IsReadOnly) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
AST.add(Ptr, LocationSize::unknown(), Loc.AATags);
AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, false));
if (IsReadOnly)
ReadOnlyPtr.insert(Ptr);
@ -523,7 +523,7 @@ public:
/// Register a store.
void addStore(MemoryLocation &Loc) {
Value *Ptr = const_cast<Value*>(Loc.Ptr);
AST.add(Ptr, LocationSize::unknown(), Loc.AATags);
AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags);
Accesses.insert(MemAccessInfo(Ptr, true));
}

View File

@ -148,7 +148,7 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
if (const CallInst *CI = isFreeCall(Inst, &TLI)) {
// calls to free() deallocate the entire structure
Loc = MemoryLocation(CI->getArgOperand(0), LocationSize::unknown());
Loc = MemoryLocation::getAfter(CI->getArgOperand(0));
return ModRefInfo::Mod;
}
@ -455,7 +455,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
// pointer, not on query pointers that are indexed off of them. It'd
// be nice to handle that at some point (the right approach is to use
// GetPointerBaseWithConstantOffset).
MemoryLocation ArgLoc(II->getArgOperand(1), LocationSize::unknown());
MemoryLocation ArgLoc = MemoryLocation::getAfter(II->getArgOperand(1));
if (BatchAA.isMustAlias(ArgLoc, MemLoc))
return MemDepResult::getDef(II);
continue;

View File

@ -20,8 +20,10 @@ using namespace llvm;
void LocationSize::print(raw_ostream &OS) const {
OS << "LocationSize::";
if (*this == unknown())
OS << "unknown";
if (*this == beforeOrAfterPointer())
OS << "beforeOrAfterPointer";
if (*this == afterPointer())
OS << "afterPointer";
else if (*this == mapEmpty())
OS << "mapEmpty";
else if (*this == mapTombstone())
@ -57,8 +59,8 @@ MemoryLocation MemoryLocation::get(const VAArgInst *VI) {
AAMDNodes AATags;
VI->getAAMetadata(AATags);
return MemoryLocation(VI->getPointerOperand(), LocationSize::unknown(),
AATags);
return MemoryLocation(VI->getPointerOperand(),
LocationSize::afterPointer(), AATags);
}
MemoryLocation MemoryLocation::get(const AtomicCmpXchgInst *CXI) {
@ -109,7 +111,7 @@ MemoryLocation MemoryLocation::getForSource(const AtomicMemTransferInst *MTI) {
}
MemoryLocation MemoryLocation::getForSource(const AnyMemTransferInst *MTI) {
auto Size = LocationSize::unknown();
auto Size = LocationSize::afterPointer();
if (ConstantInt *C = dyn_cast<ConstantInt>(MTI->getLength()))
Size = LocationSize::precise(C->getValue().getZExtValue());
@ -130,7 +132,7 @@ MemoryLocation MemoryLocation::getForDest(const AtomicMemIntrinsic *MI) {
}
MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
auto Size = LocationSize::unknown();
auto Size = LocationSize::afterPointer();
if (ConstantInt *C = dyn_cast<ConstantInt>(MI->getLength()))
Size = LocationSize::precise(C->getValue().getZExtValue());
@ -165,7 +167,7 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
AATags);
break;
return MemoryLocation::getAfter(Arg, AATags);
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
@ -237,7 +239,7 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
dyn_cast<ConstantInt>(Call->getArgOperand(2)))
return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
AATags);
break;
return MemoryLocation::getAfter(Arg, AATags);
case LibFunc_bcmp:
case LibFunc_memcmp:
assert((ArgIdx == 0 || ArgIdx == 1) &&
@ -246,14 +248,14 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
dyn_cast<ConstantInt>(Call->getArgOperand(2)))
return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
AATags);
break;
return MemoryLocation::getAfter(Arg, AATags);
case LibFunc_memchr:
assert((ArgIdx == 0) && "Invalid argument index for memchr");
if (const ConstantInt *LenCI =
dyn_cast<ConstantInt>(Call->getArgOperand(2)))
return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
AATags);
break;
return MemoryLocation::getAfter(Arg, AATags);
case LibFunc_memccpy:
assert((ArgIdx == 0 || ArgIdx == 1) &&
"Invalid argument index for memccpy");
@ -262,13 +264,12 @@ MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
dyn_cast<ConstantInt>(Call->getArgOperand(3)))
return MemoryLocation(
Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
break;
return MemoryLocation::getAfter(Arg, AATags);
default:
break;
};
}
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
return MemoryLocation(Call->getArgOperand(ArgIdx), LocationSize::unknown(),
AATags);
return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
}

View File

@ -363,7 +363,7 @@ static bool lifetimeEndsAt(MemoryDef *MD, const MemoryLocation &Loc,
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
switch (II->getIntrinsicID()) {
case Intrinsic::lifetime_end: {
MemoryLocation ArgLoc(II->getArgOperand(1), LocationSize::unknown());
MemoryLocation ArgLoc = MemoryLocation::getAfter(II->getArgOperand(1));
return AA.alias(ArgLoc, Loc) == MustAlias;
}
default:

View File

@ -57,9 +57,8 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
const Value *UA = GetUnderlyingObjCPtr(SA);
const Value *UB = GetUnderlyingObjCPtr(SB);
if (UA != SA || UB != SB) {
Result = AAResultBase::alias(
MemoryLocation(UA, LocationSize::unknown()),
MemoryLocation(UB, LocationSize::unknown()), AAQI);
Result = AAResultBase::alias(MemoryLocation::getBeforeOrAfter(UA),
MemoryLocation::getBeforeOrAfter(UB), AAQI);
// We can't use MustAlias or PartialAlias results here because
// GetUnderlyingObjCPtr may return an offsetted pointer value.
if (Result == NoAlias)
@ -88,7 +87,7 @@ bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
const Value *U = GetUnderlyingObjCPtr(S);
if (U != S)
return AAResultBase::pointsToConstantMemory(
MemoryLocation(U, LocationSize::unknown()), AAQI, OrLocal);
MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal);
// If that failed, fail. We don't need to chain here, since that's covered
// by the earlier precise query.

View File

@ -82,10 +82,12 @@ AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
Value *BO = GetBaseValue(BS);
if ((AO && AO != LocA.Ptr) || (BO && BO != LocB.Ptr))
if (alias(MemoryLocation(AO ? AO : LocA.Ptr,
AO ? LocationSize::unknown() : LocA.Size,
AO ? LocationSize::beforeOrAfterPointer()
: LocA.Size,
AO ? AAMDNodes() : LocA.AATags),
MemoryLocation(BO ? BO : LocB.Ptr,
BO ? LocationSize::unknown() : LocB.Size,
BO ? LocationSize::beforeOrAfterPointer()
: LocB.Size,
BO ? AAMDNodes() : LocB.AATags),
AAQI) == NoAlias)
return NoAlias;

View File

@ -353,11 +353,9 @@ ImplicitNullChecks::areMemoryOpsAliased(const MachineInstr &MI,
return AR_MayAlias;
continue;
}
llvm::AliasResult AAResult =
AA->alias(MemoryLocation(MMO1->getValue(), LocationSize::unknown(),
MMO1->getAAInfo()),
MemoryLocation(MMO2->getValue(), LocationSize::unknown(),
MMO2->getAAInfo()));
llvm::AliasResult AAResult = AA->alias(
MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
if (AAResult != NoAlias)
return AR_MayAlias;
}

View File

@ -803,10 +803,8 @@ void SwingSchedulerDAG::addLoopCarriedDependences(AliasAnalysis *AA) {
continue;
}
AliasResult AAResult = AA->alias(
MemoryLocation(MMO1->getValue(), LocationSize::unknown(),
MMO1->getAAInfo()),
MemoryLocation(MMO2->getValue(), LocationSize::unknown(),
MMO2->getAAInfo()));
MemoryLocation::getAfter(MMO1->getValue(), MMO1->getAAInfo()),
MemoryLocation::getAfter(MMO2->getValue(), MMO2->getAAInfo()));
if (AAResult != NoAlias) {
SDep Dep(Load, SDep::Barrier);

View File

@ -4358,7 +4358,7 @@ void SelectionDAGBuilder::visitMaskedLoad(const CallInst &I, bool IsExpanding) {
// Do not serialize masked loads of constant memory with anything.
MemoryLocation ML;
if (VT.isScalableVector())
ML = MemoryLocation(PtrOperand, LocationSize::unknown());
ML = MemoryLocation::getAfter(PtrOperand);
else
ML = MemoryLocation(PtrOperand, LocationSize::precise(
DAG.getDataLayout().getTypeStoreSize(I.getType())),

View File

@ -109,7 +109,7 @@ bool AMDGPUAnnotateUniformValues::isClobberedInFunction(LoadInst * Load) {
BasicBlock::iterator StartIt = (!L && (BB == Load->getParent())) ?
BasicBlock::iterator(Load) : BB->end();
auto Q = MDR->getPointerDependencyFrom(
MemoryLocation(Ptr, LocationSize::unknown()), true, StartIt, BB, Load);
MemoryLocation::getBeforeOrAfter(Ptr), true, StartIt, BB, Load);
if (Q.isClobber() || Q.isUnknown())
return true;
}

View File

@ -304,8 +304,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
BasicBlock *BB = RI->getParent();
MemDepResult Q = MDA->getPointerDependencyFrom(
MemoryLocation(OutArg, LocationSize::unknown()), true, BB->end(),
BB, RI);
MemoryLocation::getBeforeOrAfter(OutArg), true, BB->end(), BB, RI);
StoreInst *SI = nullptr;
if (Q.isDef())
SI = dyn_cast<StoreInst>(Q.getInst());

View File

@ -374,7 +374,7 @@ bool ARMParallelDSP::RecordMemoryOps(BasicBlock *BB) {
DepMap RAWDeps;
// Record any writes that may alias a load.
const auto Size = LocationSize::unknown();
const auto Size = LocationSize::beforeOrAfterPointer();
for (auto Write : Writes) {
for (auto Read : Loads) {
MemoryLocation ReadLoc =

View File

@ -1992,7 +1992,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
// Get the location that may be stored across the loop. Since the access
// is strided positively through memory, we say that the modified location
// starts at the pointer and has infinite size.
LocationSize AccessSize = LocationSize::unknown();
LocationSize AccessSize = LocationSize::afterPointer();
// If the loop iterates a fixed number of times, we can refine the access
// size to be exactly the size of the memset, which is (BECount+1)*StoreSize

View File

@ -167,7 +167,7 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
AAMDNodes AAInfo;
I->getAAMetadata(AAInfo);
MemoryLocation Loc(Arg, LocationSize::unknown(), AAInfo);
MemoryLocation Loc = MemoryLocation::getBeforeOrAfter(Arg, AAInfo);
// Skip accesses to local or constant memory as they don't impact the
// externally visible mod/ref behavior.

View File

@ -275,7 +275,7 @@ static MemoryLocation getLocForWrite(Instruction *Inst,
default:
return MemoryLocation(); // Unhandled intrinsic.
case Intrinsic::init_trampoline:
return MemoryLocation(II->getArgOperand(0), LocationSize::unknown());
return MemoryLocation::getAfter(II->getArgOperand(0));
case Intrinsic::masked_store:
return MemoryLocation::getForArgument(II, 1, TLI);
case Intrinsic::lifetime_end: {
@ -287,7 +287,7 @@ static MemoryLocation getLocForWrite(Instruction *Inst,
if (auto *CB = dyn_cast<CallBase>(Inst))
// All the supported TLI functions so far happen to have dest as their
// first argument.
return MemoryLocation(CB->getArgOperand(0), LocationSize::unknown());
return MemoryLocation::getAfter(CB->getArgOperand(0));
return MemoryLocation();
}
@ -828,8 +828,7 @@ static bool handleFree(CallInst *F, AliasAnalysis *AA,
MapVector<Instruction *, bool> &ThrowableInst) {
bool MadeChange = false;
MemoryLocation Loc = MemoryLocation(F->getOperand(0),
LocationSize::unknown());
MemoryLocation Loc = MemoryLocation::getAfter(F->getOperand(0));
SmallVector<BasicBlock *, 16> Blocks;
Blocks.push_back(F->getParent());
@ -1726,15 +1725,14 @@ struct DSEState {
case LibFunc_strncpy:
case LibFunc_strcat:
case LibFunc_strncat:
return {MemoryLocation(CB->getArgOperand(0),
LocationSize::unknown())};
return {MemoryLocation::getAfter(CB->getArgOperand(0))};
default:
break;
}
}
switch (CB->getIntrinsicID()) {
case Intrinsic::init_trampoline:
return {MemoryLocation(CB->getArgOperand(0), LocationSize::unknown())};
return {MemoryLocation::getAfter(CB->getArgOperand(0))};
case Intrinsic::masked_store:
return {MemoryLocation::getForArgument(CB, 1, TLI)};
default:
@ -1829,8 +1827,7 @@ struct DSEState {
if (auto *CB = dyn_cast<CallBase>(I)) {
if (isFreeCall(I, &TLI))
return {std::make_pair(MemoryLocation(CB->getArgOperand(0),
LocationSize::unknown()),
return {std::make_pair(MemoryLocation::getAfter(CB->getArgOperand(0)),
true)};
}

View File

@ -1209,8 +1209,7 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
bool Invalidated;
if (CurAST)
Invalidated = pointerInvalidatedByLoop(
MemoryLocation(Op, LocationSize::unknown(), AAMDNodes()),
CurAST, CurLoop, AA);
MemoryLocation::getBeforeOrAfter(Op), CurAST, CurLoop, AA);
else
Invalidated = pointerInvalidatedByLoopWithMSSA(
MSSA, cast<MemoryUse>(MSSA->getMemoryAccess(CI)), CurLoop, I,

View File

@ -844,7 +844,7 @@ mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L,
// Get the location that may be stored across the loop. Since the access is
// strided positively through memory, we say that the modified location starts
// at the pointer and has infinite size.
LocationSize AccessSize = LocationSize::unknown();
LocationSize AccessSize = LocationSize::afterPointer();
// If the loop iterates a fixed number of times, we can refine the access size
// to be exactly the size of the memset, which is (BECount+1)*StoreSize

View File

@ -6,7 +6,7 @@
; CHECK: Alias sets for function 'test_alloca_argmemonly':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, LocationSize::precise(1))
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %d, unknown), (i8* %s, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %d, unknown before-or-after), (i8* %s, unknown before-or-after)
define void @test_alloca_argmemonly(i8* %s, i8* %d) {
entry:
%a = alloca i8, align 1
@ -17,8 +17,8 @@ entry:
; CHECK: Alias sets for function 'test_readonly_arg'
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (i8* %s, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (i8* %s, unknown before-or-after)
define i8 @test_readonly_arg(i8* noalias %s, i8* noalias %d) {
entry:
call void @my_memcpy(i8* %d, i8* %s, i64 1)
@ -29,7 +29,7 @@ entry:
; CHECK: Alias sets for function 'test_noalias_argmemonly':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 3 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, LocationSize::precise(1))
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %d, unknown), (i8* %s, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod/Ref Pointers: (i8* %d, unknown before-or-after), (i8* %s, unknown before-or-after)
define void @test_noalias_argmemonly(i8* noalias %a, i8* %s, i8* %d) {
entry:
store i8 1, i8* %a, align 1
@ -39,8 +39,8 @@ entry:
; CHECK: Alias sets for function 'test5':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, unknown before-or-after)
define void @test5(i8* noalias %a, i8* noalias %b) {
entry:
store i8 1, i8* %a, align 1
@ -51,8 +51,8 @@ entry:
; CHECK: Alias sets for function 'test_argcollapse':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %b, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %b, unknown before-or-after)
define void @test_argcollapse(i8* noalias %a, i8* noalias %b) {
entry:
store i8 1, i8* %a, align 1
@ -63,8 +63,8 @@ entry:
; CHECK: Alias sets for function 'test_memcpy1':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %b, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %b, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod/Ref Pointers: (i8* %a, unknown before-or-after)
define void @test_memcpy1(i8* noalias %a, i8* noalias %b) {
entry:
call void @my_memcpy(i8* %b, i8* %a, i64 1)
@ -74,7 +74,7 @@ entry:
; CHECK: Alias sets for function 'test_memset1':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown before-or-after)
define void @test_memset1() {
entry:
%a = alloca i8, align 1
@ -84,7 +84,7 @@ entry:
; CHECK: Alias sets for function 'test_memset2':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown before-or-after)
define void @test_memset2(i8* %a) {
entry:
call void @my_memset(i8* %a, i8 0, i64 1)
@ -93,7 +93,7 @@ entry:
; CHECK: Alias sets for function 'test_memset3':
; CHECK-NEXT: Alias Set Tracker: 1 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Pointers: (i8* %a, unknown), (i8* %b, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 2] may alias, Mod Pointers: (i8* %a, unknown before-or-after), (i8* %b, unknown before-or-after)
define void @test_memset3(i8* %a, i8* %b) {
entry:
call void @my_memset(i8* %a, i8 0, i64 1)
@ -105,8 +105,8 @@ entry:
; CHECK: Alias sets for function 'test_memset4':
; CHECK-NEXT: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, unknown)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %a, unknown before-or-after)
; CHECK-NEXT: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %b, unknown before-or-after)
define void @test_memset4(i8* noalias %a, i8* noalias %b) {
entry:
call void @my_memset(i8* %a, i8 0, i64 1)

View File

@ -14,7 +14,7 @@ entry:
; CHECK: Alias sets for function 'test_unknown_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown after)
define void @test_unknown_size(i8* noalias %d, i64 %len) {
entry:
call void @llvm.memset.p0i8.i64(i8* align 1 %d, i8 0, i64 %len, i1 false)
@ -33,7 +33,7 @@ entry:
; CHECK: Alias sets for function 'test_atomic_unknown_size':
; CHECK: Alias Set Tracker: 1 alias sets for 1 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown after)
define void @test_atomic_unknown_size(i8* noalias %d, i64 %len) {
entry:
call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 1 %d, i8 0, i64 %len, i32 1)

View File

@ -16,8 +16,8 @@ entry:
; CHECK: Alias sets for function 'test_unknown_size':
; CHECK: Alias Set Tracker: 2 alias sets for 2 pointer values.
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (i8* %s, unknown)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Mod Pointers: (i8* %d, unknown after)
; CHECK: AliasSet[0x{{[0-9a-f]+}}, 1] must alias, Ref Pointers: (i8* %s, unknown after)
define void @test_unknown_size(i8* noalias %s, i8* noalias %d, i64 %len) {
entry:
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %d, i8* %s, i64 %len, i1 false)

View File

@ -273,9 +273,9 @@ entry:
; CHECK-LABEL: Function: test8
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func()
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func()
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessiblememonly_func()
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
@ -368,9 +368,9 @@ entry:
; CHECK: Just Ref: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #9 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #9 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]

View File

@ -9,8 +9,9 @@
; #####################################################################
; Load from %arg1 has no-alias store in Loop - arg1[i+1] never alias arg1[i]
; However, our analysis cannot detect this.
; CHECK: s_load_dword
; CHECK: flat_load_dword
; #####################################################################

View File

@ -55,8 +55,8 @@ struct AATestPass : FunctionPass {
for (Value *P1 : Pointers)
for (Value *P2 : Pointers)
(void)AA.alias(P1, LocationSize::unknown(), P2,
LocationSize::unknown());
(void)AA.alias(P1, LocationSize::beforeOrAfterPointer(), P2,
LocationSize::beforeOrAfterPointer());
return false;
}

View File

@ -1277,7 +1277,7 @@ TEST_F(MemorySSATest, LifetimeMarkersAreClobbers) {
MemoryAccess *LifetimeStartClobber =
MSSA.getWalker()->getClobberingMemoryAccess(
LifetimeStartAccess, MemoryLocation(Foo, LocationSize::unknown()));
LifetimeStartAccess, MemoryLocation::getAfter(Foo));
EXPECT_EQ(LifetimeStartClobber, LifetimeStartAccess);
}

View File

@ -1129,7 +1129,7 @@ bool ScopDetection::isValidAccess(Instruction *Inst, const SCEV *AF,
AAMDNodes AATags;
Inst->getAAMetadata(AATags);
AliasSet &AS = Context.AST.getAliasSetFor(
MemoryLocation(BP->getValue(), LocationSize::unknown(), AATags));
MemoryLocation::getBeforeOrAfter(BP->getValue(), AATags));
if (!AS.isMustAlias()) {
if (PollyUseRuntimeAliasChecks) {