mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
Revert r212572 "improve BasicAA CS-CS queries", it causes PR20303.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213024 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2639f77252
commit
5508cfd02c
@ -274,14 +274,6 @@ public:
|
|||||||
UnknownModRefBehavior = Anywhere | ModRef
|
UnknownModRefBehavior = Anywhere | ModRef
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Get the location associated with a pointer argument of a callsite.
|
|
||||||
/// The mask bits are set to indicate the allowed aliasing ModRef kinds.
|
|
||||||
/// Note that these mask bits do not necessarily account for the overall
|
|
||||||
/// behavior of the function, but rather only provide additional
|
|
||||||
/// per-argument information.
|
|
||||||
virtual Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
|
|
||||||
ModRefResult &Mask);
|
|
||||||
|
|
||||||
/// getModRefBehavior - Return the behavior when calling the given call site.
|
/// getModRefBehavior - Return the behavior when calling the given call site.
|
||||||
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
|
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
|
||||||
|
|
||||||
|
@ -60,13 +60,6 @@ bool AliasAnalysis::pointsToConstantMemory(const Location &Loc,
|
|||||||
return AA->pointsToConstantMemory(Loc, OrLocal);
|
return AA->pointsToConstantMemory(Loc, OrLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasAnalysis::Location
|
|
||||||
AliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
|
|
||||||
AliasAnalysis::ModRefResult &Mask) {
|
|
||||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
|
||||||
return AA->getArgLocation(CS, ArgIdx, Mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AliasAnalysis::deleteValue(Value *V) {
|
void AliasAnalysis::deleteValue(Value *V) {
|
||||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||||
AA->deleteValue(V);
|
AA->deleteValue(V);
|
||||||
@ -98,26 +91,22 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
|
|||||||
|
|
||||||
if (onlyAccessesArgPointees(MRB)) {
|
if (onlyAccessesArgPointees(MRB)) {
|
||||||
bool doesAlias = false;
|
bool doesAlias = false;
|
||||||
ModRefResult AllArgsMask = NoModRef;
|
|
||||||
if (doesAccessArgPointees(MRB)) {
|
if (doesAccessArgPointees(MRB)) {
|
||||||
|
MDNode *CSTag = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||||
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
|
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
|
||||||
AI != AE; ++AI) {
|
AI != AE; ++AI) {
|
||||||
const Value *Arg = *AI;
|
const Value *Arg = *AI;
|
||||||
if (!Arg->getType()->isPointerTy())
|
if (!Arg->getType()->isPointerTy())
|
||||||
continue;
|
continue;
|
||||||
ModRefResult ArgMask;
|
Location CSLoc(Arg, UnknownSize, CSTag);
|
||||||
Location CSLoc =
|
|
||||||
getArgLocation(CS, (unsigned) std::distance(CS.arg_begin(), AI),
|
|
||||||
ArgMask);
|
|
||||||
if (!isNoAlias(CSLoc, Loc)) {
|
if (!isNoAlias(CSLoc, Loc)) {
|
||||||
doesAlias = true;
|
doesAlias = true;
|
||||||
AllArgsMask = ModRefResult(AllArgsMask | ArgMask);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!doesAlias)
|
if (!doesAlias)
|
||||||
return NoModRef;
|
return NoModRef;
|
||||||
Mask = ModRefResult(Mask & AllArgsMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Loc is a constant memory location, the call definitely could not
|
// If Loc is a constant memory location, the call definitely could not
|
||||||
@ -161,23 +150,14 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
|
|||||||
if (onlyAccessesArgPointees(CS2B)) {
|
if (onlyAccessesArgPointees(CS2B)) {
|
||||||
AliasAnalysis::ModRefResult R = NoModRef;
|
AliasAnalysis::ModRefResult R = NoModRef;
|
||||||
if (doesAccessArgPointees(CS2B)) {
|
if (doesAccessArgPointees(CS2B)) {
|
||||||
|
MDNode *CS2Tag = CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||||
for (ImmutableCallSite::arg_iterator
|
for (ImmutableCallSite::arg_iterator
|
||||||
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
|
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
|
||||||
const Value *Arg = *I;
|
const Value *Arg = *I;
|
||||||
if (!Arg->getType()->isPointerTy())
|
if (!Arg->getType()->isPointerTy())
|
||||||
continue;
|
continue;
|
||||||
ModRefResult ArgMask;
|
Location CS2Loc(Arg, UnknownSize, CS2Tag);
|
||||||
Location CS2Loc =
|
R = ModRefResult((R | getModRefInfo(CS1, CS2Loc)) & Mask);
|
||||||
getArgLocation(CS2, (unsigned) std::distance(CS2.arg_begin(), I),
|
|
||||||
ArgMask);
|
|
||||||
// ArgMask indicates what CS2 might do to CS2Loc, and the dependence of
|
|
||||||
// CS1 on that location is the inverse.
|
|
||||||
if (ArgMask == Mod)
|
|
||||||
ArgMask = ModRef;
|
|
||||||
else if (ArgMask == Ref)
|
|
||||||
ArgMask = Mod;
|
|
||||||
|
|
||||||
R = ModRefResult((R | (getModRefInfo(CS1, CS2Loc) & ArgMask)) & Mask);
|
|
||||||
if (R == Mask)
|
if (R == Mask)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -190,16 +170,14 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
|
|||||||
if (onlyAccessesArgPointees(CS1B)) {
|
if (onlyAccessesArgPointees(CS1B)) {
|
||||||
AliasAnalysis::ModRefResult R = NoModRef;
|
AliasAnalysis::ModRefResult R = NoModRef;
|
||||||
if (doesAccessArgPointees(CS1B)) {
|
if (doesAccessArgPointees(CS1B)) {
|
||||||
|
MDNode *CS1Tag = CS1.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||||
for (ImmutableCallSite::arg_iterator
|
for (ImmutableCallSite::arg_iterator
|
||||||
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
|
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
|
||||||
const Value *Arg = *I;
|
const Value *Arg = *I;
|
||||||
if (!Arg->getType()->isPointerTy())
|
if (!Arg->getType()->isPointerTy())
|
||||||
continue;
|
continue;
|
||||||
ModRefResult ArgMask;
|
Location CS1Loc(Arg, UnknownSize, CS1Tag);
|
||||||
Location CS1Loc =
|
if (getModRefInfo(CS2, CS1Loc) != NoModRef) {
|
||||||
getArgLocation(CS1, (unsigned) std::distance(CS1.arg_begin(), I),
|
|
||||||
ArgMask);
|
|
||||||
if ((getModRefInfo(CS2, CS1Loc) & ArgMask) != NoModRef) {
|
|
||||||
R = Mask;
|
R = Mask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -490,10 +490,6 @@ namespace {
|
|||||||
/// global) or not.
|
/// global) or not.
|
||||||
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override;
|
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override;
|
||||||
|
|
||||||
/// Get the location associated with a pointer argument of a callsite.
|
|
||||||
Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
|
|
||||||
ModRefResult &Mask) override;
|
|
||||||
|
|
||||||
/// getModRefBehavior - Return the behavior when calling the given
|
/// getModRefBehavior - Return the behavior when calling the given
|
||||||
/// call site.
|
/// call site.
|
||||||
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
|
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
|
||||||
@ -657,21 +653,6 @@ BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) {
|
|||||||
return Worklist.empty();
|
return Worklist.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isMemsetPattern16(const Function *MS,
|
|
||||||
const TargetLibraryInfo &TLI) {
|
|
||||||
if (TLI.has(LibFunc::memset_pattern16) &&
|
|
||||||
MS->getName() == "memset_pattern16") {
|
|
||||||
FunctionType *MemsetType = MS->getFunctionType();
|
|
||||||
if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 &&
|
|
||||||
isa<PointerType>(MemsetType->getParamType(0)) &&
|
|
||||||
isa<PointerType>(MemsetType->getParamType(1)) &&
|
|
||||||
isa<IntegerType>(MemsetType->getParamType(2)))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getModRefBehavior - Return the behavior when calling the given call site.
|
/// getModRefBehavior - Return the behavior when calling the given call site.
|
||||||
AliasAnalysis::ModRefBehavior
|
AliasAnalysis::ModRefBehavior
|
||||||
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
|
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
|
||||||
@ -711,93 +692,10 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) {
|
|||||||
if (F->onlyReadsMemory())
|
if (F->onlyReadsMemory())
|
||||||
Min = OnlyReadsMemory;
|
Min = OnlyReadsMemory;
|
||||||
|
|
||||||
const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
|
|
||||||
if (isMemsetPattern16(F, TLI))
|
|
||||||
Min = OnlyAccessesArgumentPointees;
|
|
||||||
|
|
||||||
// Otherwise be conservative.
|
// Otherwise be conservative.
|
||||||
return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
|
return ModRefBehavior(AliasAnalysis::getModRefBehavior(F) & Min);
|
||||||
}
|
}
|
||||||
|
|
||||||
AliasAnalysis::Location
|
|
||||||
BasicAliasAnalysis::getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
|
|
||||||
ModRefResult &Mask) {
|
|
||||||
Location Loc = AliasAnalysis::getArgLocation(CS, ArgIdx, Mask);
|
|
||||||
const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
|
|
||||||
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
|
|
||||||
if (II != nullptr)
|
|
||||||
switch (II->getIntrinsicID()) {
|
|
||||||
default: break;
|
|
||||||
case Intrinsic::memset:
|
|
||||||
case Intrinsic::memcpy:
|
|
||||||
case Intrinsic::memmove: {
|
|
||||||
assert((ArgIdx == 0 || ArgIdx == 1) &&
|
|
||||||
"Invalid argument index for memory intrinsic");
|
|
||||||
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
|
|
||||||
Loc.Size = LenCI->getZExtValue();
|
|
||||||
assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
|
|
||||||
"Memory intrinsic location pointer not argument?");
|
|
||||||
Mask = ArgIdx ? Ref : Mod;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Intrinsic::lifetime_start:
|
|
||||||
case Intrinsic::lifetime_end:
|
|
||||||
case Intrinsic::invariant_start: {
|
|
||||||
assert(ArgIdx == 1 && "Invalid argument index");
|
|
||||||
assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
|
|
||||||
"Intrinsic location pointer not argument?");
|
|
||||||
Loc.Size = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Intrinsic::invariant_end: {
|
|
||||||
assert(ArgIdx == 2 && "Invalid argument index");
|
|
||||||
assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
|
|
||||||
"Intrinsic location pointer not argument?");
|
|
||||||
Loc.Size = cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Intrinsic::arm_neon_vld1: {
|
|
||||||
assert(ArgIdx == 0 && "Invalid argument index");
|
|
||||||
assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
|
|
||||||
"Intrinsic location pointer not argument?");
|
|
||||||
// LLVM's vld1 and vst1 intrinsics currently only support a single
|
|
||||||
// vector register.
|
|
||||||
if (DL)
|
|
||||||
Loc.Size = DL->getTypeStoreSize(II->getType());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Intrinsic::arm_neon_vst1: {
|
|
||||||
assert(ArgIdx == 0 && "Invalid argument index");
|
|
||||||
assert(Loc.Ptr == II->getArgOperand(ArgIdx) &&
|
|
||||||
"Intrinsic location pointer not argument?");
|
|
||||||
if (DL)
|
|
||||||
Loc.Size = DL->getTypeStoreSize(II->getArgOperand(1)->getType());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can bound the aliasing properties of memset_pattern16 just as we can
|
|
||||||
// for memcpy/memset. This is particularly important because the
|
|
||||||
// LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
|
|
||||||
// whenever possible.
|
|
||||||
else if (CS.getCalledFunction() &&
|
|
||||||
isMemsetPattern16(CS.getCalledFunction(), TLI)) {
|
|
||||||
assert((ArgIdx == 0 || ArgIdx == 1) &&
|
|
||||||
"Invalid argument index for memset_pattern16");
|
|
||||||
if (ArgIdx == 1)
|
|
||||||
Loc.Size = 16;
|
|
||||||
else if (const ConstantInt *LenCI =
|
|
||||||
dyn_cast<ConstantInt>(CS.getArgument(2)))
|
|
||||||
Loc.Size = LenCI->getZExtValue();
|
|
||||||
assert(Loc.Ptr == CS.getArgument(ArgIdx) &&
|
|
||||||
"memset_pattern16 location pointer not argument?");
|
|
||||||
Mask = ArgIdx ? Ref : Mod;
|
|
||||||
}
|
|
||||||
// FIXME: Handle memset_pattern4 and memset_pattern8 also.
|
|
||||||
|
|
||||||
return Loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getModRefInfo - Check to see if the specified callsite can clobber the
|
/// getModRefInfo - Check to see if the specified callsite can clobber the
|
||||||
/// specified memory object. Since we only look at local properties of this
|
/// specified memory object. Since we only look at local properties of this
|
||||||
/// function, we really can't say much about this query. We do, however, use
|
/// function, we really can't say much about this query. We do, however, use
|
||||||
@ -850,8 +748,124 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
|
|||||||
return NoModRef;
|
return NoModRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
|
||||||
|
ModRefResult Min = ModRef;
|
||||||
|
|
||||||
|
// Finally, handle specific knowledge of intrinsics.
|
||||||
|
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction());
|
||||||
|
if (II != nullptr)
|
||||||
|
switch (II->getIntrinsicID()) {
|
||||||
|
default: break;
|
||||||
|
case Intrinsic::memcpy:
|
||||||
|
case Intrinsic::memmove: {
|
||||||
|
uint64_t Len = UnknownSize;
|
||||||
|
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
|
||||||
|
Len = LenCI->getZExtValue();
|
||||||
|
Value *Dest = II->getArgOperand(0);
|
||||||
|
Value *Src = II->getArgOperand(1);
|
||||||
|
// If it can't overlap the source dest, then it doesn't modref the loc.
|
||||||
|
if (isNoAlias(Location(Dest, Len), Loc)) {
|
||||||
|
if (isNoAlias(Location(Src, Len), Loc))
|
||||||
|
return NoModRef;
|
||||||
|
// If it can't overlap the dest, then worst case it reads the loc.
|
||||||
|
Min = Ref;
|
||||||
|
} else if (isNoAlias(Location(Src, Len), Loc)) {
|
||||||
|
// If it can't overlap the source, then worst case it mutates the loc.
|
||||||
|
Min = Mod;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Intrinsic::memset:
|
||||||
|
// Since memset is 'accesses arguments' only, the AliasAnalysis base class
|
||||||
|
// will handle it for the variable length case.
|
||||||
|
if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) {
|
||||||
|
uint64_t Len = LenCI->getZExtValue();
|
||||||
|
Value *Dest = II->getArgOperand(0);
|
||||||
|
if (isNoAlias(Location(Dest, Len), Loc))
|
||||||
|
return NoModRef;
|
||||||
|
}
|
||||||
|
// We know that memset doesn't load anything.
|
||||||
|
Min = Mod;
|
||||||
|
break;
|
||||||
|
case Intrinsic::lifetime_start:
|
||||||
|
case Intrinsic::lifetime_end:
|
||||||
|
case Intrinsic::invariant_start: {
|
||||||
|
uint64_t PtrSize =
|
||||||
|
cast<ConstantInt>(II->getArgOperand(0))->getZExtValue();
|
||||||
|
if (isNoAlias(Location(II->getArgOperand(1),
|
||||||
|
PtrSize,
|
||||||
|
II->getMetadata(LLVMContext::MD_tbaa)),
|
||||||
|
Loc))
|
||||||
|
return NoModRef;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Intrinsic::invariant_end: {
|
||||||
|
uint64_t PtrSize =
|
||||||
|
cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
|
||||||
|
if (isNoAlias(Location(II->getArgOperand(2),
|
||||||
|
PtrSize,
|
||||||
|
II->getMetadata(LLVMContext::MD_tbaa)),
|
||||||
|
Loc))
|
||||||
|
return NoModRef;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Intrinsic::arm_neon_vld1: {
|
||||||
|
// LLVM's vld1 and vst1 intrinsics currently only support a single
|
||||||
|
// vector register.
|
||||||
|
uint64_t Size =
|
||||||
|
DL ? DL->getTypeStoreSize(II->getType()) : UnknownSize;
|
||||||
|
if (isNoAlias(Location(II->getArgOperand(0), Size,
|
||||||
|
II->getMetadata(LLVMContext::MD_tbaa)),
|
||||||
|
Loc))
|
||||||
|
return NoModRef;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Intrinsic::arm_neon_vst1: {
|
||||||
|
uint64_t Size =
|
||||||
|
DL ? DL->getTypeStoreSize(II->getArgOperand(1)->getType()) : UnknownSize;
|
||||||
|
if (isNoAlias(Location(II->getArgOperand(0), Size,
|
||||||
|
II->getMetadata(LLVMContext::MD_tbaa)),
|
||||||
|
Loc))
|
||||||
|
return NoModRef;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We can bound the aliasing properties of memset_pattern16 just as we can
|
||||||
|
// for memcpy/memset. This is particularly important because the
|
||||||
|
// LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
|
||||||
|
// whenever possible.
|
||||||
|
else if (TLI.has(LibFunc::memset_pattern16) &&
|
||||||
|
CS.getCalledFunction() &&
|
||||||
|
CS.getCalledFunction()->getName() == "memset_pattern16") {
|
||||||
|
const Function *MS = CS.getCalledFunction();
|
||||||
|
FunctionType *MemsetType = MS->getFunctionType();
|
||||||
|
if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 &&
|
||||||
|
isa<PointerType>(MemsetType->getParamType(0)) &&
|
||||||
|
isa<PointerType>(MemsetType->getParamType(1)) &&
|
||||||
|
isa<IntegerType>(MemsetType->getParamType(2))) {
|
||||||
|
uint64_t Len = UnknownSize;
|
||||||
|
if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2)))
|
||||||
|
Len = LenCI->getZExtValue();
|
||||||
|
const Value *Dest = CS.getArgument(0);
|
||||||
|
const Value *Src = CS.getArgument(1);
|
||||||
|
// If it can't overlap the source dest, then it doesn't modref the loc.
|
||||||
|
if (isNoAlias(Location(Dest, Len), Loc)) {
|
||||||
|
// Always reads 16 bytes of the source.
|
||||||
|
if (isNoAlias(Location(Src, 16), Loc))
|
||||||
|
return NoModRef;
|
||||||
|
// If it can't overlap the dest, then worst case it reads the loc.
|
||||||
|
Min = Ref;
|
||||||
|
// Always reads 16 bytes of the source.
|
||||||
|
} else if (isNoAlias(Location(Src, 16), Loc)) {
|
||||||
|
// If it can't overlap the source, then worst case it mutates the loc.
|
||||||
|
Min = Mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The AliasAnalysis base class has some smarts, lets use them.
|
// The AliasAnalysis base class has some smarts, lets use them.
|
||||||
return AliasAnalysis::getModRefInfo(CS, Loc);
|
return ModRefResult(AliasAnalysis::getModRefInfo(CS, Loc) & Min);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
|
/// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "llvm/Analysis/Passes.h"
|
#include "llvm/Analysis/Passes.h"
|
||||||
#include "llvm/Analysis/AliasAnalysis.h"
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -54,13 +53,6 @@ namespace {
|
|||||||
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override {
|
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Location getArgLocation(ImmutableCallSite CS, unsigned ArgIdx,
|
|
||||||
ModRefResult &Mask) override {
|
|
||||||
Mask = ModRef;
|
|
||||||
return Location(CS.getArgument(ArgIdx), UnknownSize,
|
|
||||||
CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa));
|
|
||||||
}
|
|
||||||
|
|
||||||
ModRefResult getModRefInfo(ImmutableCallSite CS,
|
ModRefResult getModRefInfo(ImmutableCallSite CS,
|
||||||
const Location &Loc) override {
|
const Location &Loc) override {
|
||||||
return ModRef;
|
return ModRef;
|
||||||
|
@ -1,221 +0,0 @@
|
|||||||
; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
|
|
||||||
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
|
|
||||||
target triple = "arm-apple-ios"
|
|
||||||
|
|
||||||
declare <8 x i16> @llvm.arm.neon.vld1.v8i16(i8*, i32) nounwind readonly
|
|
||||||
declare void @llvm.arm.neon.vst1.v8i16(i8*, <8 x i16>, i32) nounwind
|
|
||||||
|
|
||||||
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
|
|
||||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
|
||||||
|
|
||||||
define <8 x i16> @test1(i8* %p, <8 x i16> %y) {
|
|
||||||
entry:
|
|
||||||
%q = getelementptr i8* %p, i64 16
|
|
||||||
%a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
|
|
||||||
call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
|
||||||
%b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) nounwind
|
|
||||||
%c = add <8 x i16> %a, %b
|
|
||||||
ret <8 x i16> %c
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test1:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %p, i8* %q
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %p <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %q <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %p <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %p <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %q <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
|
||||||
; CHECK: NoModRef: %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16) <-> %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> %a = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1
|
|
||||||
; CHECK: NoModRef: %b = call <8 x i16> @llvm.arm.neon.vld1.v8i16(i8* %p, i32 16) #1 <-> call void @llvm.arm.neon.vst1.v8i16(i8* %q, <8 x i16> %y, i32 16)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2(i8* %P, i8* %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2:
|
|
||||||
|
|
||||||
; CHECK: MayAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2a:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2b(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
%R = getelementptr i8* %P, i64 12
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2b:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %R
|
|
||||||
; CHECK: NoAlias: i8* %Q, i8* %R
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2c(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
%R = getelementptr i8* %P, i64 11
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2c:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %R
|
|
||||||
; CHECK: NoAlias: i8* %Q, i8* %R
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2d(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
%R = getelementptr i8* %P, i64 -12
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2d:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %R
|
|
||||||
; CHECK: NoAlias: i8* %Q, i8* %R
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test2e(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
%R = getelementptr i8* %P, i64 -11
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test2e:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %R
|
|
||||||
; CHECK: NoAlias: i8* %Q, i8* %R
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test3(i8* %P, i8* %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test3:
|
|
||||||
|
|
||||||
; CHECK: MayAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test3a(i8* noalias %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test3a:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test4(i8* %P, i8* noalias %Q) nounwind ssp {
|
|
||||||
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test4:
|
|
||||||
|
|
||||||
; CHECK: NoAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @test5(i8* %P, i8* %Q, i8* %R) nounwind ssp {
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
; CHECK-LABEL: Function: test5:
|
|
||||||
|
|
||||||
; CHECK: MayAlias: i8* %P, i8* %Q
|
|
||||||
; CHECK: MayAlias: i8* %P, i8* %R
|
|
||||||
; CHECK: MayAlias: i8* %Q, i8* %R
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false)
|
|
||||||
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i32 1, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i32 1, i1 false)
|
|
||||||
}
|
|
||||||
|
|
||||||
attributes #0 = { nounwind }
|
|
Loading…
x
Reference in New Issue
Block a user