mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-24 21:14:56 +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
|
||||
};
|
||||
|
||||
/// 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.
|
||||
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
|
||||
|
||||
|
@ -60,13 +60,6 @@ bool AliasAnalysis::pointsToConstantMemory(const Location &Loc,
|
||||
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) {
|
||||
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
|
||||
AA->deleteValue(V);
|
||||
@ -98,26 +91,22 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
|
||||
|
||||
if (onlyAccessesArgPointees(MRB)) {
|
||||
bool doesAlias = false;
|
||||
ModRefResult AllArgsMask = NoModRef;
|
||||
if (doesAccessArgPointees(MRB)) {
|
||||
MDNode *CSTag = CS.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
|
||||
AI != AE; ++AI) {
|
||||
const Value *Arg = *AI;
|
||||
if (!Arg->getType()->isPointerTy())
|
||||
continue;
|
||||
ModRefResult ArgMask;
|
||||
Location CSLoc =
|
||||
getArgLocation(CS, (unsigned) std::distance(CS.arg_begin(), AI),
|
||||
ArgMask);
|
||||
Location CSLoc(Arg, UnknownSize, CSTag);
|
||||
if (!isNoAlias(CSLoc, Loc)) {
|
||||
doesAlias = true;
|
||||
AllArgsMask = ModRefResult(AllArgsMask | ArgMask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!doesAlias)
|
||||
return NoModRef;
|
||||
Mask = ModRefResult(Mask & AllArgsMask);
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
AliasAnalysis::ModRefResult R = NoModRef;
|
||||
if (doesAccessArgPointees(CS2B)) {
|
||||
MDNode *CS2Tag = CS2.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||
for (ImmutableCallSite::arg_iterator
|
||||
I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
|
||||
const Value *Arg = *I;
|
||||
if (!Arg->getType()->isPointerTy())
|
||||
continue;
|
||||
ModRefResult ArgMask;
|
||||
Location CS2Loc =
|
||||
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);
|
||||
Location CS2Loc(Arg, UnknownSize, CS2Tag);
|
||||
R = ModRefResult((R | getModRefInfo(CS1, CS2Loc)) & Mask);
|
||||
if (R == Mask)
|
||||
break;
|
||||
}
|
||||
@ -190,16 +170,14 @@ AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
|
||||
if (onlyAccessesArgPointees(CS1B)) {
|
||||
AliasAnalysis::ModRefResult R = NoModRef;
|
||||
if (doesAccessArgPointees(CS1B)) {
|
||||
MDNode *CS1Tag = CS1.getInstruction()->getMetadata(LLVMContext::MD_tbaa);
|
||||
for (ImmutableCallSite::arg_iterator
|
||||
I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) {
|
||||
const Value *Arg = *I;
|
||||
if (!Arg->getType()->isPointerTy())
|
||||
continue;
|
||||
ModRefResult ArgMask;
|
||||
Location CS1Loc =
|
||||
getArgLocation(CS1, (unsigned) std::distance(CS1.arg_begin(), I),
|
||||
ArgMask);
|
||||
if ((getModRefInfo(CS2, CS1Loc) & ArgMask) != NoModRef) {
|
||||
Location CS1Loc(Arg, UnknownSize, CS1Tag);
|
||||
if (getModRefInfo(CS2, CS1Loc) != NoModRef) {
|
||||
R = Mask;
|
||||
break;
|
||||
}
|
||||
|
@ -490,10 +490,6 @@ namespace {
|
||||
/// global) or not.
|
||||
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
|
||||
/// call site.
|
||||
ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
|
||||
@ -657,21 +653,6 @@ BasicAliasAnalysis::pointsToConstantMemory(const Location &Loc, bool OrLocal) {
|
||||
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.
|
||||
AliasAnalysis::ModRefBehavior
|
||||
BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
|
||||
@ -711,93 +692,10 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) {
|
||||
if (F->onlyReadsMemory())
|
||||
Min = OnlyReadsMemory;
|
||||
|
||||
const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfo>();
|
||||
if (isMemsetPattern16(F, TLI))
|
||||
Min = OnlyAccessesArgumentPointees;
|
||||
|
||||
// Otherwise be conservative.
|
||||
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
|
||||
/// 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
|
||||
@ -850,8 +748,124 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
|
||||
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.
|
||||
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
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/Pass.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -54,13 +53,6 @@ namespace {
|
||||
bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override {
|
||||
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,
|
||||
const Location &Loc) override {
|
||||
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…
Reference in New Issue
Block a user