[AAEval] Make compatible with opaque pointers

With opaque pointers, we cannot use the pointer element type to
determine the LocationSize for the AA query. Instead, -aa-eval
tests are now required to have an explicit load or store for any
pointer they want to compute alias results for, and the load/store
types are used to determine the location size.

This may affect ordering of results, and sorting within one result,
as the type is not considered part of the sorted string anymore.

To somewhat minimize the churn, printing still uses faux typed
pointer notation.
This commit is contained in:
Nikita Popov 2022-03-15 10:18:19 +01:00
parent 75acad41bc
commit 57d57b1afd
93 changed files with 1655 additions and 767 deletions

View File

@ -39,30 +39,48 @@ static cl::opt<bool> PrintMustModRef("print-mustmodref", cl::ReallyHidden);
static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden);
static void PrintResults(AliasResult AR, bool P, const Value *V1,
const Value *V2, const Module *M) {
static void PrintResults(AliasResult AR, bool P,
std::pair<const Value *, Type *> Loc1,
std::pair<const Value *, Type *> Loc2,
const Module *M) {
if (PrintAll || P) {
Type *Ty1 = Loc1.second, *Ty2 = Loc2.second;
unsigned AS1 = Loc1.first->getType()->getPointerAddressSpace();
unsigned AS2 = Loc2.first->getType()->getPointerAddressSpace();
std::string o1, o2;
{
raw_string_ostream os1(o1), os2(o2);
V1->printAsOperand(os1, true, M);
V2->printAsOperand(os2, true, M);
Loc1.first->printAsOperand(os1, false, M);
Loc2.first->printAsOperand(os2, false, M);
}
if (o2 < o1) {
std::swap(o1, o2);
std::swap(Ty1, Ty2);
std::swap(AS1, AS2);
// Change offset sign for the local AR, for printing only.
AR.swap();
}
errs() << " " << AR << ":\t" << o1 << ", " << o2 << "\n";
errs() << " " << AR << ":\t";
Ty1->print(errs(), false, /* NoDetails */ true);
if (AS1 != 0)
errs() << " addrspace(" << AS1 << ")";
errs() << "* " << o1 << ", ";
Ty2->print(errs(), false, /* NoDetails */ true);
if (AS2 != 0)
errs() << " addrspace(" << AS2 << ")";
errs() << "* " << o2 << "\n";
}
}
static inline void PrintModRefResults(const char *Msg, bool P, Instruction *I,
Value *Ptr, Module *M) {
static inline void PrintModRefResults(
const char *Msg, bool P, Instruction *I,
std::pair<const Value *, Type *> Loc, Module *M) {
if (PrintAll || P) {
errs() << " " << Msg << ": Ptr: ";
Ptr->printAsOperand(errs(), true, M);
Loc.second->print(errs(), false, /* NoDetails */ true);
errs() << "* ";
Loc.first->printAsOperand(errs(), false, M);
errs() << "\t<->" << *I << '\n';
}
}
@ -97,38 +115,21 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
++FunctionCount;
SetVector<Value *> Pointers;
SetVector<std::pair<const Value *, Type *>> Pointers;
SmallSetVector<CallBase *, 16> Calls;
SetVector<Value *> Loads;
SetVector<Value *> Stores;
for (auto &I : F.args())
if (I.getType()->isPointerTy()) // Add all pointer arguments.
Pointers.insert(&I);
for (Instruction &Inst : instructions(F)) {
if (Inst.getType()->isPointerTy()) // Add all pointer instructions.
Pointers.insert(&Inst);
if (EvalAAMD && isa<LoadInst>(&Inst))
Loads.insert(&Inst);
if (EvalAAMD && isa<StoreInst>(&Inst))
Stores.insert(&Inst);
if (auto *Call = dyn_cast<CallBase>(&Inst)) {
Value *Callee = Call->getCalledOperand();
// Skip actual functions for direct function calls.
if (!isa<Function>(Callee) && isInterestingPointer(Callee))
Pointers.insert(Callee);
// Consider formals.
for (Use &DataOp : Call->data_ops())
if (isInterestingPointer(DataOp))
Pointers.insert(DataOp);
Calls.insert(Call);
} else {
// Consider all operands.
for (Use &Op : Inst.operands())
if (isInterestingPointer(Op))
Pointers.insert(Op);
}
if (auto *LI = dyn_cast<LoadInst>(&Inst)) {
Pointers.insert({LI->getPointerOperand(), LI->getType()});
Loads.insert(LI);
} else if (auto *SI = dyn_cast<StoreInst>(&Inst)) {
Pointers.insert({SI->getPointerOperand(),
SI->getValueOperand()->getType()});
Stores.insert(SI);
} else if (auto *CB = dyn_cast<CallBase>(&Inst))
Calls.insert(CB);
}
if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias ||
@ -137,20 +138,12 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
<< " pointers, " << Calls.size() << " call sites\n";
// 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::afterPointer();
Type *I1ElTy = (*I1)->getType()->getPointerElementType();
if (I1ElTy->isSized())
I1Size = LocationSize::precise(DL.getTypeStoreSize(I1ElTy));
for (SetVector<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
auto I2Size = LocationSize::afterPointer();
Type *I2ElTy = (*I2)->getType()->getPointerElementType();
if (I2ElTy->isSized())
I2Size = LocationSize::precise(DL.getTypeStoreSize(I2ElTy));
AliasResult AR = AA.alias(*I1, I1Size, *I2, I2Size);
for (auto I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) {
LocationSize Size1 = LocationSize::precise(DL.getTypeStoreSize(I1->second));
for (auto I2 = Pointers.begin(); I2 != I1; ++I2) {
LocationSize Size2 =
LocationSize::precise(DL.getTypeStoreSize(I2->second));
AliasResult AR = AA.alias(I1->first, Size1, I2->first, Size2);
switch (AR) {
case AliasResult::NoAlias:
PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
@ -229,13 +222,10 @@ 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::afterPointer();
Type *ElTy = Pointer->getType()->getPointerElementType();
if (ElTy->isSized())
Size = LocationSize::precise(DL.getTypeStoreSize(ElTy));
switch (AA.getModRefInfo(Call, Pointer, Size)) {
for (const auto &Pointer : Pointers) {
LocationSize Size =
LocationSize::precise(DL.getTypeStoreSize(Pointer.second));
switch (AA.getModRefInfo(Call, Pointer.first, Size)) {
case ModRefInfo::NoModRef:
PrintModRefResults("NoModRef", PrintNoModRef, Call, Pointer,
F.getParent());

View File

@ -18,6 +18,11 @@ define void @test0(%T addrspace(100)* %P) {
%C = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1
%D = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 0
%E = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 5
load %T, %T addrspace(100)* %A
load i32, i32 addrspace(100)* %B
load [10 x i8], [10 x i8] addrspace(100)* %C
load i8, i8 addrspace(100)* %D
load i8, i8 addrspace(100)* %E
ret void
}
@ -37,6 +42,8 @@ define void @test1(double addrspace(100)* %P, i128 %i) {
%i69 = add i128 %i, 590295810358705651712
%A = getelementptr double, double addrspace(100)* %P, i128 %i70
%B = getelementptr double, double addrspace(100)* %P, i128 %i69
load double, double addrspace(100)* %A
load double, double addrspace(100)* %B
ret void
}
@ -56,5 +63,7 @@ define void @test2(double addrspace(100)* %P, i128 %i) {
%j70 = add i128 %i69, 590295810358705651712
%A = getelementptr double, double addrspace(100)* %P, i128 %i70
%C = getelementptr double, double addrspace(100)* %P, i128 %j70
load double, double addrspace(100)* %A
load double, double addrspace(100)* %C
ret void
}

View File

@ -26,6 +26,7 @@ no_exit: ; preds = %no_exit, %entry
loopexit: ; preds = %no_exit, %entry
%Y.0.1 = phi i32 [ 0, %entry ], [ %tmp.13, %no_exit ] ; <i32> [#uses=1]
%tmp.4 = getelementptr [3 x [3 x i32]], [3 x [3 x i32]]* %X, i32 0, i32 0 ; <[3 x i32]*> [#uses=1]
load [3 x i32], [3 x i32]* %tmp.4
%tmp.15 = call i32 (...) @foo( [3 x i32]* %tmp.4, i32 %Y.0.1 ) ; <i32> [#uses=0]
ret void
}

View File

@ -48,254 +48,310 @@ define void @caller_a(double* %arg_a0,
}
; CHECK: Function: caller_a: 16 pointers, 8 call sites
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %arg_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_arg_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double** %indirect_a1
; CHECK-NEXT: MayAlias: double** %indirect_a0, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %noescape_alloca_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %normal_ret_a1, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %normal_ret_a1, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double** %indirect_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noalias_ret_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a1
; CHECK-NEXT: MayAlias: double* %loaded_a0, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %loaded_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a1
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a1
; CHECK-NEXT: MayAlias: double* %loaded_a1, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %loaded_a1, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a1
; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a1
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %loaded_a1
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: MayAlias: double** %indirect_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %loaded_a0
; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %loaded_a0
; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %loaded_a1
; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %arg_a1
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %escape_alloca_a1
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %noescape_alloca_a1
; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a0
; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a1
; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a0
; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a1
; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noalias_ret_a1
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %noalias_ret_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %noalias_ret_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double* %noalias_ret_a1 <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %noescape_alloca_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %escape_alloca_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noescape_alloca_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %noescape_alloca_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %normal_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: Ptr: double* %loaded_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a0 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: NoModRef: Ptr: double* %noalias_ret_a1 <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: %normal_ret_a0 = call double* @normal_returner() <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: %normal_ret_a1 = call double* @normal_returner() <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: %noalias_ret_a0 = call double* @noalias_returner() <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: %noalias_ret_a1 = call double* @noalias_returner() <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a0) <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK-NEXT: Both ModRef: call void @callee(double* %escape_alloca_a1) <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a0) <-> call void @nocap_callee(double* %noescape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> %normal_ret_a0 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> %normal_ret_a1 = call double* @normal_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> %noalias_ret_a0 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> %noalias_ret_a1 = call double* @noalias_returner()
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> call void @callee(double* %escape_alloca_a0)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> call void @callee(double* %escape_alloca_a1)
; CHECK-NEXT: Both ModRef: call void @nocap_callee(double* %noescape_alloca_a1) <-> call void @nocap_callee(double* %noescape_alloca_a0)
; CHECK: ===== Alias Analysis Evaluator Report =====
; CHECK-NEXT: 120 Total Alias Queries Performed
; CHECK-NEXT: 84 no alias responses (70.0%)

View File

@ -10,12 +10,13 @@ define void @test1(double* %ptr, i32 %skip) {
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt)
;
load double, double* %ptr
%gt = icmp sgt i32 %skip, -1
call void @llvm.assume(i1 %gt)
%stride = add nsw nuw i32 %skip, 6
@ -23,6 +24,7 @@ define void @test1(double* %ptr, i32 %skip) {
%lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
%col.ptr.2= getelementptr double, double* %ptr, i32 %stride
%col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
load double, double* %col.ptr.2
%lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
%res.1 = fadd <6 x double> %lv.1, %lv.1
%res.2 = fadd <6 x double> %lv.2, %lv.2
@ -39,12 +41,14 @@ define void @test2(double* %ptr, i32 %skip) {
; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
;
load double, double* %ptr
%stride = add nsw nuw i32 %skip, 6
%col.ptr.1 = bitcast double* %ptr to <6 x double>*
%lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
%col.ptr.2= getelementptr double, double* %ptr, i32 %stride
%col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
load double, double* %col.ptr.2
%col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
%lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
%res.1 = fadd <6 x double> %lv.1, %lv.1
@ -65,18 +69,20 @@ define void @test3(double* %ptr, i32 %skip) {
; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt)
;
load double, double* %ptr
%gt = icmp sgt i32 %skip, -3
call void @llvm.assume(i1 %gt)
%stride = add nsw nuw i32 %skip, 6
%col.ptr.1 = bitcast double* %ptr to <6 x double>*
%lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
%col.ptr.2= getelementptr double, double* %ptr, i32 %stride
%col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
load double, double* %col.ptr.2
%col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
%lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
%res.1 = fadd <6 x double> %lv.1, %lv.1
@ -94,18 +100,20 @@ define void @test4(double* %ptr, i32 %skip) {
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast
; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt)
; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt)
;
load double, double* %ptr
%gt = icmp sge i32 %skip, 0
call void @llvm.assume(i1 %gt)
%stride = add nsw nuw i32 %skip, 6
%col.ptr.1 = bitcast double* %ptr to <6 x double>*
%lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
%col.ptr.2= getelementptr double, double* %ptr, i32 %stride
%col.ptr.2 = getelementptr double, double* %ptr, i32 %stride
load double, double* %col.ptr.2
%col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
%lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
%res.1 = fadd <6 x double> %lv.1, %lv.1
@ -122,11 +130,13 @@ define void @symmetry([0 x i8]* %ptr, i32 %a, i32 %b, i32 %c) {
%b.cmp = icmp slt i32 %b, 0
call void @llvm.assume(i1 %b.cmp)
%gep1 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %b
load i8, i8* %gep1
call void @barrier()
%c.cmp = icmp sgt i32 %c, -1
call void @llvm.assume(i1 %c.cmp)
%c.off = add nuw nsw i32 %c, 1
%gep2 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %c.off
load i8, i8* %gep2
ret void
}
@ -142,6 +152,9 @@ define void @shl_of_non_negative(i8* %ptr, i64 %a) {
%ptr.a = getelementptr i8, i8* %ptr, i64 %a
%shl = shl i64 %a, 1
%ptr.shl = getelementptr i8, i8* %ptr, i64 %shl
load i8, i8* %ptr.a
load i8, i8* %ptr.neg
load i8, i8* %ptr.shl
ret void
}
@ -157,6 +170,9 @@ define void @shl_nsw_of_non_negative(i8* %ptr, i64 %a) {
%ptr.a = getelementptr i8, i8* %ptr, i64 %a
%shl = shl nsw i64 %a, 1
%ptr.shl = getelementptr i8, i8* %ptr, i64 %shl
load i8, i8* %ptr.a
load i8, i8* %ptr.neg
load i8, i8* %ptr.shl
ret void
}

View File

@ -7,6 +7,8 @@ declare void @llvm.assume(i1) #0
define void @test1(i8* %P, i8* %Q) nounwind ssp {
tail call void @llvm.assume(i1 true)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
load i8, i8* %P
load i8, i8* %Q
ret void
; CHECK-LABEL: Function: test1:
@ -24,6 +26,8 @@ define void @test1(i8* %P, i8* %Q) nounwind ssp {
define void @test2(i8* %P, i8* %Q) nounwind ssp {
tail call void @llvm.assume(i1 true) [ "nonnull"(i8* %P) ]
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
load i8, i8* %P
load i8, i8* %Q
ret void
; CHECK-LABEL: Function: test2:

View File

@ -9,6 +9,7 @@ define void @test_memset_element_unordered_atomic_const_size(i8* noalias %a) {
; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %a, i8 0, i64 4, i32 1)
;
entry:
load i8, i8* %a
call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 1 %a, i8 0, i64 4, i32 1)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -24,6 +25,7 @@ define void @test_memset_element_unordered_atomic_variable_size(i8* noalias %a,
; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %a, i8 0, i64 %n, i32 1)
;
entry:
load i8, i8* %a
call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 1 %a, i8 0, i64 %n, i32 1)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -44,6 +46,8 @@ define void @test_memcpy_element_unordered_atomic_const_size(i8* noalias %a, i8*
; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 4, i32 1)
;
entry:
load i8, i8* %a
load i8, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -66,6 +70,8 @@ define void @test_memcpy_element_unordered_atomic_variable_size(i8* noalias %a,
; CHECK-NEXT: Just Mod: Ptr: i8* %b.gep.5 <-> call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 %n, i32 1)
;
entry:
load i8, i8* %a
load i8, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -90,6 +96,8 @@ define void @test_memmove_element_unordered_atomic_const_size(i8* noalias %a, i8
; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 4, i32 1)
;
entry:
load i8, i8* %a
load i8, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -112,6 +120,8 @@ define void @test_memmove_element_unordered_atomic_variable_size(i8* noalias %a,
; CHECK-NEXT: Just Mod: Ptr: i8* %b.gep.5 <-> call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 %n, i32 1)
;
entry:
load i8, i8* %a
load i8, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5

View File

@ -12,6 +12,8 @@ define void @f() {
%idxprom5 = zext i32 %add4 to i64
%arrayidx6 = getelementptr inbounds i32, i32* @c, i64 %idxprom5
%arrayidx = getelementptr inbounds i32, i32* @c, i64 %idxprom
load i32, i32* %arrayidx
load i32, i32* %arrayidx6
ret void
}

View File

@ -18,6 +18,10 @@ define void @compute1(i32 %num.0.lcssa, i32* %out) {
%add12 = or i32 %num.0.lcssa, 2
%idxprom13 = zext i32 %add12 to i64
%arrayidx14 = getelementptr inbounds i32, i32* %out, i64 %idxprom13
load i32, i32* %out
load i32, i32* %arrayidx8
load i32, i32* %arrayidx11
load i32, i32* %arrayidx14
ret void
}
@ -27,5 +31,7 @@ define void @compute2(i32 %num, i32* %out.addr) {
%add9 = add i32 %num, 1
%idxprom10 = zext i32 %add9 to i64
%arrayidx11 = getelementptr inbounds i32, i32* %out.addr, i64 %idxprom10
load i32, i32* %out.addr
load i32, i32* %arrayidx11
ret void
}

View File

@ -14,6 +14,7 @@ declare void @func()
define void @test(i8* noalias %p) {
entry:
load i8, i8* %p
call void @readonly_attr(i8* %p)
call void @readonly_func(i8* %p)

View File

@ -10,6 +10,8 @@ declare void @a_readonly_func(i8*) #1
declare void @a_writeonly_func(i8*) #2
define void @test2(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
@ -26,6 +28,8 @@ define void @test2(i8* %P, i8* %Q) #3 {
}
define void @test2_atomic(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
ret void
@ -42,6 +46,8 @@ define void @test2_atomic(i8* %P, i8* %Q) #3 {
}
define void @test2a(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
@ -58,8 +64,11 @@ define void @test2a(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test2b(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 12
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
@ -79,8 +88,11 @@ define void @test2b(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test2c(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 11
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
@ -100,8 +112,11 @@ define void @test2c(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test2d(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 -12
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
@ -121,8 +136,11 @@ define void @test2d(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test2e(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 -11
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
@ -142,6 +160,8 @@ define void @test2e(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test3(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
@ -158,6 +178,8 @@ define void @test3(i8* %P, i8* %Q) #3 {
}
define void @test3a(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
@ -174,6 +196,8 @@ define void @test3a(i8* noalias %P, i8* noalias %Q) #3 {
}
define void @test4(i8* %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
@ -190,6 +214,9 @@ define void @test4(i8* %P, i8* noalias %Q) #3 {
}
define void @test5(i8* %P, i8* %Q, i8* %R) #3 {
load i8, i8* %P
load i8, i8* %Q
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
ret void
@ -210,6 +237,9 @@ define void @test5(i8* %P, i8* %Q, i8* %R) #3 {
}
define void @test5a(i8* noalias %P, i8* noalias %Q, i8* noalias %R) nounwind ssp {
load i8, i8* %P
load i8, i8* %Q
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
ret void
@ -230,6 +260,7 @@ define void @test5a(i8* noalias %P, i8* noalias %Q, i8* noalias %R) nounwind ssp
}
define void @test6(i8* %P) #3 {
load i8, i8* %P
call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false)
call void @a_readonly_func(i8* %P)
ret void
@ -243,6 +274,7 @@ define void @test6(i8* %P) #3 {
}
define void @test7(i8* %P) #3 {
load i8, i8* %P
call void @a_writeonly_func(i8* %P)
call void @a_readonly_func(i8* %P)
ret void
@ -262,6 +294,8 @@ declare void @an_argmemonly_func(i8*) #0
define void @test8(i8* %p) {
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p)
call void @an_inaccessiblememonly_func()
call void @a_writeonly_func(i8* %q)
@ -302,6 +336,8 @@ entry:
declare void @another_argmemonly_func(i8*, i8*) #0
define void @test8a(i8* noalias %p, i8* noalias %q) {
entry:
load i8, i8* %p
load i8, i8* %q
call void @another_argmemonly_func(i8* %p, i8* %q)
ret void
@ -311,6 +347,8 @@ entry:
}
define void @test8b(i8* %p, i8* %q) {
entry:
load i8, i8* %p
load i8, i8* %q
call void @another_argmemonly_func(i8* %p, i8* %q)
ret void
@ -325,6 +363,8 @@ define void @test9(i8* %p) {
; CHECK-LABEL: Function: test9
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p) [ "unknown"() ]
call void @an_inaccessiblememonly_func() [ "unknown"() ]
call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
@ -358,6 +398,8 @@ define void @test10(i8* %p) {
; CHECK-LABEL: Function: test10
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]

View File

@ -11,12 +11,15 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; CHECK: MustAlias: i16* %bigbase, i8* %phi
define i8 @foo(i8* %base, i1 %x, i1 %w) {
entry:
load i8, i8* %base
br i1 %w, label %wa, label %wb
wa:
%wwa = bitcast i8* %base to i8*
load i8, i8* %wwa
br label %wc
wb:
%wwb = bitcast i8* %base to i8*
load i8, i8* %wwb
br label %wc
wc:
%first = phi i8* [ %wwa, %wa ], [ %wwb, %wb ]

View File

@ -9,6 +9,7 @@ declare void @llvm.experimental.deoptimize.void(...)
declare void @unknown_but_readonly() readonly
define void @test1(i8* %p) {
load i8, i8* %p
call void(...) @llvm.experimental.deoptimize.void() [ "deopt"() ]
ret void
@ -26,6 +27,8 @@ define i32 @test_memcpy_with_deopt() {
%A = alloca i8
%B = alloca i8
load i8, i8* %A
load i8, i8* %B
store i32 2, i32* @G1 ;; Not referenced by semantics of memcpy but still may be read due to "deopt"
@ -43,6 +46,8 @@ define i32 @test_memmove_with_deopt() {
%A = alloca i8
%B = alloca i8
load i8, i8* %A
load i8, i8* %B
store i32 2, i32* @G1 ;; Not referenced by semantics of memcpy but still may be read due to "deopt"

View File

@ -7,7 +7,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define i64 @global_and_deref_arg_1(i64* dereferenceable(8) %arg) nofree nosync {
; CHECK: Function: global_and_deref_arg_1: 2 pointers, 0 call sites
; CHECK-NEXT: NoAlias: i32* @G, i64* %arg
; CHECK-NEXT: NoAlias: i64* %arg, i32* @G
bb:
store i64 1, i64* %arg, align 8
store i32 0, i32* @G, align 4
@ -27,7 +27,7 @@ bb:
define i32 @byval_and_deref_arg_1(i32* byval(i32) %obj, i64* dereferenceable(8) %arg) nofree nosync {
; CHECK: Function: byval_and_deref_arg_1: 2 pointers, 0 call sites
; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg
; CHECK-NEXT: NoAlias: i64* %arg, i32* %obj
bb:
store i32 1, i32* %obj, align 4
store i64 0, i64* %arg, align 8
@ -80,7 +80,7 @@ bb:
define i64 @global_and_deref_arg_non_deref_1(i64* dereferenceable(2) %arg) nofree nosync {
; CHECK: Function: global_and_deref_arg_non_deref_1: 2 pointers, 0 call sites
; CHECK-NEXT: NoAlias: i32* @G, i64* %arg
; CHECK-NEXT: NoAlias: i64* %arg, i32* @G
bb:
store i64 1, i64* %arg, align 8
store i32 0, i32* @G, align 4
@ -101,7 +101,7 @@ bb:
define i32 @byval_and_deref_arg_non_deref_1(i32* byval(i32) %obj, i64* dereferenceable(2) %arg) nofree nosync {
; CHECK: Function: byval_and_deref_arg_non_deref_1: 2 pointers, 0 call sites
; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg
; CHECK-NEXT: NoAlias: i64* %arg, i32* %obj
bb:
store i32 1, i32* %obj, align 4
store i64 0, i64* %arg, align 8

View File

@ -27,5 +27,14 @@ define void @test(i8* %base) {
%gep.inc6 = getelementptr i8, i8* %gep.inc5, i64 1
%gep.inc7 = getelementptr i8, i8* %gep.inc6, i64 1
load i8, i8* %gep.add5
load i8, i8* %gep.add6
load i8, i8* %gep.add7
load i8, i8* %gep.inc3
load i8, i8* %gep.inc4
load i8, i8* %gep.inc5
load i8, i8* %gep.inc6
load i8, i8* %gep.inc7
ret void
}

View File

@ -13,6 +13,7 @@ define void @mustalias_overflow_in_32_bit_constants(i8* %ptr) {
; CHECK-NEXT: MustAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%gep.1 = getelementptr i8, i8* %ptr, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 0
@ -24,6 +25,7 @@ define void @mustalias_overflow_in_32_with_var_index([1 x i8]* %ptr, i64 %n) {
; CHECK-LABEL: Function: mustalias_overflow_in_32_with_var_index
; CHECK: MustAlias: i8* %gep.1, i8* %gep.2
;
load [1 x i8], [1 x i8]* %ptr
%gep.1 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 0
@ -37,6 +39,7 @@ define void @noalias_overflow_in_32_bit_constants(i8* %ptr) {
; CHECK-NEXT: NoAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%gep.1 = getelementptr i8, i8* %ptr, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 1
@ -53,6 +56,7 @@ define void @mustalias_overflow_in_32_bit_add_mul_gep(i8* %ptr, i64 %i) {
; CHECK-NEXT: MayAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%s.1 = icmp sgt i64 %i, 0
call void @llvm.assume(i1 %s.1)
@ -69,6 +73,7 @@ define void @mayalias_overflow_in_32_bit_non_zero(i8* %ptr, i64 %n) {
; CHECK-LABEL: Function: mayalias_overflow_in_32_bit_non_zero
; CHECK: MayAlias: i8* %gep, i8* %ptr
;
load i8, i8* %ptr
%c = icmp ne i64 %n, 0
call void @llvm.assume(i1 %c)
store i8 0, i8* %ptr
@ -83,6 +88,7 @@ define void @mayalias_overflow_in_32_bit_positive(i8* %ptr, i64 %n) {
; CHECK: MayAlias: i8* %gep.2, i8* %ptr
; CHECK: MayAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%c = icmp sgt i64 %n, 0
call void @llvm.assume(i1 %c)
%gep.1 = getelementptr i8, i8* %ptr, i64 -1

View File

@ -5,10 +5,11 @@ target datalayout = "p:64:64:64"
; %gep.idx and %gep.6 must-alias if %mul overflows (e.g. %idx == 52).
define void @may_overflow_mul_add_i8([16 x i8]* %ptr, i8 %idx) {
; CHECK-LABEL: Function: may_overflow_mul_add_i8: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 6): [16 x i8]* %ptr, i8* %gep.6
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -6): i8* %gep.6, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.6, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i8 %idx, 5
%add = add i8 %mul, 2
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %add
@ -20,10 +21,11 @@ define void @may_overflow_mul_add_i8([16 x i8]* %ptr, i8 %idx) {
define void @nuw_nsw_mul_add_i8([16 x i8]* %ptr, i8 %idx) {
; CHECK-LABEL: Function: nuw_nsw_mul_add_i8: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 6): [16 x i8]* %ptr, i8* %gep.6
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -6): i8* %gep.6, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.6, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw nsw i8 %idx, 5
%add = add nuw nsw i8 %mul, 2
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %add
@ -36,10 +38,11 @@ define void @nuw_nsw_mul_add_i8([16 x i8]* %ptr, i8 %idx) {
; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 52).
define void @may_overflow_mul_sub_i8([16 x i8]* %ptr, i8 %idx) {
; CHECK-LABEL: Function: may_overflow_mul_sub_i8: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i8 %idx, 5
%sub = sub i8 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %sub
@ -51,10 +54,11 @@ define void @may_overflow_mul_sub_i8([16 x i8]* %ptr, i8 %idx) {
define void @nuw_nsw_mul_sub_i8([16 x i8]* %ptr, i8 %idx) {
; CHECK-LABEL: Function: nuw_nsw_mul_sub_i8: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw nsw i8 %idx, 5
%sub = sub nuw nsw i8 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %sub
@ -68,10 +72,11 @@ define void @nuw_nsw_mul_sub_i8([16 x i8]* %ptr, i8 %idx) {
; (e.g. %idx == 3689348814741910323).
define void @may_overflow_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: may_overflow_mul_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i64 %idx, 5
%sub = sub i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -83,10 +88,11 @@ define void @may_overflow_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
define void @nuw_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: nuw_nsw_mul_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw nsw i64 %idx, 5
%sub = sub nuw nsw i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -98,10 +104,11 @@ define void @nuw_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
define void @only_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: only_nsw_mul_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nsw i64 %idx, 5
%sub = sub nsw i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -113,10 +120,11 @@ define void @only_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
define void @only_nuw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: only_nuw_mul_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw i64 %idx, 5
%sub = sub nuw i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -130,10 +138,11 @@ define void @only_nuw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) {
; because we multiply by a power-of-2.
define void @may_overflow_mul_pow2_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: may_overflow_mul_pow2_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i64 %idx, 8
%sub = sub i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -146,10 +155,11 @@ define void @may_overflow_mul_pow2_sub_i64([16 x i8]* %ptr, i64 %idx) {
; Multiplies by power-of-2 preserves modulo and the sub does not wrap.
define void @mul_pow2_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: mul_pow2_sub_nsw_nuw_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i64 %idx, 8
%sub = sub nuw nsw i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -161,10 +171,11 @@ define void @mul_pow2_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) {
define void @may_overflow_shl_sub_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: may_overflow_shl_sub_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = shl i64 %idx, 2
%sub = sub i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -176,10 +187,11 @@ define void @may_overflow_shl_sub_i64([16 x i8]* %ptr, i64 %idx) {
define void @shl_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: shl_sub_nsw_nuw_i64: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = shl i64 %idx, 3
%sub = sub nsw nuw i64 %mul, 1
%gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub
@ -192,10 +204,11 @@ define void @shl_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) {
; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 110).
define void @may_overflow_i32_sext([16 x i8]* %ptr, i32 %idx) {
; CHECK-LABEL: Function: may_overflow_i32_sext: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i32 %idx, 678152731
%sub = sub i32 %mul, 1582356375
%sub.ext = sext i32 %sub to i64
@ -208,10 +221,11 @@ define void @may_overflow_i32_sext([16 x i8]* %ptr, i32 %idx) {
define void @nuw_nsw_i32_sext([16 x i8]* %ptr, i32 %idx) {
; CHECK-LABEL: Function: nuw_nsw_i32_sext: 3 pointers, 0 call sites
; CHECK-NEXT: NoAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: NoAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw nsw i32 %idx, 678152731
%sub = sub nuw nsw i32 %mul, 1582356375
%sub.ext = sext i32 %sub to i64
@ -225,10 +239,11 @@ define void @nuw_nsw_i32_sext([16 x i8]* %ptr, i32 %idx) {
; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 110).
define void @may_overflow_i32_zext([16 x i8]* %ptr, i32 %idx) {
; CHECK-LABEL: Function: may_overflow_i32_zext: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul i32 %idx, 678152731
%sub = sub i32 %mul, 1582356375
%sub.ext = zext i32 %sub to i64
@ -241,10 +256,11 @@ define void @may_overflow_i32_zext([16 x i8]* %ptr, i32 %idx) {
define void @nuw_nsw_i32_zext([16 x i8]* %ptr, i32 %idx) {
; CHECK-LABEL: Function: nuw_nsw_i32_zext: 3 pointers, 0 call sites
; CHECK-NEXT: NoAlias: [16 x i8]* %ptr, i8* %gep.idx
; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3
; CHECK-NEXT: NoAlias: i8* %gep.idx, [16 x i8]* %ptr
; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx
;
load [16 x i8], [16 x i8]* %ptr
%mul = mul nuw nsw i32 %idx, 678152731
%sub = sub nuw nsw i32 %mul, 1582356375
%sub.ext = zext i32 %sub to i64
@ -259,10 +275,11 @@ define void @nuw_nsw_i32_zext([16 x i8]* %ptr, i32 %idx) {
; %gep.mul.1 and %gep.sub.2 may alias.
define void @may_overflow_pointer_diff([16 x i8]* %ptr, i64 %idx) {
; CHECK-LABEL: Function: may_overflow_pointer_diff: 3 pointers, 0 call sites
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.mul.1
; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.sub.2
; CHECK-NEXT: MayAlias: i8* %gep.mul.1, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.sub.2, [16 x i8]* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.mul.1, i8* %gep.sub.2
;
load [16 x i8], [16 x i8]* %ptr
%mul.1 = mul i64 %idx, 6148914691236517207
%gep.mul.1 = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %mul.1
store i8 1, i8* %gep.mul.1, align 1
@ -278,19 +295,21 @@ define void @may_overflow_pointer_diff([16 x i8]* %ptr, i64 %idx) {
; (((18446744073709551614 * 8) % 2^64 + 6 * 2) % 2^64 + 10) % 2^64 == 6.
define void @may_overflow_mul_scale_neg([200 x [ 6 x i8]]* %ptr, i64 %idx.1,i64 %idx.2) {
; CHECK-LABEL: Function: may_overflow_mul_scale_neg: 4 pointers, 2 call sites
; CHECK-NEXT: MustAlias: [200 x [6 x i8]]* %ptr, i8* %bc
; CHECK-NEXT: PartialAlias (off 6): [200 x [6 x i8]]* %ptr, i8* %gep.1
; CHECK-NEXT: MustAlias: i8* %bc, [200 x [6 x i8]]* %ptr
; CHECK-NEXT: PartialAlias (off -6): i8* %gep.1, [200 x [6 x i8]]* %ptr
; CHECK-NEXT: NoAlias: i8* %bc, i8* %gep.1
; CHECK-NEXT: MayAlias: [200 x [6 x i8]]* %ptr, i8* %gep.idx
; CHECK-NEXT: MayAlias: i8* %gep.idx, [200 x [6 x i8]]* %ptr
; CHECK-NEXT: MayAlias: i8* %bc, i8* %gep.idx
; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %gep.idx
;
load [200 x [6 x i8]], [200 x [6 x i8]]* %ptr
%idx.1.pos = icmp sge i64 %idx.1, 0
call void @llvm.assume(i1 %idx.1.pos)
%idx.2.pos = icmp sge i64 %idx.2, 0
call void @llvm.assume(i1 %idx.2.pos)
%bc = bitcast [ 200 x [ 6 x i8 ] ]* %ptr to i8*
load i8, i8* %bc
%gep.1 = getelementptr i8, i8* %bc, i64 6
store i8 1, i8* %gep.1, align 1
@ -311,6 +330,7 @@ define i8 @mul_may_overflow_var_nonzero_minabsvarindex_one_index([2000 x i8]* %a
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.idx
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.917
;
load [2000 x i8], [2000 x i8]* %arr
%or = or i64 %v, 1
%idx = mul i64 %or, 1844674407370955
%gep.idx = getelementptr inbounds [2000 x i8], [2000 x i8]* %arr, i32 0, i64 %idx
@ -331,7 +351,7 @@ define i8 @mul_nsw_var_nonzero_minabsvarindex_one_index([2000 x i8]* %arr, i8 %x
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.idx
; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.917
;
load [2000 x i8], [2000 x i8]* %arr
%or = or i64 %v, 1
%idx = mul nsw i64 %or, 1844674407370955
%gep.idx = getelementptr inbounds [2000 x i8], [2000 x i8]* %arr, i32 0, i64 %idx

View File

@ -6,6 +6,8 @@ declare void @llvm.experimental.guard(i1, ...)
declare void @unknown_but_readonly() readonly
define void @test1(i8* %P, i8* %Q) {
load i8, i8* %P
load i8, i8* %Q
tail call void(i1,...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void

View File

@ -10,6 +10,7 @@ define void @mustalias_due_to_index_size(i8* %ptr) {
; CHECK-NEXT: MustAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%gep.1 = getelementptr i8, i8* %ptr, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 0

View File

@ -35,9 +35,12 @@ define i8 @testLaunderInvariantGroupIsNotEscapeSource() {
entry:
%a = alloca %struct.A, align 8
%a.bitcast = bitcast %struct.A* %a to i8*
load %struct.A, %struct.A* %a
load i8, i8* %a.bitcast
%n = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 1
store i8 42, i8* %n
%a.laundered = call i8* @llvm.launder.invariant.group.p0i8(i8* nonnull %a.bitcast)
load i8, i8* %a.laundered
%n.laundered = getelementptr inbounds i8, i8* %a.laundered, i64 8
%v = load i8, i8* %n.laundered
; make sure that the load from %n.laundered to %v aliases the store of 42 to %n

View File

@ -14,6 +14,8 @@ define void @test_memset_pattern4_const_size(i8* noalias %a, i8* noalias %patter
; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.4 <-> call void @memset_pattern4(i8* %a, i8* %pattern, i64 17)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern4(i8* %a, i8* %pattern, i64 17)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -35,6 +37,8 @@ define void @test_memset_pattern4_variable_size(i8* noalias %a, i8* noalias %pat
; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern4(i8* %a, i8* %pattern, i64 %n)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern4(i8* %a, i8* %pattern, i64 %n)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -53,6 +57,8 @@ define void @test_memset_pattern8_const_size(i8* noalias %a, i8* noalias %patter
; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.8 <-> call void @memset_pattern8(i8* %a, i8* %pattern, i64 17)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern8(i8* %a, i8* %pattern, i64 17)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -74,6 +80,8 @@ define void @test_memset_pattern8_variable_size(i8* noalias %a, i8* noalias %pat
; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern8(i8* %a, i8* %pattern, i64 %n)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern8(i8* %a, i8* %pattern, i64 %n)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -92,6 +100,8 @@ define void @test_memset_pattern16_const_size(i8* noalias %a, i8* noalias %patte
; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.16 <-> call void @memset_pattern16(i8* %a, i8* %pattern, i64 17)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern16(i8* %a, i8* %pattern, i64 17)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -113,6 +123,8 @@ define void @test_memset_pattern16_variable_size(i8* noalias %a, i8* noalias %pa
; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern16(i8* %a, i8* %pattern, i64 %n)
;
entry:
load i8, i8* %a
load i8, i8* %pattern
call void @memset_pattern16(i8* %a, i8* %pattern, i64 %n)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1

View File

@ -9,6 +9,8 @@
; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4)
define i32 @test_memcmp_const_size(i8* noalias %a, i8* noalias %b) {
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -30,6 +32,8 @@ entry:
; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 %n)
define i32 @test_memcmp_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) {
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i32 @memcmp(i8* %a, i8* %b, i64 %n)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -54,6 +58,8 @@ declare i32 @bcmp(i8*, i8*, i64)
; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 4)
define i32 @test_bcmp_const_size(i8* noalias %a, i8* noalias %b) {
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i32 @bcmp(i8* %a, i8* %b, i64 4)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -75,6 +81,8 @@ entry:
; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 %n)
define i32 @test_bcmp_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) {
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i32 @bcmp(i8* %a, i8* %b, i64 %n)
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
@ -96,6 +104,7 @@ declare i8* @memchr(i8*, i32, i64)
define i8* @test_memchr_const_size(i8* noalias %a) {
entry:
%res = call i8* @memchr(i8* %a, i32 42, i64 4)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -116,7 +125,10 @@ declare i8* @memccpy(i8*, i8*, i32, i64)
define i8* @test_memccpy_const_size(i8* noalias %a, i8* noalias %b) {
entry:
load i8, i8* %a
load i8, i8* %b
%res = call i8* @memccpy(i8* %a, i8* %b, i32 42, i64 4)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -144,8 +156,11 @@ entry:
store i8 0, i8* %a
store i8 2, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
load i8, i8* %a.gep.1
%b.gep.1 = getelementptr i8, i8* %b, i32 1
load i8, i8* %b.gep.1
%res = tail call i8* @strcat(i8* %a.gep.1, i8* %b.gep.1)
load i8, i8* %res
%a.gep.5 = getelementptr i8, i8* %a, i32 5
store i8 1, i8* %a.gep.5
%b.gep.5 = getelementptr i8, i8* %b, i32 5
@ -169,8 +184,11 @@ entry:
store i8 0, i8* %a
store i8 2, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
load i8, i8* %a.gep.1
%b.gep.1 = getelementptr i8, i8* %b, i32 1
load i8, i8* %b.gep.1
%res = tail call i8* @strncat(i8* %a.gep.1, i8* %b.gep.1, i64 %n)
load i8, i8* %res
%a.gep.5 = getelementptr i8, i8* %a, i32 5
store i8 1, i8* %a.gep.5
%b.gep.5 = getelementptr i8, i8* %b, i32 5
@ -194,8 +212,11 @@ entry:
store i8 0, i8* %a
store i8 2, i8* %b
%a.gep.1 = getelementptr i8, i8* %a, i32 1
load i8, i8* %a.gep.1
%b.gep.1 = getelementptr i8, i8* %b, i32 1
load i8, i8* %b.gep.1
%res = tail call i8* @strcpy(i8* %a.gep.1, i8* %b.gep.1)
load i8, i8* %res
%a.gep.5 = getelementptr i8, i8* %a, i32 5
store i8 1, i8* %a.gep.5
%b.gep.5 = getelementptr i8, i8* %b, i32 5
@ -216,7 +237,10 @@ define i8* @test_strncpy_const_size(i8* noalias %a, i8* noalias %b) {
; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 4)
;
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i8* @strncpy(i8* %a, i8* %b, i64 4)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -239,7 +263,10 @@ define i8* @test_strncpy_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) {
; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 %n)
;
entry:
load i8, i8* %a
load i8, i8* %b
%res = tail call i8* @strncpy(i8* %a, i8* %b, i64 %n)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -261,7 +288,9 @@ define i8* @test_memset_chk_const_size(i8* noalias %a, i64 %n) {
; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n)
;
entry:
load i8, i8* %a
%res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5
@ -277,7 +306,9 @@ define i8* @test_memset_chk_variable_size(i8* noalias %a, i64 %n.1, i64 %n.2) {
; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 %n.1, i64 %n.2)
;
entry:
load i8, i8* %a
%res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 %n.1, i64 %n.2)
load i8, i8* %res
%a.gep.1 = getelementptr i8, i8* %a, i32 1
store i8 0, i8* %a.gep.1
%a.gep.5 = getelementptr i8, i8* %a, i32 5

View File

@ -14,6 +14,9 @@ define void @arr() {
%random = call i32* @random.i32(i32* %alloca)
%p0 = getelementptr inbounds i32, i32* %random, i32 0
%p1 = getelementptr inbounds i32, i32* %random, i32 1
load i32, i32* %alloca
load i32, i32* %p0
load i32, i32* %p1
ret void
}
@ -24,6 +27,9 @@ define void @arg(i32* %arg) {
%random = call i32* @random.i32(i32* %arg)
%p0 = getelementptr inbounds i32, i32* %random, i32 0
%p1 = getelementptr inbounds i32, i32* %random, i32 1
load i32, i32* %arg
load i32, i32* %p0
load i32, i32* %p1
ret void
}
@ -35,6 +41,9 @@ define void @global() {
%random = call i32* @random.i32(i32* @gv)
%p0 = getelementptr inbounds i32, i32* %random, i32 0
%p1 = getelementptr inbounds i32, i32* %random, i32 1
load i32, i32* @gv
load i32, i32* %p0
load i32, i32* %p1
ret void
}
@ -52,6 +61,10 @@ define void @struct() {
%f1 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 1
%p0 = getelementptr inbounds i32, i32* %random, i32 0
%p1 = getelementptr inbounds i32, i32* %random, i32 1
load i32, i32* %f0
load i32, i32* %f1
load i32, i32* %p0
load i32, i32* %p1
ret void
}
@ -76,6 +89,12 @@ define void @complex1(i32 %i) {
%r2.1 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 1
%r2.i = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 %i
%r2.1i = getelementptr inbounds i32, i32* %r2.1, i32 %i
load i32, i32* %a2.0
load i32, i32* %a1
load i32, i32* %r2.0
load i32, i32* %r2.1
load i32, i32* %r2.i
load i32, i32* %r2.1i
ret void
}
@ -94,6 +113,11 @@ define void @complex2(i32 %i, i32 %j) {
%p120 = getelementptr inbounds %outer, %outer* %random, i32 1, i32 2, i32 2, i32 0
%pi20 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 2, i32 0
%pij1 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 %j, i32 1
load i32, i32* %alloca
load i32, i32* %a3
load i32, i32* %p120
load i32, i32* %pi20
load i32, i32* %pij1
ret void
}
@ -124,6 +148,7 @@ entry:
define void @one_size_unknown(i8* %p, i32 %size) {
%p.minus1 = getelementptr inbounds i8, i8* %p, i32 -1
call void @llvm.memset.p0i8.i32(i8* %p, i8 0, i32 %size, i1 false)
load i8, i8* %p.minus1
ret void
}
@ -141,6 +166,9 @@ define void @all_inbounds() {
%p0 = getelementptr inbounds i8, i8* %random, i8 0
%step = getelementptr i8, i8* %random, i8 4
%p1 = getelementptr inbounds i8, i8* %step, i8 2
load i32, i32* %alloca
load i8, i8* %p0
load i8, i8* %p1
ret void
}
@ -156,6 +184,8 @@ define void @common_factor(i32 %x) {
%step = getelementptr inbounds i8, i8* %random, i8 4
%step.bitcast = bitcast i8* %step to i32*
%p1 = getelementptr inbounds i32, i32* %step.bitcast, i32 %x
load i32, i32* %p0
load i32, i32* %p1
ret void
}

View File

@ -26,8 +26,11 @@ bb3:
%f1 = getelementptr i32, i32* %ptr_phi , i32 1
%g1 = getelementptr i32, i32* %ptr_phi2 , i32 1
; This should also work if the access size is not the same.
; CHECK: NoAlias: i16* %h1, i32* %f1
; CHECK: NoAlias: i32* %f1, i16* %h1
%h1 = bitcast i32* %g1 to i16*
load i32, i32* %f1
load i32, i32* %g1
load i16, i16* %h1
ret i32 0
}
@ -54,6 +57,8 @@ bb3:
; CHECK: NoAlias: i32* %f1, i32* %g1
%f1 = getelementptr [2 x i32], [2 x i32]* %ptr_phi , i32 1, i32 %i
%g1 = getelementptr [2 x i32], [2 x i32]* %ptr_phi2 , i32 1, i32 %i
load i32, i32* %f1
load i32, i32* %g1
ret i32 0
}

View File

@ -5,6 +5,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) #
declare void @llvm.experimental.noalias.scope.decl(metadata)
define void @test1(i8* %P, i8* %Q) nounwind ssp {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.experimental.noalias.scope.decl(metadata !0)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void

View File

@ -64,6 +64,7 @@ for.body:
%sub11 = add i32 %1, -1
%idxprom12 = zext i32 %sub11 to i64
%arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom12
load i32, i32* %arrayidx13
call void @inc(i32* %jj7)
br label %codeRepl
@ -90,6 +91,7 @@ entry:
loop1:
%n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ]
%val1 = phi i32* [ @X, %entry ], [ %val2, %loop2 ]
load i32, i32* %val1
%add1 = add i32 %n1, 1
%cmp1 = icmp ne i32 %n1, 32
br i1 %cmp1, label %loop2, label %end
@ -97,6 +99,7 @@ loop1:
loop2:
%n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ]
%val2 = phi i32* [ %val1, %loop1 ], [ %val3, %loop3 ]
load i32, i32* %val2
%add2 = add i32 %n2, 1
%cmp2 = icmp ne i32 %n2, 32
br i1 %cmp2, label %loop3, label %loop1
@ -174,8 +177,8 @@ exit:
declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1)
; CHECK-LABEL: unsound_inequality
; CHECK: MayAlias: i32* %arrayidx13, i32* %phi
; CHECK: MayAlias: i32* %arrayidx5, i32* %phi
; CHECK: MayAlias: i32* %arrayidx13, i32* %phi
; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5
; When recursively reasoning about phis, we can't use predicates between
@ -187,6 +190,7 @@ entry:
for.body: ; preds = %for.body, %entry
%phi = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ]
load i32, i32* %phi
%idx = load i32, i32* %jj7, align 4
%arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %idx
store i32 0, i32* %arrayidx5, align 4
@ -208,10 +212,14 @@ entry:
loop:
%ptr = phi i32* [ %ptr.base, %entry ], [ %ptr.next, %split ]
%ptr.next = getelementptr inbounds i32, i32* %ptr, i64 1
load i32, i32* %ptr
load i32, i32* %ptr.next
br label %split
split:
%ptr.phi = phi i32* [ %ptr, %loop ]
%ptr.next.phi = phi i32* [ %ptr.next, %loop ]
load i32, i32* %ptr.phi
load i32, i32* %ptr.next.phi
br label %loop
}

View File

@ -27,6 +27,8 @@ for.body4: ; preds = %for.body4, %for.con
%lsr.iv1 = phi [16000 x double]* [ %i10, %for.body4 ], [ @X, %for.cond2.preheader ]
%lsr.iv = phi i32 [ %lsr.iv.next, %for.body4 ], [ 16000, %for.cond2.preheader ]
load [16000 x double], [16000 x double]* %lsr.iv4
load [16000 x double], [16000 x double]* %lsr.iv1
%lsr.iv46 = bitcast [16000 x double]* %lsr.iv4 to <4 x double>*
%lsr.iv12 = bitcast [16000 x double]* %lsr.iv1 to <4 x double>*
%scevgep11 = getelementptr <4 x double>, <4 x double>* %lsr.iv46, i64 -2
@ -50,8 +52,10 @@ for.body4: ; preds = %for.body4, %for.con
%lsr.iv.next = add i32 %lsr.iv, -16
%scevgep = getelementptr [16000 x double], [16000 x double]* %lsr.iv1, i64 0, i64 16
load double, double* %scevgep
%i10 = bitcast double* %scevgep to [16000 x double]*
%scevgep5 = getelementptr [16000 x double], [16000 x double]* %lsr.iv4, i64 0, i64 16
load double, double* %scevgep5
%i11 = bitcast double* %scevgep5 to [16000 x double]*
%exitcond.15 = icmp eq i32 %lsr.iv.next, 0
br i1 %exitcond.15, label %for.end, label %for.body4

View File

@ -27,6 +27,8 @@ while.body:
%tobool = icmp eq i32 %dec, 0
%ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1
%ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1
load i32, i32* %ptr_inc
load i32, i32* %ptr2_inc
br i1 %tobool, label %the_exit, label %while.body
the_exit:
@ -34,10 +36,10 @@ the_exit:
}
; CHECK: test_noalias_2
; CHECK: NoAlias: i32* %ptr_outer_phi, i32* %ptr_outer_phi2
; CHECK: NoAlias: i32* %ptr2_inc_outer, i32* %ptr_inc_outer
; CHECK: NoAlias: i32* %ptr2_phi, i32* %ptr_phi
; CHECK: NoAlias: i32* %ptr2_inc, i32* %ptr_inc
; CHECK-DAG: NoAlias: i32* %ptr_outer_phi, i32* %ptr_outer_phi2
; CHECK-DAG: NoAlias: i32* %ptr2_inc_outer, i32* %ptr_inc_outer
; CHECK-DAG: NoAlias: i32* %ptr2_phi, i32* %ptr_phi
; CHECK-DAG: NoAlias: i32* %ptr2_inc, i32* %ptr_inc
define i32 @test_noalias_2(i32* %ptr2, i32 %count, i32* %coeff) {
entry:
%ptr = getelementptr inbounds i32, i32* %ptr2, i64 1
@ -47,6 +49,8 @@ outer.while.header:
%ptr_outer_phi = phi i32* [%ptr_inc_outer, %outer.while.backedge], [ %ptr, %entry]
%ptr_outer_phi2 = phi i32* [%ptr2_inc_outer, %outer.while.backedge], [ %ptr2, %entry]
%num.outer = phi i32 [ %count, %entry ], [ %dec.outer, %outer.while.backedge ]
%ignore1 = load i32, i32* %ptr_outer_phi
%ignore2 = load i32, i32* %ptr_outer_phi2
br label %while.body
while.body:
@ -64,11 +68,15 @@ while.body:
%tobool = icmp eq i32 %dec, 0
%ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1
%ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1
load i32, i32* %ptr_inc
load i32, i32* %ptr2_inc
br i1 %tobool, label %outer.while.backedge, label %while.body
outer.while.backedge:
%ptr_inc_outer = getelementptr inbounds i32, i32* %ptr_phi, i64 1
%ptr2_inc_outer = getelementptr inbounds i32, i32* %ptr2_phi, i64 1
load i32, i32* %ptr_inc_outer
load i32, i32* %ptr2_inc_outer
%dec.outer = add nsw i32 %num.outer, -1
%br.cond = icmp eq i32 %dec.outer, 0
br i1 %br.cond, label %the_exit, label %outer.while.header
@ -88,6 +96,8 @@ while.body:
%num = phi i32 [ %count, %entry ], [ %dec, %while.body ]
%ptr_phi = phi i8* [ %x, %entry ], [ %z, %while.body ]
%ptr2_phi = phi i8* [ %y, %entry ], [ %ptr_phi, %while.body ]
load i8, i8* %ptr_phi
load i8, i8* %ptr2_phi
%dec = add nsw i32 %num, -1
%tobool = icmp eq i32 %dec, 0
br i1 %tobool, label %the_exit, label %while.body
@ -97,18 +107,24 @@ the_exit:
}
; CHECK-LABEL: test_different_stride_noalias
; CHECK: NoAlias: i16* %y.base, i8* %x.base
; CHECK: NoAlias: i16* %y, i8* %x
; CHECK: NoAlias: i16* %y.next, i8* %x.next
; CHECK: NoAlias: i8* %x.base, i16* %y.base
; CHECK: NoAlias: i8* %x, i16* %y
; CHECK: NoAlias: i8* %x.next, i16* %y.next
define void @test_different_stride_noalias(i1 %c, i8* noalias %x.base, i16* noalias %y.base) {
entry:
load i8, i8* %x.base
load i16, i16* %y.base
br label %loop
loop:
%x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ]
%y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ]
load i8, i8* %x
load i16, i16* %y
%x.next = getelementptr i8, i8* %x, i64 1
%y.next = getelementptr i16, i16* %y, i64 1
load i8, i8* %x.next
load i16, i16* %y.next
br i1 %c, label %loop, label %exit
exit:
@ -131,24 +147,32 @@ else:
end:
%z8 = phi i8* [ %x8, %if ], [ %y8, %else ]
%z16 = phi i16* [ %x16, %if ], [ %y16, %else ]
load i8, i8* %z8
load i16, i16* %z16
ret void
}
; CHECK-LABEL: test_same_stride_mustalias
; CHECK: MustAlias: i4* %y.base, i8* %x.base
; CHECK: MayAlias: i4* %y, i8* %x
; CHECK: MayAlias: i4* %y.next, i8* %x.next
; CHECK: MustAlias: i8* %x.base, i4* %y.base
; CHECK: MayAlias: i8* %x, i4* %y
; CHECK: MayAlias: i8* %x.next, i4* %y.next
; TODO: (x, y) could be MustAlias
define void @test_same_stride_mustalias(i1 %c, i8* noalias %x.base) {
entry:
%y.base = bitcast i8* %x.base to i4*
load i8, i8* %x.base
load i4, i4* %y.base
br label %loop
loop:
%x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ]
%y = phi i4* [ %y.base, %entry ], [ %y.next, %loop ]
load i8, i8* %x
load i4, i4* %y
%x.next = getelementptr i8, i8* %x, i64 1
%y.next = getelementptr i4, i4* %y, i64 1
load i8, i8* %x.next
load i4, i4* %y.next
br i1 %c, label %loop, label %exit
exit:
@ -156,21 +180,27 @@ exit:
}
; CHECK-LABEL: test_different_stride_mustalias
; CHECK: MustAlias: i16* %y.base, i8* %x.base
; CHECK: MayAlias: i16* %y, i8* %x
; CHECK: MayAlias: i16* %y.next, i8* %x.next
; CHECK: MustAlias: i8* %x.base, i16* %y.base
; CHECK: MayAlias: i8* %x, i16* %y
; CHECK: MayAlias: i8* %x.next, i16* %y.next
; Even though the base pointers MustAlias, the different strides don't preserve
; this property across iterations.
define void @test_different_stride_mustalias(i1 %c, i8* noalias %x.base) {
entry:
%y.base = bitcast i8* %x.base to i16*
load i8, i8* %x.base
load i16, i16* %y.base
br label %loop
loop:
%x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ]
%y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ]
load i8, i8* %x
load i16, i16* %y
%x.next = getelementptr i8, i8* %x, i64 1
%y.next = getelementptr i16, i16* %y, i64 1
load i8, i8* %x.next
load i16, i16* %y.next
br i1 %c, label %loop, label %exit
exit:

View File

@ -15,5 +15,7 @@ define i1 @ham(%struct.blam* %arg) {
%tmp2 = getelementptr %struct.blam, %struct.blam* %arg, i64 0, i32 1
%select = select i1 %isNull, i32* null, i32* %tmp2
%tmp3 = getelementptr i32, i32* %select, i32 -1
load i32, i32* %tmp
load i32, i32* %tmp3
ret i1 true
}

View File

@ -1,11 +1,13 @@
; RUN: opt %s -passes=aa-eval -disable-output 2>&1 | FileCheck %s
; RUN: opt %s -passes=aa-eval -disable-output -print-all-alias-modref-info 2>&1 | FileCheck %s
; CHECK: 6 Total Alias Queries Performed
; CHECK-NEXT: 6 no alias responses
; CHECK-LABEL: Function: patatino
; CHECK: NoAlias: i1* %G26, i1** %G47
define void @patatino() {
%G26 = getelementptr i1, i1* undef, i1 undef
%B20 = shl i8 -128, 16
%G47 = getelementptr i1*, i1** undef, i8 %B20
load i1, i1* %G26
load i1*, i1** %G47
ret void
}

View File

@ -1,12 +1,14 @@
; RUN: opt %s -passes=aa-eval -disable-output 2>&1 | FileCheck %s
; RUN: opt %s -passes=aa-eval -disable-output -print-all-alias-modref-info 2>&1 | FileCheck %s
; CHECK: 6 Total Alias Queries Performed
; CHECK-NEXT: 6 no alias responses
; CHECK-LABEL: Function: patatino
; CHECK: NoAlias: i1** %G22, i1*** %G45
define void @patatino() {
BB:
%G22 = getelementptr i1*, i1** undef, i8 -1
%B1 = mul i66 undef, 9223372036854775808
%G45 = getelementptr i1**, i1*** undef, i66 %B1
load i1*, i1** %G22
load i1**, i1*** %G45
ret void
}

View File

@ -11,7 +11,8 @@
target triple = "x86_64-unknown-linux-gnu"
; CHECK: MayAlias: i32* %v, void (i32*, i8*)* asm "movl $$1, $0", "=*m,X,~{dirflag},~{fpsr},~{flags}"
; CHECK: Both ModRef: Ptr: i32* %v <-> callbr void asm "movl $$1, $0", "=*m,X,~{dirflag},~{fpsr},~{flags}"(i32* nonnull elementtype(i32) %v, i8* blockaddress(@foo, %out))
define dso_local i32 @foo() {
entry:

View File

@ -2,24 +2,28 @@
%struct = type <{ [20 x i64] }>
; CHECK-LABEL: Function: test_noalias: 4 pointers, 1 call sites
; CHECK-LABEL: Function: test_noalias
; CHECK-NEXT: NoAlias: %struct* %ptr1, i64* %ptr2
; CHECK-NEXT: NoAlias: %struct* %addr.ptr, i64* %ptr2
; CHECK-NEXT: NoAlias: i64* %gep, i64* %ptr2
define void @test_noalias(%struct* noalias %ptr1, i64* %ptr2, i64 %offset) {
entry:
%addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928)
load %struct, %struct* %ptr1
load %struct, %struct* %addr.ptr
store i64 10, i64* %ptr2
%gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset
store i64 1, i64* %gep, align 8
ret void
}
; CHECK-NEXT: Function: test_alias: 4 pointers, 1 call sites
; CHECK-NEXT: Function: test_alias
; CHECK-NOT: NoAlias
define void @test_alias(%struct* %ptr1, i64* %ptr2, i64 %offset) {
entry:
%addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928)
load %struct, %struct* %ptr1
load %struct, %struct* %addr.ptr
store i64 10, i64* %ptr2
%gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset
store i64 1, i64* %gep, align 8

View File

@ -11,6 +11,8 @@ define void @test_zext_sext_amounts255(i8* %mem) {
%sext.zext.2 = zext i32 %sext.2 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -25,6 +27,8 @@ define void @test_zext_sext_amounts(i8* %mem, i8 %num) {
%sext.zext.2 = zext i32 %sext.2 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1
%b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -40,6 +44,9 @@ define void @based_on_pr18068(i32 %loaded, i8* %mem) {
%a = getelementptr inbounds i8, i8* %mem, i64 %loaded.64
%b = getelementptr inbounds i8, i8* %mem, i64 %add1.64
%c = getelementptr inbounds i8, i8* %mem, i64 %sub1.64
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
ret void
}
@ -65,6 +72,10 @@ define void @test_path_dependence(i16 %p, i8* %mem) {
%b = getelementptr inbounds i8, i8* %mem, i64 %p.64.again
%c = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.nuw.64.again
%d = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.64.again
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
load i8, i8* %d
ret void
}
@ -79,6 +90,8 @@ define void @test_zext_sext_255(i8* %mem) {
%zext.sext.zext.255 = zext i32 %sext.zext.255 to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.255
%b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.255
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -94,6 +107,8 @@ define void @test_zext_sext_num(i8* %mem, i8 %num) {
%zext.sext.zext.num = zext i32 %sext.zext.num to i64
%a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.num
%b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.num
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -106,6 +121,9 @@ define void @uncompressStream(i8* %mem) {
%a = getelementptr inbounds i8, i8* %mem, i32 255
%b = getelementptr inbounds i8, i8* %mem, i32 %zext.255
%c = getelementptr inbounds i8, i8* %mem, i32 %sext.255
load i8, i8* %a
load i8, i8* %b
load i8, i8* %c
ret void
}
@ -122,6 +140,9 @@ define void @constantOffsetHeuristic_i3_i32(i32* %mem, i3 %val) {
%a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
%b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
%c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
ret void
}
@ -138,6 +159,9 @@ define void @constantOffsetHeuristic_i8_i32(i32* %mem, i8 %val) {
%a = getelementptr inbounds i32, i32* %mem, i32 %zext.4
%b = getelementptr inbounds i32, i32* %mem, i32 %zext.7
%c = getelementptr inbounds i32, i32* %mem, i32 %zext.val
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
ret void
}
@ -157,6 +181,9 @@ define void @constantOffsetHeuristic_i3_i8(i8* %mem, i3 %val) {
%a = bitcast i8* %a.8 to i32*
%b = bitcast i8* %b.8 to i32*
%c = bitcast i8* %c.8 to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
ret void
}
@ -176,6 +203,9 @@ define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) {
%a = bitcast i8* %a.8 to i32*
%b = bitcast i8* %b.8 to i32*
%c = bitcast i8* %c.8 to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
ret void
}
@ -184,5 +214,7 @@ define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) {
define void @different_large_bitwidths(i8* %a, i64 %i, i128 %j) {
%p1 = getelementptr i8, i8* %a, i64 %i
%p2 = getelementptr i8, i8* %a, i128 %j
load i8, i8* %p1
load i8, i8* %p2
ret void
}

View File

@ -8,6 +8,8 @@
define void @t1(%struct.S* %s) {
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -17,6 +19,8 @@ define void @t2_fwd(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -26,6 +30,8 @@ define void @t2_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -35,6 +41,8 @@ define void @t3_fwd(%struct.S* %s, i32* %q) {
%knownzero = load i32, i32* %q, !range !1
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -44,6 +52,8 @@ define void @t3_rev(%struct.S* %s, i32* %q) {
%knownzero = load i32, i32* %q, !range !1
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -53,6 +63,8 @@ define void @member_after(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -62,6 +74,8 @@ define void @member_after_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -71,6 +85,8 @@ define void @member_before(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -80,101 +96,104 @@ define void @member_before_rev(%struct.S* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !0
%gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0
%gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t5
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 4): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t5
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t5(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t6
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 16): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t6
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -16): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t6(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !3
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 3
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t7
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 20): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t7
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t7(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t8
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 24): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t8
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -24): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t8(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !4
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 1
load %struct.S2, %struct.S2* %s
load i32, i32* %q
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t9
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 20): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t9
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s
; CHECK: NoAlias: i32* %gep1, i32* %gep2
define void @t9(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t10
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q
; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q
; CHECK-NEXT: PartialAlias (off 4): %struct.S2* %s, i32* %gep2
; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q
; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2
; CHECK-LABEL: Function: t10
; CHECK: MayAlias: i32* %gep1, %struct.S2* %s
; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s
; CHECK: MayAlias: i32* %gep1, i32* %gep2
define void @t10(%struct.S2* %s, i32* %q) {
%in_array = load i32, i32* %q, !range !5
%gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array
%gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0
load %struct.S2, %struct.S2* %s
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: zeroext_index
; CHECK-NEXT: MayAlias: [256 x i32]* %s, i8* %q
; CHECK-NEXT: MayAlias: [256 x i32]* %s, i32* %gep
; CHECK-NEXT: MayAlias: i32* %gep, i8* %q
; CHECK-LABEL: Function: zeroext_index
; CHECK: MayAlias: i32* %gep, [256 x i32]* %s
define void @zeroext_index([256 x i32]* %s, i8* %q) {
%a = load i8, i8* %q, !range !6
%in_array = zext i8 %a to i32
%gep = getelementptr inbounds [256 x i32], [256 x i32]* %s, i64 0, i32 %in_array
load [256 x i32], [256 x i32]* %s
load i32, i32* %gep
ret void
}
@ -193,6 +212,11 @@ define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) {
%p.02 = getelementptr i32, i32* %p.01, i32 %o2 ; p + [0, 2]
%p.2 = getelementptr i32, i32* %p, i32 2
%p.3 = getelementptr i32, i32* %p, i32 3
load i32, i32* %p
load i32, i32* %p.01
load i32, i32* %p.02
load i32, i32* %p.2
load i32, i32* %p.3
ret void
}
@ -210,6 +234,10 @@ define void @benign_overflow(i8* %p, i64 %o) {
%p.neg1 = getelementptr i8, i8* %p, i64 -1
%p.o = getelementptr i8, i8* %p, i64 %o
%p.o.1 = getelementptr i8, i8* %p.o, i64 1
load i8, i8* %p
load i8, i8* %p.neg1
load i8, i8* %p.o
load i8, i8* %p.o.1
ret void
}

View File

@ -14,6 +14,8 @@
; CHECK: NoAlias: float* %g, float* %next
define void @simple(float *%src1, float * noalias %src2, i32 %n) nounwind {
entry:
load float, float* %src1
load float, float* %src2
br label %loop
loop:
@ -22,6 +24,7 @@ loop:
%next = getelementptr inbounds float, float* %phi, i32 1
%g = getelementptr inbounds float, float* %src1, i32 3
%l = load float, float* %phi
load float, float* %next
%a = fadd float %l, 1.0
store float %a, float* %g
%idxn = add nsw nuw i32 %idx, 1
@ -33,25 +36,27 @@ end:
}
; CHECK-LABEL: Function: notmust: 6 pointers, 0 call sites
; CHECK: MustAlias: [2 x i32]* %tab, i8* %0
; CHECK: PartialAlias (off 4): [2 x i32]* %tab, i32* %arrayidx
; CHECK: NoAlias: i32* %arrayidx, i8* %0
; CHECK: MustAlias: [2 x i32]* %tab, i32* %arrayidx1
; CHECK: MustAlias: i32* %arrayidx1, i8* %0
; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1
; CHECK: MayAlias: [2 x i32]* %tab, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %p.addr.05.i, i8* %0
; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i
; CHECK: MayAlias: [2 x i32]* %tab, i32* %incdec.ptr.i
; CHECK: NoAlias: i32* %incdec.ptr.i, i8* %0
; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i
; CHECK: NoAlias: i32* %arrayidx1, i32* %incdec.ptr.i
; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i
; CHECK: MustAlias: i8* %0, [2 x i32]* %tab
; CHECK: PartialAlias (off -4): i32* %arrayidx, [2 x i32]* %tab
; CHECK: NoAlias: i8* %0, i32* %arrayidx
; CHECK: MustAlias: i32* %arrayidx1, [2 x i32]* %tab
; CHECK: MustAlias: i8* %0, i32* %arrayidx1
; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1
; CHECK: MayAlias: i32* %incdec.ptr.i, [2 x i32]* %tab
; CHECK: NoAlias: i8* %0, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i
; CHECK: NoAlias: i32* %arrayidx1, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %p.addr.05.i, [2 x i32]* %tab
; CHECK: MayAlias: i8* %0, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i
; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i
define i32 @notmust() nounwind {
entry:
%tab = alloca [2 x i32], align 4
%ignore1 = load [2 x i32], [2 x i32]* %tab
%0 = bitcast [2 x i32]* %tab to i8*
%ignore2 = load i8, i8* %0
%arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %tab, i32 0, i32 1
store i32 0, i32* %arrayidx, align 4
%arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %tab, i32 0, i32 0
@ -66,6 +71,7 @@ while.body.i: ; preds = %while.body.i, %entry
%p.addr.05.i = phi i32* [ %incdec.ptr.i, %while.body.i ], [ %arrayidx1, %entry ]
%sub.i = sub nsw i32 %foo.06.i, %2
%incdec.ptr.i = getelementptr inbounds i32, i32* %p.addr.05.i, i32 1
%ignore3 = load i32, i32* %incdec.ptr.i
store i32 %sub.i, i32* %p.addr.05.i, align 4
%cmp.i = icmp sgt i32 %sub.i, 1
br i1 %cmp.i, label %while.body.i, label %f.exit
@ -86,25 +92,27 @@ if.end: ; preds = %f.exit
}
; CHECK-LABEL: Function: reverse: 6 pointers, 0 call sites
; CHECK: MustAlias: [10 x i32]* %tab, i8* %0
; CHECK: MustAlias: [10 x i32]* %tab, i32* %arrayidx
; CHECK: MustAlias: i32* %arrayidx, i8* %0
; CHECK: PartialAlias (off 36): [10 x i32]* %tab, i32* %arrayidx1
; CHECK: NoAlias: i32* %arrayidx1, i8* %0
; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1
; CHECK: MayAlias: [10 x i32]* %tab, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %p.addr.05.i, i8* %0
; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i
; CHECK: MayAlias: [10 x i32]* %tab, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %incdec.ptr.i, i8* %0
; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %incdec.ptr.i
; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i
; CHECK: MustAlias: i8* %0, [10 x i32]* %tab
; CHECK: MustAlias: i32* %arrayidx, [10 x i32]* %tab
; CHECK: MustAlias: i8* %0, i32* %arrayidx
; CHECK: PartialAlias (off -36): i32* %arrayidx1, [10 x i32]* %tab
; CHECK: NoAlias: i8* %0, i32* %arrayidx1
; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1
; CHECK: MayAlias: i32* %incdec.ptr.i, [10 x i32]* %tab
; CHECK: MayAlias: i8* %0, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %incdec.ptr.i
; CHECK: MayAlias: i32* %p.addr.05.i, [10 x i32]* %tab
; CHECK: MayAlias: i8* %0, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i
; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i
; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i
define i32 @reverse() nounwind {
entry:
%tab = alloca [10 x i32], align 4
%ignore1 = load [10 x i32], [10 x i32]* %tab
%0 = bitcast [10 x i32]* %tab to i8*
%ignore2 = load i8, i8* %0
%arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %tab, i32 0, i32 0
store i32 0, i32* %arrayidx, align 4
%arrayidx1 = getelementptr inbounds [10 x i32], [10 x i32]* %tab, i32 0, i32 9
@ -119,6 +127,7 @@ while.body.i: ; preds = %while.body.i, %entry
%p.addr.05.i = phi i32* [ %incdec.ptr.i, %while.body.i ], [ %arrayidx1, %entry ]
%sub.i = sub nsw i32 %foo.06.i, %2
%incdec.ptr.i = getelementptr inbounds i32, i32* %p.addr.05.i, i32 -1
%ignore3 = load i32, i32* %incdec.ptr.i
store i32 %sub.i, i32* %p.addr.05.i, align 4
%cmp.i = icmp sgt i32 %sub.i, 1
br i1 %cmp.i, label %while.body.i, label %f.exit
@ -138,31 +147,27 @@ if.end: ; preds = %f.exit
ret i32 0
}
; CHECK-LABEL: Function: negative: 6 pointers, 1 call sites
; CHECK: NoAlias: [3 x i16]* %int_arr.10, i16** %argv.6.par
; CHECK: NoAlias: i16* %_tmp1, i16** %argv.6.par
; CHECK: PartialAlias (off 4): [3 x i16]* %int_arr.10, i16* %_tmp1
; CHECK: NoAlias: i16* %ls1.9.0, i16** %argv.6.par
; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0
; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0
; CHECK: NoAlias: i16* %_tmp7, i16** %argv.6.par
; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %_tmp7
; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7
; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0
; CHECK: NoAlias: i16* %_tmp11, i16** %argv.6.par
; CHECK: PartialAlias (off 2): [3 x i16]* %int_arr.10, i16* %_tmp11
; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11
; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0
; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7
; CHECK: Both ModRef: Ptr: i16** %argv.6.par <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: NoModRef: Ptr: i16* %_tmp1 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: Both ModRef: Ptr: i16* %ls1.9.0 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: Both ModRef: Ptr: i16* %_tmp7 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: NoModRef: Ptr: i16* %_tmp11 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
define i16 @negative(i16 %argc.5.par, i16** nocapture readnone %argv.6.par) {
; CHECK-LABEL: Function: negative: 5 pointers, 1 call sites
; CHECK: PartialAlias (off -4): i16* %_tmp1, [3 x i16]* %int_arr.10
; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0
; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0
; CHECK: MayAlias: i16* %_tmp7, [3 x i16]* %int_arr.10
; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7
; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0
; CHECK: PartialAlias (off -2): i16* %_tmp11, [3 x i16]* %int_arr.10
; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11
; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0
; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7
; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: NoModRef: Ptr: i16* %_tmp1 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: Both ModRef: Ptr: i16* %ls1.9.0 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: Both ModRef: Ptr: i16* %_tmp7 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
; CHECK: NoModRef: Ptr: i16* %_tmp11 <-> %_tmp16 = call i16 @call(i32 %_tmp13)
define i16 @negative(i16 %argc.5.par) {
%int_arr.10 = alloca [3 x i16], align 1
load [3 x i16], [3 x i16]* %int_arr.10
%_tmp1 = getelementptr inbounds [3 x i16], [3 x i16]* %int_arr.10, i16 0, i16 2
load i16, i16* %_tmp1
br label %bb1
bb1: ; preds = %bb1, %0
@ -171,6 +176,7 @@ bb1: ; preds = %bb1, %0
store i16 %i.7.0, i16* %ls1.9.0, align 1
%_tmp5 = add nsw i16 %i.7.0, -1
%_tmp7 = getelementptr i16, i16* %ls1.9.0, i16 -1
load i16, i16* %_tmp7
%_tmp9 = icmp sgt i16 %i.7.0, 0
br i1 %_tmp9, label %bb1, label %bb3
@ -199,12 +205,16 @@ bb5: ; preds = %bb3, %bb4
define void @dynamic_offset(i1 %c, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %loop
loop:
%p = phi i8* [ %p.base, %entry ], [ %p.next, %loop ]
%offset = call i16 @call(i32 0)
%p.next = getelementptr inbounds i8, i8* %p, i16 %offset
load i8, i8* %p
load i8, i8* %p.next
br i1 %c, label %loop, label %exit
exit:
@ -221,41 +231,51 @@ exit:
; CHECK: MustAlias: i32* %p.next, i32* %result
define i32* @symmetry(i32* %p.base, i1 %c) {
entry:
load i32, i32* %p.base
br label %loop
loop:
%p = phi i32* [ %p.base, %entry ], [ %p.next, %loop ]
%p.next = getelementptr inbounds i32, i32* %p, i32 1
load i32, i32* %p
load i32, i32* %p.next
br i1 %c, label %loop, label %exit
exit:
%result = phi i32* [ %p.next, %loop ]
load i32, i32* %result
ret i32* %result
}
; CHECK-LABEL: Function: nested_loop
; CHECK: NoAlias: i8* %a, i8* %p.base
; CHECK: NoAlias: i8* %a, i8* %p.outer
; CHECK: NoAlias: i8* %a, i8* %p.outer.next
; NO-PHI-VALUES: MayAlias: i8* %a, i8* %p.inner
; PHI-VALUES: NoAlias: i8* %a, i8* %p.inner
; CHECK: NoAlias: i8* %a, i8* %p.inner.next
; CHECK: NoAlias: i8* %a, i8* %p.outer.next
define void @nested_loop(i1 %c, i1 %c2, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %outer_loop
outer_loop:
%p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]
load i8, i8* %p.outer
br label %inner_loop
inner_loop:
%p.inner = phi i8* [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ]
%p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1
load i8, i8* %p.inner
load i8, i8* %p.inner.next
br i1 %c, label %inner_loop, label %outer_loop_latch
outer_loop_latch:
%p.outer.next = getelementptr inbounds i8, i8* %p.inner, i64 10
load i8, i8* %p.outer.next
br i1 %c2, label %outer_loop, label %exit
exit:
@ -273,16 +293,22 @@ exit:
define void @nested_loop2(i1 %c, i1 %c2, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %outer_loop
outer_loop:
%p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]
%p.outer.next = getelementptr inbounds i8, i8* %p.outer, i64 10
load i8, i8* %p.outer
load i8, i8* %p.outer.next
br label %inner_loop
inner_loop:
%p.inner = phi i8* [ %p.outer.next, %outer_loop ], [ %p.inner.next, %inner_loop ]
%p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1
load i8, i8* %p.inner
load i8, i8* %p.inner.next
br i1 %c, label %inner_loop, label %outer_loop_latch
outer_loop_latch:
@ -302,16 +328,22 @@ exit:
define void @nested_loop3(i1 %c, i1 %c2, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %outer_loop
outer_loop:
%p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ]
%p.outer.next = getelementptr inbounds i8, i8* %p.outer, i64 10
load i8, i8* %p.outer
load i8, i8* %p.outer.next
br label %inner_loop
inner_loop:
%p.inner = phi i8* [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ]
%p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1
load i8, i8* %p.inner
load i8, i8* %p.inner.next
br i1 %c, label %inner_loop, label %outer_loop_latch
outer_loop_latch:
@ -331,16 +363,22 @@ exit:
define void @sibling_loop(i1 %c, i1 %c2, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %loop1
loop1:
%p1 = phi i8* [ %p.base, %entry ], [ %p1.next, %loop1 ]
%p1.next = getelementptr inbounds i8, i8* %p1, i64 10
load i8, i8* %p1
load i8, i8* %p1.next
br i1 %c, label %loop1, label %loop2
loop2:
%p2 = phi i8* [ %p1.next, %loop1 ], [ %p2.next, %loop2 ]
%p2.next = getelementptr inbounds i8, i8* %p2, i64 1
load i8, i8* %p2
load i8, i8* %p2.next
br i1 %c2, label %loop2, label %exit
exit:
@ -357,16 +395,22 @@ exit:
define void @sibling_loop2(i1 %c, i1 %c2, i8* noalias %p.base) {
entry:
%a = alloca i8
load i8, i8* %p.base
load i8, i8* %a
br label %loop1
loop1:
%p1 = phi i8* [ %p.base, %entry ], [ %p1.next, %loop1 ]
%p1.next = getelementptr inbounds i8, i8* %p1, i64 10
load i8, i8* %p1
load i8, i8* %p1.next
br i1 %c, label %loop1, label %loop2
loop2:
%p2 = phi i8* [ %p1, %loop1 ], [ %p2.next, %loop2 ]
%p2.next = getelementptr inbounds i8, i8* %p2, i64 1
load i8, i8* %p2
load i8, i8* %p2.next
br i1 %c2, label %loop2, label %exit
exit:

View File

@ -17,14 +17,14 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK-DAG: NoAlias: i32* %y, i32* %z
; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12
; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
@ -37,6 +37,14 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
%y_10 = bitcast i32* %y to i80*
%ya = call i32* @func1(i32* %y)
%y_8 = bitcast i32* %ya to i64*
load %struct, %struct* %st
load %struct, %struct* %sta
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
ret void
}

View File

@ -7,6 +7,8 @@ define void @t1([8 x i32]* %p, i32 %addend, i32* %q) {
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -17,6 +19,8 @@ define void @t2([8 x i32]* %p, i32 %addend, i32* %q) {
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -27,6 +31,8 @@ define void @t3([8 x i32]* %p, i32 %addend, i32* %q) {
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -37,17 +43,21 @@ define void @t4([8 x i32]* %p, i32 %addend, i32* %q) {
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 %add, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK: Function: t5
; CHECK: MayAlias: i32* %gep2, i64* %bc
; CHECK: MayAlias: i64* %bc, i32* %gep2
define void @t5([8 x i32]* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
%add = add nsw nuw i32 %addend, %knownnonzero
%gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend
%gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add
%bc = bitcast i32* %gep1 to i64*
load i32, i32* %gep2
load i64, i64* %bc
ret void
}
@ -58,26 +68,30 @@ define void @add_non_zero_simple(i32* %p, i32 %addend, i32* %q) {
%add = add i32 %addend, %knownnonzero
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK-LABEL: Function: add_non_zero_different_scales
; CHECK: MayAlias: i16* %gep2, i32* %gep1
; CHECK: MayAlias: i32* %gep1, i16* %gep2
define void @add_non_zero_different_scales(i32* %p, i32 %addend, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
%add = add i32 %addend, %knownnonzero
%p16 = bitcast i32* %p to i16*
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i16, i16* %p16, i32 %add
load i32, i32* %gep1
load i16, i16* %gep2
ret void
}
; CHECK-LABEL: Function: add_non_zero_different_sizes
; CHECK: NoAlias: i16* %gep1.16, i32* %gep2
; CHECK: NoAlias: i16* %gep2.16, i32* %gep1
; CHECK: NoAlias: i32* %gep1, i16* %gep2.16
; CHECK: NoAlias: i16* %gep1.16, i16* %gep2.16
; CHECK: MayAlias: i32* %gep2, i64* %gep1.64
; CHECK: MayAlias: i16* %gep2.16, i64* %gep1.64
; CHECK: MayAlias: i64* %gep1.64, i32* %gep2
; CHECK: MayAlias: i64* %gep1.64, i16* %gep2.16
; CHECK: MayAlias: i32* %gep1, i64* %gep2.64
; CHECK: MayAlias: i16* %gep1.16, i64* %gep2.64
; CHECK: MayAlias: i64* %gep1.64, i64* %gep2.64
@ -90,6 +104,12 @@ define void @add_non_zero_different_sizes(i32* %p, i32 %addend, i32* %q) {
%gep2.16 = bitcast i32* %gep2 to i16*
%gep1.64 = bitcast i32* %gep1 to i64*
%gep2.64 = bitcast i32* %gep2 to i64*
load i32, i32* %gep1
load i32, i32* %gep2
load i16, i16* %gep1.16
load i16, i16* %gep2.16
load i64, i64* %gep1.64
load i64, i64* %gep2.64
ret void
}
@ -107,6 +127,10 @@ define void @add_non_zero_with_offset(i32* %p, i32 %addend, i32* %q) {
%gep2 = getelementptr i32, i32* %p, i32 %add
%gep1.16 = bitcast i32* %gep1 to i16*
%gep2.16 = bitcast i32* %gep2 to i16*
load i32, i32* %gep1
load i32, i32* %gep2
load i16, i16* %gep1.16
load i16, i16* %gep2.16
ret void
}
@ -118,23 +142,29 @@ define void @add_non_zero_assume(i32* %p, i32 %addend, i32 %knownnonzero) {
%add = add i32 %addend, %knownnonzero
%gep1 = getelementptr i32, i32* %p, i32 %addend
%gep2 = getelementptr i32, i32* %p, i32 %add
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
; CHECK-LABEL: non_zero_index_simple
; CHECK: NoAlias: i32* %gep, i32* %p
; CHECK: NoAlias: i16* %gep.16, i32* %p
; CHECK: MayAlias: i32* %p, i64* %gep.64
; CHECK: MayAlias: i64* %gep.64, i32* %p
define void @non_zero_index_simple(i32* %p, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
%gep = getelementptr i32, i32* %p, i32 %knownnonzero
%gep.16 = bitcast i32* %gep to i16*
%gep.64 = bitcast i32* %gep to i64*
load i32, i32* %p
load i32, i32* %gep
load i16, i16* %gep.16
load i64, i64* %gep.64
ret void
}
; CHECK-LABEL: non_zero_index_with_offset
; CHECK: NoAlias: i32* %gep, i32* %p
; CHECK: MayAlias: i32* %gep, i32* %p
; CHECK: NoAlias: i16* %gep.16, i32* %p
define void @non_zero_index_with_offset(i32* %p, i32* %q) {
%knownnonzero = load i32, i32* %q, !range !0
@ -143,6 +173,9 @@ define void @non_zero_index_with_offset(i32* %p, i32* %q) {
%p.off = bitcast i8* %p.off.8 to i32*
%gep = getelementptr i32, i32* %p.off, i32 %knownnonzero
%gep.16 = bitcast i32* %gep to i16*
load i32, i32* %p
load i32, i32* %gep
load i16, i16* %gep.16
ret void
}
@ -152,6 +185,8 @@ define void @non_zero_index_assume(i32* %p, i32 %knownnonzero) {
%cmp = icmp ne i32 %knownnonzero, 0
call void @llvm.assume(i1 %cmp)
%gep = getelementptr i32, i32* %p, i32 %knownnonzero
load i32, i32* %p
load i32, i32* %gep
ret void
}

View File

@ -15,14 +15,14 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; CHECK-DAG: NoAlias: i32* %y, i32* %z
; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12
; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8
; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
@ -33,6 +33,13 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load %struct, %struct* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
ret void
}
@ -42,6 +49,8 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) {
define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr %struct, %struct* %st, i64 %j, i32 1
load i32, i32* %x
load i32, i32* %y
ret void
}
@ -55,15 +64,15 @@ define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) {
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z
; CHECK-DAG: MayAlias: %struct* %y_12, [1 x %struct]* %st
; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y_8
; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
@ -74,6 +83,13 @@ define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1,
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load [1 x %struct], [1 x %struct]* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
ret void
}
@ -87,15 +103,15 @@ define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1,
; CHECK-DAG: NoAlias: i32* %x, i32* %z
; CHECK-DAG: NoAlias: i32* %y, i32* %z
; CHECK-DAG: MayAlias: %struct* %y_12, [1 x [1 x [1 x %struct]]]* %st
; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x
; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12
; CHECK-DAG: MayAlias: i32* %x, i80* %y_10
; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8
; CHECK-DAG: MayAlias: i32* %z, i64* %y_8
; CHECK-DAG: MayAlias: i64* %y_8, i32* %z
; CHECK-DAG: NoAlias: i32* %x, i64* %y_8
; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y
; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12
; CHECK-DAG: MustAlias: i32* %y, i64* %y_8
; CHECK-DAG: MustAlias: i32* %y, i80* %y_10
@ -106,6 +122,13 @@ define void @test_in_3d_array([1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %j, i6
%y_12 = bitcast i32* %y to %struct*
%y_10 = bitcast i32* %y to i80*
%y_8 = bitcast i32* %y to i64*
load [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load %struct, %struct* %y_12
load i80, i80* %y_10
load i64, i64* %y_8
ret void
}
@ -132,6 +155,12 @@ define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64
%x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1
%z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load i32, i32* %x2
load i32, i32* %y2
load i32, i32* %z2
ret void
}
@ -158,6 +187,12 @@ define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1
%x = getelementptr inbounds %struct, %struct* %st, i64 %i1, i32 0
%y = getelementptr inbounds %struct, %struct* %st, i64 %j1, i32 1
%z = getelementptr inbounds %struct, %struct* %st, i64 %k1, i32 2
load i32, i32* %x
load i32, i32* %y
load i32, i32* %z
load i32, i32* %x2
load i32, i32* %y2
load i32, i32* %z2
ret void
}
@ -169,6 +204,8 @@ define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1
define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
%x = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 1, i32 1, i32 0
%y = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1
load i32, i32* %x
load i32, i32* %y
ret void
}
@ -178,5 +215,7 @@ define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) {
define void @test_different_index_types([2 x i16]* %arr) {
%tmp1 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i32 1
%tmp2 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i16 1
load i16, i16* %tmp1
load i16, i16* %tmp2
ret void
}

View File

@ -10,6 +10,9 @@ define void @gep_alloca_const_offset_1() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
ret void
}
@ -22,6 +25,9 @@ define void @gep_alloca_const_offset_2() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
ret void
}
@ -33,6 +39,9 @@ define void @gep_alloca_const_offset_3() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load i32, i32* %gep2
ret void
}
@ -44,6 +53,9 @@ define void @gep_alloca_const_offset_4() {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 0, i64 0
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load i32, i32* %gep2
ret void
}
@ -55,17 +67,23 @@ define void @gep_alloca_symbolic_offset(i64 %idx1, i64 %idx2) {
%alloc = alloca <vscale x 4 x i32>
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc, i64 %idx2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %alloc
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
ret void
}
; CHECK-LABEL: gep_same_base_const_offset
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep2
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep2, <vscale x 4 x i32>* %p
; TODO: AliasResult for gep1,gep2 can be improved as NoAlias
; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2
define void @gep_same_base_const_offset(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %gep1
load i32, i32* %gep2
ret void
}
@ -76,6 +94,9 @@ define void @gep_same_base_const_offset(<vscale x 4 x i32>* %p) {
define void @gep_same_base_symbolic_offset(<vscale x 4 x i32>* %p, i64 %idx1, i64 %idx2) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 %idx2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
ret void
}
@ -89,6 +110,10 @@ define void @gep_same_base_symbolic_offset(<vscale x 4 x i32>* %p, i64 %idx1, i6
define void @gep_different_base_const_offset(<vscale x 4 x i32>* noalias %p1, <vscale x 4 x i32>* noalias %p2) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p1, i64 1
%gep2 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p2, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep2
ret void
}
@ -96,69 +121,85 @@ define void @gep_different_base_const_offset(<vscale x 4 x i32>* noalias %p1, <v
; CHECK-LABEL: gep_bitcast_1
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %p, i32* %p2
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep1
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, i32* %p2
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep2
; CHECK-DAG: MayAlias: i32* %gep2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2
; CHECK-DAG: NoAlias: i32* %gep2, i32* %p2
define void @gep_bitcast_1(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%p2 = bitcast <vscale x 4 x i32>* %p to i32*
%gep2 = getelementptr i32, i32* %p2, i64 4
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %gep1
load i32, i32* %gep2
load i32, i32* %p2
ret void
}
; CHECK-LABEL: gep_bitcast_2
; CHECK-DAG: MustAlias: <vscale x 4 x float>* %p2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep1
; CHECK-DAG: MayAlias: <vscale x 4 x float>* %p2, i32* %gep1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, float* %gep2
; CHECK-DAG: MayAlias: float* %gep2, i32* %gep1
; CHECK-DAG: MayAlias: <vscale x 4 x float>* %p2, float* %gep2
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %p, <vscale x 4 x float>* %p2
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, <vscale x 4 x float>* %p2
; CHECK-DAG: MayAlias: float* %gep2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep1, float* %gep2
; CHECK-DAG: MayAlias: float* %gep2, <vscale x 4 x float>* %p2
define void @gep_bitcast_2(<vscale x 4 x i32>* %p) {
%gep1 = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 0
%p2 = bitcast <vscale x 4 x i32>* %p to <vscale x 4 x float>*
%gep2 = getelementptr <vscale x 4 x float>, <vscale x 4 x float>* %p2, i64 1, i64 0
load i32, i32* %gep1
load float, float* %gep2
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load <vscale x 4 x float>, <vscale x 4 x float>* %p2
ret void
}
; getelementptr recursion
; CHECK-LABEL: gep_recursion_level_1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %a
; CHECK-DAG: MayAlias: i32* %a, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %a, i32* %gep
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_1
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
define void @gep_recursion_level_1(i32* %a, <vscale x 4 x i32>* %p) {
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
ret void
}
; CHECK-LABEL: gep_recursion_level_1_bitcast
; CHECK-DAG: MustAlias: <vscale x 4 x i32>* %p, i32* %a
; CHECK-DAG: MustAlias: i32* %a, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %a, i32* %gep
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_1
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
define void @gep_recursion_level_1_bitcast(i32* %a) {
%p = bitcast i32* %a to <vscale x 4 x i32>*
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
ret void
}
; CHECK-LABEL: gep_recursion_level_2
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %a
; CHECK-DAG: MayAlias: i32* %a, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %a, i32* %gep
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_2
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_2
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_2, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2
; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_2
@ -166,11 +207,16 @@ define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
%gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %p, i64 1, i64 2
%gep_rec_1 = getelementptr i32, i32* %gep, i64 1
%gep_rec_2 = getelementptr i32, i32* %gep_rec_1, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
load i32, i32* %gep_rec_2
ret void
}
; CHECK-LABEL: gep_recursion_max_lookup_depth_reached
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %a
; CHECK-DAG: MayAlias: i32* %a, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %a, i32* %gep
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_2
@ -178,13 +224,13 @@ define void @gep_recursion_level_2(i32* %a, <vscale x 4 x i32>* %p) {
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_4
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_5
; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_6
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_1
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_2
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_3
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_4
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_5
; CHECK-DAG: MayAlias: <vscale x 4 x i32>* %p, i32* %gep_rec_6
; CHECK-DAG: MayAlias: i32* %gep, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_1, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_2, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_3, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_4, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_5, <vscale x 4 x i32>* %p
; CHECK-DAG: MayAlias: i32* %gep_rec_6, <vscale x 4 x i32>* %p
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2
; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_3
@ -215,5 +261,14 @@ define void @gep_recursion_max_lookup_depth_reached(i32* %a, <vscale x 4 x i32>*
%gep_rec_4 = getelementptr i32, i32* %gep_rec_3, i64 1
%gep_rec_5 = getelementptr i32, i32* %gep_rec_4, i64 1
%gep_rec_6 = getelementptr i32, i32* %gep_rec_5, i64 1
load <vscale x 4 x i32>, <vscale x 4 x i32>* %p
load i32, i32* %a
load i32, i32* %gep
load i32, i32* %gep_rec_1
load i32, i32* %gep_rec_2
load i32, i32* %gep_rec_3
load i32, i32* %gep_rec_4
load i32, i32* %gep_rec_5
load i32, i32* %gep_rec_6
ret void
}

View File

@ -11,6 +11,8 @@ define void @test_with_zext() {
%2 = getelementptr inbounds i8, i8* %1, i64 16
%3 = zext i32 3 to i64
%b = getelementptr inbounds i8, i8* %2, i64 %3
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -23,19 +25,23 @@ define void @test_with_lshr(i64 %i) {
%2 = getelementptr inbounds i8, i8* %1, i64 16
%3 = lshr i64 %i, 2
%b = getelementptr inbounds i8, i8* %2, i64 %3
load i8, i8* %a
load i8, i8* %b
ret void
}
; CHECK-LABEL: test_with_lshr_different_sizes
; CHECK: NoAlias: i16* %m2.idx, i8* %m1
; CHECK: NoAlias: i8* %m1, i16* %m2.idx
define void @test_with_lshr_different_sizes(i64 %i) {
%m0 = tail call i8* @malloc(i64 120)
%m1 = getelementptr inbounds i8, i8* %m0, i64 1
load i8, i8* %m1
%m2 = getelementptr inbounds i8, i8* %m0, i64 2
%idx = lshr i64 %i, 2
%m2.i16 = bitcast i8* %m2 to i16*
%m2.idx = getelementptr inbounds i16, i16* %m2.i16, i64 %idx
load i16, i16* %m2.idx
ret void
}
@ -48,9 +54,11 @@ define void @test_with_a_loop(i8* %mem) {
for.loop:
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%a = getelementptr inbounds i8, i8* %mem, i64 8
load i8, i8* %a
%a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
%i.64 = zext i32 %i to i64
%b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
load i8, i8* %b
%i.plus1 = add nuw nsw i32 %i, 1
%cmp = icmp eq i32 %i.plus1, 10
br i1 %cmp, label %for.loop.exit, label %for.loop
@ -69,9 +77,11 @@ for.loop:
%mem = phi i8* [ %mem.orig, %0 ], [ %mem.plus1, %for.loop ]
%i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ]
%a = getelementptr inbounds i8, i8* %mem, i64 8
load i8, i8* %a
%a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16
%i.64 = zext i32 %i to i64
%b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64
load i8, i8* %b
%i.plus1 = add nuw nsw i32 %i, 1
%mem.plus1 = getelementptr inbounds i8, i8* %mem, i64 8
%cmp = icmp eq i32 %i.plus1, 10
@ -82,16 +92,18 @@ for.loop.exit:
}
; CHECK-LABEL: test_sign_extension
; CHECK: MayAlias: i64* %b.i64, i8* %a
; CHECK: MayAlias: i8* %a, i64* %b.i64
define void @test_sign_extension(i32 %p) {
%1 = tail call i8* @malloc(i64 120)
%p.64 = zext i32 %p to i64
%a = getelementptr inbounds i8, i8* %1, i64 %p.64
load i8, i8* %a
%p.minus1 = add i32 %p, -1
%p.minus1.64 = zext i32 %p.minus1 to i64
%b.i8 = getelementptr inbounds i8, i8* %1, i64 %p.minus1.64
%b.i64 = bitcast i8* %b.i8 to i64*
load i64, i64* %b.i64
ret void
}
@ -105,12 +117,14 @@ for.loop:
%i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ]
%idxprom = zext i32 %i to i64
%b = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 %idxprom
load i32, i32* %b
%i.next = add nuw nsw i32 %i, 1
%1 = icmp eq i32 %i.next, 10
br i1 %1, label %for.loop.exit, label %for.loop
%cmp = icmp eq i32 %i.next, 10
br i1 %cmp, label %for.loop.exit, label %for.loop
reorder:
%a = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 1
load i32, i32* %a
br label %for.loop
for.loop.exit:
@ -128,21 +142,23 @@ define void @test_spec2006() {
%d.val = load i32, i32* @d, align 4
%d.promoted = sext i32 %d.val to i64
%1 = icmp slt i32 %d.val, 2
br i1 %1, label %.lr.ph, label %3
br i1 %1, label %.lr.ph, label %bb3
.lr.ph: ; preds = %0
br label %2
br label %bb2
; <label>:2 ; preds = %.lr.ph, %2
%i = phi i32 [ %d.val, %.lr.ph ], [ %i.plus1, %2 ]
bb2:
%i = phi i32 [ %d.val, %.lr.ph ], [ %i.plus1, %bb2 ]
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %d.promoted, i64 %i.promoted
load i32*, i32** %x
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %2, label %3
br i1 %cmp, label %bb2, label %bb3
; <label>:3 ; preds = %._crit_edge, %0
bb3:
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
load i32*, i32** %y
ret void
}
@ -153,6 +169,8 @@ define void @test_modulo_analysis_easy_case(i64 %i) {
%h = alloca [1 x [2 x i32*]], align 16
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i, i64 0
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
load i32*, i32** %x
load i32*, i32** %y
ret void
}
@ -168,6 +186,8 @@ for.loop:
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 0
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
load i32*, i32** %x
load i32*, i32** %y
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %for.loop, label %for.loop.exit
@ -190,6 +210,8 @@ for.loop:
%i.promoted = sext i32 %i to i64
%x = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 %i.promoted, i64 %b.promoted
%y = getelementptr inbounds [1 x [2 x i32*]], [1 x [2 x i32*]]* %h, i64 0, i64 0, i64 1
load i32*, i32** %x
load i32*, i32** %y
%i.plus1 = add nsw i32 %i, 1
%cmp = icmp slt i32 %i.plus1, 2
br i1 %cmp, label %for.loop, label %for.loop.exit
@ -205,6 +227,8 @@ define void @test_const_eval(i8* %ptr, i64 %offset) {
%a.dup = getelementptr inbounds i8, i8* %ptr, i64 %offset
%three = zext i32 3 to i64
%b = getelementptr inbounds i8, i8* %a.dup, i64 %three
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -215,6 +239,8 @@ define void @test_const_eval_scaled(i8* %ptr) {
%six = mul i64 %three, 2
%a = getelementptr inbounds i8, i8* %ptr, i64 %six
%b = getelementptr inbounds i8, i8* %ptr, i64 6
load i8, i8* %a
load i8, i8* %b
ret void
}
@ -249,6 +275,8 @@ define void @test_shl_nuw_zext(i8* %p, i32 %x) {
%ext.shl = shl nuw i64 %ext, 1
%p.1 = getelementptr i8, i8* %p, i64 %shl.ext
%p.2 = getelementptr i8, i8* %p, i64 %ext.shl
load i8, i8* %p.1
load i8, i8* %p.2
ret void
}
@ -261,6 +289,8 @@ define void @test_shl_nsw_sext(i8* %p, i32 %x) {
%ext.shl = shl nsw i64 %ext, 1
%p.1 = getelementptr i8, i8* %p, i64 %shl.ext
%p.2 = getelementptr i8, i8* %p, i64 %ext.shl
load i8, i8* %p.1
load i8, i8* %p.2
ret void
}
@ -272,6 +302,8 @@ define void @test_implicit_sext(i8* %p, i32 %x) {
%ext.add = add i64 %ext, 1
%p.1 = getelementptr i8, i8* %p, i32 %add
%p.2 = getelementptr i8, i8* %p, i64 %ext.add
load i8, i8* %p.1
load i8, i8* %p.2
ret void
}
@ -283,6 +315,8 @@ define void @test_partial_decomposition(i8* %p, i32 %x) {
%add.2 = add nsw i32 %add, 1
%p.1 = getelementptr i8, i8* %p, i32 %add.1
%p.2 = getelementptr i8, i8* %p, i32 %add.2
load i8, i8* %p.1
load i8, i8* %p.2
ret void
}

View File

@ -5,11 +5,11 @@
; CHECK-LABEL: Function: test_assign
; CHECK: NoAlias: i64* %a, i64* %b
; CHECK: NoAlias: i32* %c, i64* %b
; CHECK: NoAlias: i32* %d, i64* %a
; CHECK: NoAlias: i64* %b, i32* %c
; CHECK: NoAlias: i64* %a, i32* %d
; CHECK: NoAlias: i32* %c, i32* %d
; CHECK: MayAlias: i32* %e, i64* %a
; CHECK: MayAlias: i32* %e, i64* %b
; CHECK: MayAlias: i64* %a, i32* %e
; CHECK: MayAlias: i64* %b, i32* %e
; CHECK: MayAlias: i32* %c, i32* %e
; CHECK: MayAlias: i32* %d, i32* %e
define void @test_assign(i1 %cond) {
@ -19,5 +19,10 @@ define void @test_assign(i1 %cond) {
%c = bitcast i64* %a to i32*
%d = bitcast i64* %b to i32*
%e = select i1 %cond, i32* %c, i32* %d
load i64, i64* %a
load i64, i64* %b
load i32, i32* %c
load i32, i32* %d
load i32, i32* %e
ret void
}
}

View File

@ -4,10 +4,10 @@
; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Function: test_assign2
; CHECK: NoAlias: i32* %b, i64* %a
; CHECK: NoAlias: i64* %a, i32* %b
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: NoAlias: i32* %b, i32* %d
; CHECK: MayAlias: i32* %e, i64* %a
; CHECK: MayAlias: i64* %a, i32* %e
; CHECK: MayAlias: i32* %b, i32* %e
; CHECK: MayAlias: i32* %c, i32* %e
; CHECK: MayAlias: i32* %d, i32* %e
@ -18,5 +18,10 @@ define void @test_assign2(i1 %cond) {
%c = bitcast i64* %a to i32*
%d = bitcast i64* %a to i32*
%e = select i1 %cond, i32* %c, i32* %b
load i64, i64* %a
load i32, i32* %b
load i32, i32* %c
load i32, i32* %d
load i32, i32* %e
ret void
}
}

View File

@ -4,19 +4,19 @@
; RUN: opt < %s -aa-pipeline=cfl-anders-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Function: test_attr_below
; CHECK: MayAlias: i64* %q, i64*** %p
; CHECK: NoAlias: i64* %esc, i64*** %p
; CHECK: NoAlias: i64* %esc, i64* %q
; CHECK-DAG: MayAlias: i64*** %p, i64* %q
; CHECK-DAG: NoAlias: i64* %esc, i64*** %p
; CHECK-DAG: NoAlias: i64* %esc, i64* %q
; CHECK: MayAlias: i64* %unknown, i64*** %p
; CHECK: MayAlias: i64* %q, i64* %unknown
; CHECK: MayAlias: i64* %esc, i64* %unknown
; CHECK: MayAlias: i64* %q, i64** %pdrf
; CHECK: MayAlias: i64* %esc, i64** %pdrf
; CHECK: MayAlias: i64* %unknown, i64** %pdrf
; CHECK: MayAlias: i64* %pdrf2, i64* %q
; CHECK: MayAlias: i64* %esc, i64* %pdrf2
; CHECK: MayAlias: i64* %pdrf2, i64* %unknown
; CHECK-DAG: MayAlias: i64*** %p, i64* %unknown
; CHECK-DAG: MayAlias: i64* %q, i64* %unknown
; CHECK-DAG: MayAlias: i64* %esc, i64* %unknown
; CHECK-DAG: MayAlias: i64** %pdrf, i64* %q
; CHECK-DAG: MayAlias: i64* %esc, i64** %pdrf
; CHECK-DAG: MayAlias: i64** %pdrf, i64* %unknown
; CHECK-DAG: MayAlias: i64* %pdrf2, i64* %q
; CHECK-DAG: MayAlias: i64* %esc, i64* %pdrf2
; CHECK-DAG: MayAlias: i64* %pdrf2, i64* %unknown
define void @test_attr_below(i64*** %p, i64* %q) {
%esc = alloca i64, align 8
%escint = ptrtoint i64* %esc to i64
@ -25,25 +25,30 @@ define void @test_attr_below(i64*** %p, i64* %q) {
%pdrf = load i64**, i64*** %p
%pdrf2 = load i64*, i64** %pdrf
load i64, i64* %q
load i64, i64* %esc
load i64, i64* %unknown
load i64, i64* %pdrf2
ret void
}
; CHECK-LABEL: Function: test_attr_assign_below
; CHECK: MayAlias: i64** %sel, i64*** %p
; CHECK: MayAlias: i64* %q, i64** %sel
; CHECK: MayAlias: i64** %a, i64** %sel
; CHECK: MayAlias: i64** %pdrf, i64** %sel
; CHECK-DAG: MayAlias: i64*** %p, i64** %sel
; CHECK-DAG: MayAlias: i64* %q, i64** %sel
; CHECK-DAG: MayAlias: i64** %a, i64** %sel
; CHECK-DAG: MayAlias: i64** %pdrf, i64** %sel
; CHECK: MayAlias: i64** %c, i64*** %p
; CHECK: MayAlias: i64* %q, i64** %c
; CHECK: MayAlias: i64** %a, i64** %c
; CHECK: MayAlias: i64** %c, i64** %pdrf
; CHECK: MayAlias: i64** %c, i64** %sel
; CHECK-DAG: MayAlias: i64** %c, i64*** %p
; CHECK-DAG: MayAlias: i64** %c, i64* %q
; CHECK-DAG: MayAlias: i64** %a, i64** %c
; CHECK-DAG: MayAlias: i64** %c, i64** %pdrf
; CHECK-DAG: MayAlias: i64** %c, i64** %sel
; CHECK: MayAlias: i64* %d, i64*** %p
; CHECK: MayAlias: i64* %d, i64* %q
; CHECK: MayAlias: i64* %d, i64** %pdrf
; CHECK: MayAlias: i64* %d, i64** %sel
; CHECK-DAG: MayAlias: i64* %d, i64*** %p
; CHECK-DAG: MayAlias: i64* %d, i64* %q
; CHECK-DAG: MayAlias: i64* %d, i64** %pdrf
; CHECK-DAG: MayAlias: i64* %d, i64** %sel
define void @test_attr_assign_below(i64*** %p, i64* %q, i1 %cond) {
%a = alloca i64*, align 8
%pdrf = load i64**, i64*** %p
@ -55,6 +60,13 @@ define void @test_attr_assign_below(i64*** %p, i64* %q, i1 %cond) {
%c = load i64**, i64*** %b
%d = load i64*, i64** %c
load i64, i64* %q
load i64*, i64** %a
load i64*, i64** %pdrf
load i64*, i64** %sel
load i64*, i64** %c
load i64, i64* %d
ret void
}

View File

@ -11,62 +11,75 @@ define void @test_local() {
%b = alloca i32, align 4
%aint = ptrtoint i32* %a to i64
%aAlias = inttoptr i64 %aint to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %aAlias
ret void
}
; CHECK-LABEL: Function: test_global_param
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: MayAlias: i32* %a, i32* %xload
; CHECK: MayAlias: i32* %a, i32* %gload
; CHECK: MayAlias: i32* %gload, i32* %xload
; CHECK: MayAlias: i32** %x, i32** @ext_global
; CHECK: NoAlias: i32* %a, i32** @ext_global
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: MayAlias: i32* %a, i32* %xload
; CHECK-DAG: MayAlias: i32* %a, i32* %gload
; CHECK-DAG: MayAlias: i32* %gload, i32* %xload
; CHECK-DAG: MayAlias: i32** %x, i32** @ext_global
; CHECK-DAG: NoAlias: i32* %a, i32** @ext_global
@ext_global = external global i32*
define void @test_global_param(i32** %x) {
%a = alloca i32, align 4
%aint = ptrtoint i32* %a to i64
%xload = load i32*, i32** %x
%gload = load i32*, i32** @ext_global
load i32, i32* %a
load i32, i32* %xload
load i32, i32* %gload
ret void
}
declare void @external_func(i32**)
; CHECK-LABEL: Function: test_external_call
; CHECK: NoAlias: i32* %b, i32* %x
; CHECK: NoAlias: i32* %b, i32** %a
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: MayAlias: i32* %c, i32** %a
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %b
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: MayAlias: i32** %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
define void @test_external_call(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
call void @external_func(i32** %a)
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %b
load i32, i32* %c
ret void
}
declare void @external_func_readonly(i32**) readonly
; CHECK-LABEL: Function: test_external_call_func_readonly
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %c, i32** %a
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %c
define void @test_external_call_func_readonly(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
store i32* %x, i32** %a, align 4
call void @external_func_readonly(i32** %a)
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %c
ret void
}
; CHECK-LABEL: Function: test_external_call_callsite_readonly
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %c, i32** %a
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %c
define void @test_external_call_callsite_readonly(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
store i32* %x, i32** %a, align 4
call void @external_func(i32** %a) readonly
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %c
ret void
}
@ -78,6 +91,9 @@ define void @test_external_call_normal_return(i32* %x) {
%a = alloca i32, align 8
%b = alloca i32, align 4
%c = call i32* @external_func_normal_return(i32* %a)
load i32, i32* %x
load i32, i32* %a
load i32, i32* %c
ret void
}
@ -89,5 +105,8 @@ define void @test_external_call_noalias_return(i32* %x) {
%a = alloca i32, align 8
%b = alloca i32, align 4
%c = call i32* @external_func_noalias_return(i32* %a)
load i32, i32* %x
load i32, i32* %a
load i32, i32* %c
ret void
}

View File

@ -15,6 +15,8 @@ define void @noop_callee(i32* %arg1, i32* %arg2) {
define void @test_noop() {
%a = alloca i32, align 4
%b = alloca i32, align 4
load i32, i32* %a
load i32, i32* %b
call void @noop_callee(i32* %a, i32* %b)
ret void

View File

@ -10,24 +10,27 @@
; CHECK: NoAlias: i64** %b, i64**** %d
; CHECK: NoAlias: i64*** %c, i64**** %d
; CHECK: NoAlias: i64* %a, i64* %e
; CHECK: NoAlias: i64* %e, i64** %b
; CHECK: NoAlias: i64* %e, i64*** %c
; CHECK: NoAlias: i64** %b, i64* %e
; CHECK: NoAlias: i64*** %c, i64* %e
; CHECK: MayAlias: i64* %a, i64* %f
; CHECK: NoAlias: i64* %f, i64** %b
; CHECK: NoAlias: i64* %f, i64*** %c
; CHECK: MayAlias: i64* %f, i64**** %d
; CHECK: NoAlias: i64** %b, i64* %f
; CHECK: NoAlias: i64*** %c, i64* %f
; CHECK: MayAlias: i64**** %d, i64* %f
; CHECK: MayAlias: i64* %e, i64* %f
define void @test_cycle() {
%a = alloca i64, align 8
%b = alloca i64*, align 8
%c = alloca i64**, align 8
%d = alloca i64***, align 8
load i64, i64* %a
store i64* %a, i64** %b
store i64** %b, i64*** %c
store i64*** %c, i64**** %d
%e = bitcast i64**** %d to i64*
load i64, i64* %e
store i64* %e, i64** %b
%f = load i64*, i64** %b
load i64, i64* %f
ret void
}

View File

@ -10,23 +10,26 @@ define void @escape_arg_deref(i32** %arg) {
ret void
}
; CHECK-LABEL: Function: test_arg_deref_escape
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: NoAlias: i32* %b, i32** %x
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32** %p, i32** %x
; CHECK: NoAlias: i32* %a, i32** %p
; CHECK: NoAlias: i32* %b, i32** %p
; CHECK: MayAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: NoAlias: i32* %c, i32** %p
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: NoAlias: i32* %b, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: NoAlias: i32** %p, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32** %p
; CHECK-DAG: NoAlias: i32* %b, i32** %p
; CHECK-DAG: MayAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %c, i32** %p
define void @test_arg_deref_escape(i32** %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
%p = alloca i32*, align 4
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
call void @escape_arg_deref(i32** %p)
%c = load i32*, i32** %x
load i32, i32* %c
ret void
}
}

View File

@ -9,22 +9,26 @@ define void @escape_arg(i32* %arg) {
ret void
}
; CHECK-LABEL: Function: test_arg_escape
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: NoAlias: i32* %b, i32** %x
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %c, i32** %x
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: MayAlias: i32* %a, i32* %d
; CHECK: MayAlias: i32* %b, i32* %d
; CHECK: NoAlias: i32* %c, i32* %d
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: NoAlias: i32* %b, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: NoAlias: i32* %c, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
; CHECK-DAG: MayAlias: i32* %a, i32* %d
; CHECK-DAG: MayAlias: i32* %b, i32* %d
; CHECK-DAG: NoAlias: i32* %c, i32* %d
define void @test_arg_escape(i32** %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
call void @escape_arg(i32* %a)
call void @escape_arg(i32* %b)
%d = load i32*, i32** %x
load i32, i32* %d
ret void
}
}

View File

@ -20,6 +20,9 @@ define void @test_return_arg() {
%b = alloca i32, align 4
%c = call i32* @return_arg_callee(i32* %a, i32* %b)
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
ret void
}
}

View File

@ -39,13 +39,18 @@ define void @test_return_deref_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32** %p, i32*** %pp
%c = call i32* @return_deref_arg_multilevel_callee(i32*** %pp)
load i32, i32* %c
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}
}

View File

@ -27,10 +27,14 @@ define void @test_return_deref_arg() {
%b = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
%c = call i32* @return_deref_arg_callee(i32** %p)
load i32, i32* %c
%lp = load i32*, i32** %p
load i32, i32* %lp
ret void
}
}

View File

@ -27,6 +27,10 @@ define void @test_return_escape(i32** %x) {
%b = call i32* @return_escaped_callee()
%c = call i32* @return_escaped_callee()
%d = load i32*, i32** %x
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
load i32, i32* %d
ret void
}
}

View File

@ -15,20 +15,20 @@ define i32*** @return_ref_arg_multilevel_callee(i32* %arg1) {
ret i32*** %ptr_cast
}
; CHECK-LABEL: Function: test_return_ref_arg_multilevel
; CHECK: NoAlias: i32* %a, i32*** %b
; CHECK: NoAlias: i32** %p, i32*** %b
; CHECK: NoAlias: i32*** %b, i32*** %pp
; CHECK: NoAlias: i32* %a, i32** %lb
; CHECK: NoAlias: i32** %lb, i32** %p
; CHECK: NoAlias: i32** %lb, i32*** %pp
; CHECK: NoAlias: i32** %lb, i32*** %b
; CHECK: MayAlias: i32* %a, i32* %lb_deref
; CHECK: NoAlias: i32* %lb_deref, i32** %lpp
; CHECK: MayAlias: i32* %lb_deref, i32* %lpp_deref
; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
; CHECK: MayAlias: i32* %lb_deref, i32* %lp
; CHECK: NoAlias: i32* %lp, i32** %lpp
; CHECK: MayAlias: i32* %lp, i32* %lpp_deref
; CHECK-DAG: NoAlias: i32* %a, i32*** %b
; CHECK-DAG: NoAlias: i32*** %b, i32** %p
; CHECK-DAG: NoAlias: i32*** %b, i32*** %pp
; CHECK-DAG: NoAlias: i32* %a, i32** %lb
; CHECK-DAG: NoAlias: i32** %lb, i32** %p
; CHECK-DAG: NoAlias: i32** %lb, i32*** %pp
; CHECK-DAG: NoAlias: i32*** %b, i32** %lb
; CHECK-DAG: MayAlias: i32* %a, i32* %lb_deref
; CHECK-DAG: NoAlias: i32* %lb_deref, i32** %lpp
; CHECK-DAG: MayAlias: i32* %lb_deref, i32* %lpp_deref
; CHECK-DAG: NoAlias: i32** %lpp, i32* %lpp_deref
; CHECK-DAG: MayAlias: i32* %lb_deref, i32* %lp
; CHECK-DAG: NoAlias: i32* %lp, i32** %lpp
; CHECK-DAG: MayAlias: i32* %lp, i32* %lpp_deref
; Temporarily disable modref checks
; Just Mod: Ptr: i32*** %b <-> %b = call i32*** @return_ref_arg_multilevel_callee(i32* %a)
@ -38,6 +38,7 @@ define void @test_return_ref_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
store i32* %a, i32** %p
store i32** %p, i32*** %pp
%b = call i32*** @return_ref_arg_multilevel_callee(i32* %a)
@ -47,6 +48,9 @@ define void @test_return_ref_arg_multilevel() {
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lb_deref
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}
}

View File

@ -15,9 +15,9 @@ define i32** @return_ref_arg_callee(i32* %arg1) {
; CHECK: NoAlias: i32** %b, i32** %p
; CHECK: MayAlias: i32* %a, i32* %lb
; CHECK: NoAlias: i32* %lb, i32** %p
; CHECK: NoAlias: i32* %lb, i32** %b
; CHECK: NoAlias: i32** %b, i32* %lb
; CHECK: NoAlias: i32* %lp, i32** %p
; CHECK: NoAlias: i32* %lp, i32** %b
; CHECK: NoAlias: i32** %b, i32* %lp
; CHECK: MayAlias: i32* %lb, i32* %lp
; Temporarily disable modref checks
@ -26,11 +26,14 @@ define void @test_return_ref_arg() {
%a = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %a
store i32* %a, i32** %p
%b = call i32** @return_ref_arg_callee(i32* %a)
%lb = load i32*, i32** %b
%lp = load i32*, i32** %p
load i32, i32* %lb
load i32, i32* %lp
ret void
}
}

View File

@ -8,15 +8,19 @@ define i32* @return_unknown_callee(i32* %arg1, i32* %arg2) {
ret i32* @g
}
; CHECK-LABEL: Function: test_return_unknown
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
define void @test_return_unknown(i32* %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = call i32* @return_unknown_callee(i32* %a, i32* %b)
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
load i32, i32* %x
ret void
}
@ -26,12 +30,14 @@ define i32** @return_unknown_callee2() {
ret i32** @g2
}
; CHECK-LABEL: Function: test_return_unknown2
; CHECK: MayAlias: i32* %x, i32** %a
; CHECK: MayAlias: i32* %b, i32* %x
; CHECK: MayAlias: i32* %b, i32** %a
; CHECK-DAG: MayAlias: i32** %a, i32* %x
; CHECK-DAG: MayAlias: i32* %b, i32* %x
; CHECK-DAG: MayAlias: i32** %a, i32* %b
define void @test_return_unknown2(i32* %x) {
%a = call i32** @return_unknown_callee2()
%b = load i32*, i32** %a
load i32, i32* %b
load i32, i32* %x
ret void
}
}

View File

@ -21,7 +21,7 @@ define void @store_arg_multilevel_callee(i32*** %arg1, i32* %arg2) {
; CHECK: MayAlias: i32* %b, i32* %lpp_deref
; CHECK: NoAlias: i32* %lpp_deref, i32** %p
; CHECK: NoAlias: i32* %lpp_deref, i32*** %pp
; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
; CHECK: NoAlias: i32** %lpp, i32* %lpp_deref
; CHECK: MayAlias: i32* %a, i32* %lp
; CHECK: NoAlias: i32* %lp, i32*** %pp
; CHECK: NoAlias: i32* %lp, i32** %lpp
@ -32,6 +32,8 @@ define void @test_store_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32** %p, i32*** %pp
call void @store_arg_multilevel_callee(i32*** %pp, i32* %b)
@ -39,6 +41,8 @@ define void @test_store_arg_multilevel() {
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}
}

View File

@ -10,7 +10,7 @@ define void @store_arg_unknown_callee(i32** %arg1) {
ret void
}
; CHECK-LABEL: Function: test_store_arg_unknown
; CHECK: NoAlias: i32* %x, i32** %p
; CHECK: NoAlias: i32** %p, i32* %x
; CHECK: NoAlias: i32* %a, i32** %p
; CHECK: NoAlias: i32* %b, i32** %p
; CHECK: MayAlias: i32* %lp, i32* %x
@ -22,10 +22,14 @@ define void @test_store_arg_unknown(i32* %x) {
%b = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %x
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
call void @store_arg_unknown_callee(i32** %p)
%lp = load i32*, i32** %p
load i32, i32* %lp
ret void
}
}

View File

@ -28,12 +28,16 @@ define void @test_store_arg() {
%p = alloca i32*, align 8
%q = alloca i32*, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32* %b, i32** %q
call void @store_arg_callee(i32** %p, i32* %b)
%lp = load i32*, i32** %p
%lq = load i32*, i32** %q
load i32, i32* %lp
load i32, i32* %lq
ret void
}
}

View File

@ -5,16 +5,18 @@
; CHECK-LABEL: Function: test_memalias
; CHECK: NoAlias: i64* %a, i64** %b
; CHECK: NoAlias: i32** %c, i64* %a
; CHECK: MayAlias: i32* %d, i64* %a
; CHECK: NoAlias: i32* %d, i64** %b
; CHECK: NoAlias: i32* %d, i32** %c
; CHECK: NoAlias: i64* %a, i32** %c
; CHECK: MayAlias: i64* %a, i32* %d
; CHECK: NoAlias: i64** %b, i32* %d
; CHECK: NoAlias: i32** %c, i32* %d
define void @test_memalias() {
%a = alloca i64, align 8
%b = alloca i64*, align 8
load i64, i64* %a
store i64* %a, i64** %b
%c = bitcast i64** %b to i32**
%d = load i32*, i32** %c
load i32, i32* %d
ret void
}
}

View File

@ -3,18 +3,24 @@
; (Everything should alias everything, because args can alias globals, so the
; aliasing sets should of args+alloca+global should be combined)
; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-may-aliases -disable-output 2>&1 | FileCheck %s
; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK: Function: test
@g = external global i32
; CHECK: MayAlias: i32* %arg1, i32* %arg2
; CHECK: NoAlias: i32* %A, i32* %arg1
; CHECK: NoAlias: i32* %A, i32* %arg2
; CHECK: MayAlias: i32* %arg1, i32* @g
; CHECK: MayAlias: i32* %arg2, i32* @g
; CHECK: MayAlias: i32* %A, i32* @g
define void @test(i1 %c, i32* %arg1, i32* %arg2) {
; CHECK: 15 Total Alias Queries Performed
; CHECK: 0 no alias responses
%A = alloca i32, align 4
%B = select i1 %c, i32* %arg1, i32* %arg2
%C = select i1 %c, i32* @g, i32* %A
%A = alloca i32
load i32, i32* %arg1
load i32, i32* %arg2
load i32, i32* %A
load i32, i32* @g
ret void
}

View File

@ -10,6 +10,10 @@ define void @test(i1 %c, i32* %arg1, i32* %arg2) {
; CHECK: 3 no alias responses
%a = alloca i32, align 4
%b = select i1 %c, i32* %arg1, i32* %arg2
load i32, i32* %a
load i32, i32* %b
load i32, i32* %arg1
load i32, i32* %arg2
ret void
}

View File

@ -12,5 +12,7 @@ define void @test_no_crash() #0 {
entry:
call i8* asm "nop", "=r,r"(
i8* getelementptr inbounds ([1 x i8], [1 x i8]* @G, i64 0, i64 0))
load [1 x i8], [1 x i8]* @G
load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @G, i64 0, i64 0)
ret void
}

View File

@ -11,83 +11,102 @@ define void @test_local() {
%b = alloca i32, align 4
%aint = ptrtoint i32* %a to i64
%aAlias = inttoptr i64 %aint to i32*
load i32, i32* %a
load i32, i32* %b
load i32, i32* %aAlias
ret void
}
; CHECK-LABEL: Function: test_global_param
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: MayAlias: i32* %a, i32* %xload
; CHECK: MayAlias: i32* %a, i32* %gload
; CHECK: MayAlias: i32* %gload, i32* %xload
; CHECK: MayAlias: i32** %x, i32** @ext_global
; CHECK: NoAlias: i32* %a, i32** @ext_global
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: MayAlias: i32* %a, i32* %xload
; CHECK-DAG: MayAlias: i32* %a, i32* %gload
; CHECK-DAG: MayAlias: i32* %gload, i32* %xload
; CHECK-DAG: MayAlias: i32** %x, i32** @ext_global
; CHECK-DAG: NoAlias: i32* %a, i32** @ext_global
@ext_global = external global i32*
define void @test_global_param(i32** %x) {
%a = alloca i32, align 4
%aint = ptrtoint i32* %a to i64
%xload = load i32*, i32** %x
%gload = load i32*, i32** @ext_global
load i32, i32* %a
load i32, i32* %xload
load i32, i32* %gload
ret void
}
declare void @external_func(i32**)
; CHECK-LABEL: Function: test_external_call
; CHECK: NoAlias: i32* %b, i32* %x
; CHECK: NoAlias: i32* %b, i32** %a
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: MayAlias: i32* %c, i32** %a
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %b
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: MayAlias: i32** %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
define void @test_external_call(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
call void @external_func(i32** %a)
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %b
load i32, i32* %c
ret void
}
declare void @external_func_readonly(i32**) readonly
; CHECK-LABEL: Function: test_external_call_func_readonly
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %c, i32** %a
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %c
define void @test_external_call_func_readonly(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
store i32* %x, i32** %a, align 4
call void @external_func_readonly(i32** %a)
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %c
ret void
}
; CHECK-LABEL: Function: test_external_call_callsite_readonly
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %c, i32** %a
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32** %a, i32* %c
define void @test_external_call_callsite_readonly(i32* %x) {
%a = alloca i32*, align 8
%b = alloca i32, align 4
store i32* %x, i32** %a, align 4
call void @external_func(i32** %a) readonly
%c = load i32*, i32** %a
load i32, i32* %x
load i32, i32* %c
ret void
}
declare i32* @external_func_normal_return(i32*)
; CHECK-LABEL: Function: test_external_call_normal_return
; CHECK: MayAlias: i32* %c, i32* %x
; CHECK: MayAlias: i32* %a, i32* %c
; CHECK-DAG: MayAlias: i32* %c, i32* %x
; CHECK-DAG: MayAlias: i32* %a, i32* %c
define void @test_external_call_normal_return(i32* %x) {
%a = alloca i32, align 8
%b = alloca i32, align 4
%c = call i32* @external_func_normal_return(i32* %a)
load i32, i32* %a
load i32, i32* %x
load i32, i32* %c
ret void
}
declare noalias i32* @external_func_noalias_return(i32*)
; CHECK-LABEL: Function: test_external_call_noalias_return
; CHECK: NoAlias: i32* %c, i32* %x
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %c, i32* %x
; CHECK-DAG: NoAlias: i32* %a, i32* %c
define void @test_external_call_noalias_return(i32* %x) {
%a = alloca i32, align 8
%b = alloca i32, align 4
%c = call i32* @external_func_noalias_return(i32* %a)
load i32, i32* %a
load i32, i32* %x
load i32, i32* %c
ret void
}

View File

@ -15,6 +15,8 @@ define void @noop_callee(i32* %arg1, i32* %arg2) {
define void @test_noop() {
%a = alloca i32, align 4
%b = alloca i32, align 4
load i32, i32* %a
load i32, i32* %b
call void @noop_callee(i32* %a, i32* %b)
ret void

View File

@ -25,6 +25,7 @@ entry:
%i = alloca i32, align 4
%AliasA1 = alloca i32**, align 8
%ShouldAliasA = alloca i32*, align 8
%ignore1 = load i32*, i32** %A
store i64 0, i64* %RefCopy, align 8
store i32 0, i32* %i, align 4
br label %for.cond

View File

@ -21,6 +21,9 @@ define void @test() {
%D = getelementptr %T, %T* @G, i64 0, i32 0
%F = getelementptr i32, i32* getelementptr (%T, %T* @G, i64 0, i32 0), i64 0
%X = getelementptr [10 x i8], [10 x i8]* getelementptr (%T, %T* @G, i64 0, i32 1), i64 0, i64 5
load i32, i32* %D
load i32, i32* %F
load i8, i8* %X
ret void
}
@ -32,6 +35,9 @@ define void @test() {
define void @simplecheck(i32* %arg0) {
%F = getelementptr i32, i32* getelementptr (%T, %T* @G, i64 0, i32 0), i64 0
%H = getelementptr %T, %T* @G2, i64 0, i32 0
load i32, i32* %arg0
load i32, i32* %F
load i32, i32* %H
ret void
}
@ -53,5 +59,7 @@ define void @checkNesting(i32* %arg0) {
i32 0),
i64 0,
i32 0
load i32, i32* %arg0
load i32, i32* %A
ret void
}

View File

@ -7,20 +7,21 @@
@g3 = extern_weak dso_local global i32, align 4
; CHECK-LABEL: Function: foo
; CHECK: NoAlias: i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3), i32** %a
; CHECK: NoAlias: i32* %b, i32** %a
; CHECK: MayAlias: i32* %b, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK: NoAlias: i32* @g2, i32** %a
; CHECK: MayAlias: i32* @g2, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK: MayAlias: i32* %b, i32* @g2
; CHECK: NoAlias: i32* @g3, i32** %a
; CHECK: MayAlias: i32* @g3, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK: MayAlias: i32* %b, i32* @g3
; CHECK: MayAlias: i32* @g2, i32* @g3
; CHECK-DAG: NoAlias: i32** %a, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK-DAG: NoAlias: i32** %a, i32* %b
; CHECK-DAG: MayAlias: i32* %b, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK-DAG: NoAlias: i32** %a, i32* @g2
; CHECK-DAG: MayAlias: i32* @g2, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK-DAG: MayAlias: i32* %b, i32* @g2
; CHECK-DAG: NoAlias: i32** %a, i32* @g3
; CHECK-DAG: MayAlias: i32* @g3, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
; CHECK-DAG: MayAlias: i32* %b, i32* @g3
; CHECK-DAG: MayAlias: i32* @g2, i32* @g3
define void @foo() {
entry:
%a = alloca i32*, align 8
load i32, i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3)
store i32* select (i1 icmp ne (i32* @g, i32* null), i32* @g2, i32* @g3), i32** %a
%b = load i32*, i32** %a
%c = load i32, i32* %b

View File

@ -9,5 +9,9 @@ define void @foo(i32 %n) {
%b = alloca [2 x i32], align 4
%c = getelementptr inbounds [2 x i32], [2 x i32]* %a, i32 0, i32 %n
%d = getelementptr inbounds [2 x i32], [2 x i32]* %b, i32 0, i32 %n
load [2 x i32], [2 x i32]* %a
load [2 x i32], [2 x i32]* %b
load i32, i32* %c
load i32, i32* %d
ret void
}

View File

@ -10,23 +10,26 @@ define void @escape_arg_deref(i32** %arg) {
ret void
}
; CHECK-LABEL: Function: test_arg_deref_escape
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: NoAlias: i32* %b, i32** %x
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32** %p, i32** %x
; CHECK: NoAlias: i32* %a, i32** %p
; CHECK: NoAlias: i32* %b, i32** %p
; CHECK: MayAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: NoAlias: i32* %c, i32** %p
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: NoAlias: i32* %b, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: NoAlias: i32** %p, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32** %p
; CHECK-DAG: NoAlias: i32* %b, i32** %p
; CHECK-DAG: MayAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %c, i32** %p
define void @test_arg_deref_escape(i32** %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
%p = alloca i32*, align 4
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
call void @escape_arg_deref(i32** %p)
%c = load i32*, i32** %x
load i32, i32* %c
ret void
}
}

View File

@ -9,22 +9,26 @@ define void @escape_arg(i32* %arg) {
ret void
}
; CHECK-LABEL: Function: test_arg_escape
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: NoAlias: i32* %b, i32** %x
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %c, i32** %x
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: MayAlias: i32* %a, i32* %d
; CHECK: MayAlias: i32* %b, i32* %d
; CHECK: NoAlias: i32* %c, i32* %d
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: NoAlias: i32* %b, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: NoAlias: i32* %c, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
; CHECK-DAG: MayAlias: i32* %a, i32* %d
; CHECK-DAG: MayAlias: i32* %b, i32* %d
; CHECK-DAG: NoAlias: i32* %c, i32* %d
define void @test_arg_escape(i32** %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
call void @escape_arg(i32* %a)
call void @escape_arg(i32* %b)
%d = load i32*, i32** %x
load i32, i32* %d
ret void
}
}

View File

@ -17,7 +17,10 @@ define void @test_return_arg() {
%a = alloca i32, align 4
%b = alloca i32, align 4
load i32, i32* %a
load i32, i32* %b
%c = call i32* @return_arg_callee(i32* %a, i32* %b)
load i32, i32* %c
ret void
}
}

View File

@ -33,13 +33,18 @@ define void @test_return_deref_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32** %p, i32*** %pp
%c = call i32* @return_deref_arg_multilevel_callee(i32*** %pp)
load i32, i32* %c
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}
}

View File

@ -20,10 +20,14 @@ define void @test_return_deref_arg() {
%b = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
%c = call i32* @return_deref_arg_callee(i32** %p)
%lp = load i32*, i32** %p
load i32, i32* %c
load i32, i32* %lp
ret void
}
}

View File

@ -13,20 +13,24 @@ define i32* @return_escaped_callee() {
ret i32* %ptr_cast
}
; CHECK-LABEL: Function: test_return_escape
; CHECK: NoAlias: i32* %a, i32** %x
; CHECK: NoAlias: i32* %b, i32** %x
; CHECK: NoAlias: i32* %a, i32* %b
; CHECK: NoAlias: i32* %c, i32** %x
; CHECK: NoAlias: i32* %a, i32* %c
; CHECK: NoAlias: i32* %b, i32* %c
; CHECK: NoAlias: i32* %a, i32* %d
; CHECK: MayAlias: i32* %b, i32* %d
; CHECK: MayAlias: i32* %c, i32* %d
; CHECK-DAG: NoAlias: i32* %a, i32** %x
; CHECK-DAG: NoAlias: i32* %b, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %b
; CHECK-DAG: NoAlias: i32* %c, i32** %x
; CHECK-DAG: NoAlias: i32* %a, i32* %c
; CHECK-DAG: NoAlias: i32* %b, i32* %c
; CHECK-DAG: NoAlias: i32* %a, i32* %d
; CHECK-DAG: MayAlias: i32* %b, i32* %d
; CHECK-DAG: MayAlias: i32* %c, i32* %d
define void @test_return_escape(i32** %x) {
%a = alloca i32, align 4
%b = call i32* @return_escaped_callee()
%c = call i32* @return_escaped_callee()
load i32, i32* %a
load i32, i32* %b
load i32, i32* %c
%d = load i32*, i32** %x
load i32, i32* %d
ret void
}
}

View File

@ -15,18 +15,18 @@ define i32*** @return_ref_arg_multilevel_callee(i32* %arg1) {
ret i32*** %ptr_cast
}
; CHECK-LABEL: Function: test_return_ref_arg_multilevel
; CHECK: NoAlias: i32* %a, i32*** %b
; CHECK: NoAlias: i32** %p, i32*** %b
; CHECK: NoAlias: i32* %a, i32** %lb
; CHECK: NoAlias: i32** %lb, i32*** %pp
; CHECK: NoAlias: i32** %lb, i32*** %b
; CHECK: MayAlias: i32* %a, i32* %lb_deref
; CHECK: NoAlias: i32* %lb_deref, i32** %lpp
; CHECK: MayAlias: i32* %lb_deref, i32* %lpp_deref
; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
; CHECK: MayAlias: i32* %lb_deref, i32* %lp
; CHECK: NoAlias: i32* %lp, i32** %lpp
; CHECK: MayAlias: i32* %lp, i32* %lpp_deref
; CHECK-DAG: NoAlias: i32* %a, i32*** %b
; CHECK-DAG: NoAlias: i32*** %b, i32** %p
; CHECK-DAG: NoAlias: i32* %a, i32** %lb
; CHECK-DAG: NoAlias: i32** %lb, i32*** %pp
; CHECK-DAG: NoAlias: i32*** %b, i32** %lb
; CHECK-DAG: MayAlias: i32* %a, i32* %lb_deref
; CHECK-DAG: NoAlias: i32* %lb_deref, i32** %lpp
; CHECK-DAG: MayAlias: i32* %lb_deref, i32* %lpp_deref
; CHECK-DAG: NoAlias: i32** %lpp, i32* %lpp_deref
; CHECK-DAG: MayAlias: i32* %lb_deref, i32* %lp
; CHECK-DAG: NoAlias: i32* %lp, i32** %lpp
; CHECK-DAG: MayAlias: i32* %lp, i32* %lpp_deref
; We could've proven the following facts if the analysis were inclusion-based:
; NoAlias: i32*** %b, i32*** %pp
@ -36,6 +36,7 @@ define void @test_return_ref_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
store i32* %a, i32** %p
store i32** %p, i32*** %pp
%b = call i32*** @return_ref_arg_multilevel_callee(i32* %a)
@ -45,6 +46,9 @@ define void @test_return_ref_arg_multilevel() {
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lb_deref
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}
}

View File

@ -14,9 +14,9 @@ define i32** @return_ref_arg_callee(i32* %arg1) {
; CHECK-LABEL: Function: test_return_ref_arg
; CHECK: MayAlias: i32* %a, i32* %lb
; CHECK: NoAlias: i32* %lb, i32** %p
; CHECK: NoAlias: i32* %lb, i32** %b
; CHECK: NoAlias: i32** %b, i32* %lb
; CHECK: NoAlias: i32* %lp, i32** %p
; CHECK: NoAlias: i32* %lp, i32** %b
; CHECK: NoAlias: i32** %b, i32* %lp
; CHECK: MayAlias: i32* %lb, i32* %lp
; We could've proven the following facts if the analysis were inclusion-based:
@ -25,11 +25,14 @@ define void @test_return_ref_arg() {
%a = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %a
store i32* %a, i32** %p
%b = call i32** @return_ref_arg_callee(i32* %a)
%lb = load i32*, i32** %b
%lp = load i32*, i32** %p
load i32, i32* %lb
load i32, i32* %lp
ret void
}
}

View File

@ -16,7 +16,11 @@ define void @test_return_unknown(i32* %x) {
%a = alloca i32, align 4
%b = alloca i32, align 4
load i32, i32* %x
load i32, i32* %a
load i32, i32* %b
%c = call i32* @return_unknown_callee(i32* %a, i32* %b)
load i32, i32* %c
ret void
}
@ -26,12 +30,14 @@ define i32** @return_unknown_callee2() {
ret i32** @g2
}
; CHECK-LABEL: Function: test_return_unknown2
; CHECK: MayAlias: i32* %x, i32** %a
; CHECK: MayAlias: i32** %a, i32* %x
; CHECK: MayAlias: i32* %b, i32* %x
; CHECK: MayAlias: i32* %b, i32** %a
; CHECK: MayAlias: i32** %a, i32* %b
define void @test_return_unknown2(i32* %x) {
load i32, i32* %x
%a = call i32** @return_unknown_callee2()
%b = load i32*, i32** %a
load i32, i32* %b
ret void
}
}

View File

@ -20,7 +20,7 @@ define void @store_arg_multilevel_callee(i32*** %arg1, i32* %arg2) {
; CHECK: MayAlias: i32* %b, i32* %lpp_deref
; CHECK: NoAlias: i32* %lpp_deref, i32** %p
; CHECK: NoAlias: i32* %lpp_deref, i32*** %pp
; CHECK: NoAlias: i32* %lpp_deref, i32** %lpp
; CHECK: NoAlias: i32** %lpp, i32* %lpp_deref
; CHECK: MayAlias: i32* %a, i32* %lp
; CHECK: NoAlias: i32* %lp, i32*** %pp
; CHECK: NoAlias: i32* %lp, i32** %lpp
@ -34,6 +34,8 @@ define void @test_store_arg_multilevel() {
%p = alloca i32*, align 8
%pp = alloca i32**, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32** %p, i32*** %pp
call void @store_arg_multilevel_callee(i32*** %pp, i32* %b)
@ -41,6 +43,8 @@ define void @test_store_arg_multilevel() {
%lpp = load i32**, i32*** %pp
%lpp_deref = load i32*, i32** %lpp
%lp = load i32*, i32** %p
load i32, i32* %lpp_deref
load i32, i32* %lp
ret void
}

View File

@ -10,7 +10,7 @@ define void @store_arg_unknown_callee(i32** %arg1) {
ret void
}
; CHECK-LABEL: Function: test_store_arg_unknown
; CHECK: NoAlias: i32* %x, i32** %p
; CHECK: NoAlias: i32** %p, i32* %x
; CHECK: NoAlias: i32* %a, i32** %p
; CHECK: NoAlias: i32* %b, i32** %p
; CHECK: MayAlias: i32* %lp, i32* %x
@ -22,10 +22,14 @@ define void @test_store_arg_unknown(i32* %x) {
%b = alloca i32, align 4
%p = alloca i32*, align 8
load i32, i32* %x
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
call void @store_arg_unknown_callee(i32** %p)
%lp = load i32*, i32** %p
load i32, i32* %lp
ret void
}
}

View File

@ -24,12 +24,16 @@ define void @test_store_arg() {
%p = alloca i32*, align 8
%q = alloca i32*, align 8
load i32, i32* %a
load i32, i32* %b
store i32* %a, i32** %p
store i32* %b, i32** %q
call void @store_arg_callee(i32** %p, i32* %b)
%lp = load i32*, i32** %p
%lq = load i32*, i32** %q
load i32, i32* %lp
load i32, i32* %lq
ret void
}
}

View File

@ -10,6 +10,8 @@ declare void @free(i8* nocapture)
; CHECK: NoAlias: i8* %p, i8* %q
define void @test_malloc(i8* %p) {
%q = call i8* @malloc(i64 4)
load i8, i8* %p
load i8, i8* %q
ret void
}
@ -17,6 +19,8 @@ define void @test_malloc(i8* %p) {
; CHECK: NoAlias: i8* %p, i8* %q
define void @test_calloc(i8* %p) {
%q = call i8* @calloc(i64 2, i64 4)
load i8, i8* %p
load i8, i8* %q
ret void
}
@ -25,5 +29,7 @@ define void @test_calloc(i8* %p) {
define void @test_free(i8* %p) {
%q = alloca i8, align 4
call void @free(i8* %q)
load i8, i8* %p
load i8, i8* %q
ret void
}

View File

@ -26,6 +26,10 @@ define void @test(i1 %C) {
store %T* %MS, %T** %M
%AP = load %T*, %T** %M ; PartialAlias with %A, %B
load %T, %T* %A
load %T, %T* %B
load %T, %T* %MS
load %T, %T* %AP
ret void
}

View File

@ -25,6 +25,10 @@ define void @test() {
%AP = load %T*, %T** %M ; PartialAlias with %A
%BP = load %T*, %T** %N ; PartialAlias with %B
load %T, %T* %A
load %T, %T* %B
load %T, %T* %AP
load %T, %T* %BP
ret void
}

View File

@ -41,7 +41,7 @@ entry:
ret i8 %loaded
}
; Incoming pointer arguments should not be PartialAlias because we do not know their initial state
; Incoming pointer arguments should not be MayAlias because we do not know their initial state
; even if they are nocapture
; CHECK: MayAlias: double* %A, double* %Index
define void @testr2(double* nocapture readonly %A, double* nocapture readonly %Index) {
@ -51,5 +51,7 @@ define void @testr2(double* nocapture readonly %A, double* nocapture readonly %I
%2 = load double, double* %arrayidx25
%3 = fneg double %1
%mul26 = fmul double %3, %2
load double, double* %A
load double, double* %Index
ret void
}

View File

@ -11,8 +11,11 @@
define void @test(i8* %Arg) {
%Noalias = alloca i8
%Escapes = alloca i8
load i8, i8* %Arg
load i8, i8* %Escapes
call void @set_thepointer(i8* %Escapes)
%Retrieved = call i8* @get_thepointer()
load i8, i8* %Retrieved
ret void
}

View File

@ -16,6 +16,7 @@ entry:
define void @bar(i32* %A, i32* %B) {
entry:
store i32 0, i32* %A, align 4
load i32, i32* %B
%arrayidx = getelementptr inbounds i32, i32* %B, i64 1
store i32 0, i32* %arrayidx, align 4
ret void

View File

@ -17,17 +17,19 @@ define void @test(i1 %cond,
i32* %arg26, i32* %arg27, i32* %arg28, i32* %arg29, i32* %arg30,
i32* %arg31, i32* %arg32, i32* %arg33, i32* %arg34, i32* %arg35) {
; CHECK: 946 Total Alias Queries Performed
; CHECK: 43 no alias responses (4.5%)
; CHECK: 45 Total Alias Queries Performed
; CHECK: 9 no alias responses (20.0%)
%a = alloca i32, align 4
%b = select i1 %cond, i32* %arg35, i32* %arg34
%c = select i1 %cond, i32* %arg34, i32* %arg33
%d = select i1 %cond, i32* %arg33, i32* %arg32
%e = select i1 %cond, i32* %arg32, i32* %arg31
%f = select i1 %cond, i32* %arg31, i32* %arg30
%g = select i1 %cond, i32* %arg30, i32* %arg29
%h = select i1 %cond, i32* %arg29, i32* %arg28
%i = select i1 %cond, i32* %arg28, i32* %arg27
load i32, i32* %a
load i32, i32* %arg27
load i32, i32* %arg28
load i32, i32* %arg29
load i32, i32* %arg30
load i32, i32* %arg31
load i32, i32* %arg32
load i32, i32* %arg33
load i32, i32* %arg34
load i32, i32* %arg35
ret void
}

View File

@ -1,10 +1,10 @@
; RUN: opt < %s -aa-pipeline=cfl-steens-aa -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
; CHECK-LABEL: Function: test1
; CHECK: MayAlias: i32* %X, i32* %tmp
; CHECK: MayAlias: i32* %tmp, i8** %ap
; CHECK: NoAlias: i8** %ap, i8** %aq
; CHECK: MayAlias: i32* %tmp, i8** %aq
; CHECK-DAG: MayAlias: i32* %X, i32* %tmp
; CHECK-DAG: MayAlias: i8** %ap, i32* %tmp
; CHECK-DAG: NoAlias: i8** %ap, i8** %aq
; CHECK-DAG: MayAlias: i8** %aq, i32* %tmp
define i32* @test1(i32* %X, ...) {
; Initialize variable argument processing
@ -23,6 +23,11 @@ define i32* @test1(i32* %X, ...) {
; Stop processing of arguments.
call void @llvm.va_end(i8* %ap2)
load i32, i32* %X
load i8*, i8** %ap
load i8*, i8** %aq
load i32, i32* %tmp
ret i32* %tmp
}

View File

@ -4,9 +4,10 @@
; CHECK-LABEL: test1
; CHECK-DAG: NoAlias: i32* %gp, i32* %p
; CHECK-DAG: NoAlias: i32 addrspace(3)* @g0, i32* %p
; CHECK-DAG: MustAlias: i32 addrspace(3)* @g0, i32* %gp
; CHECK-DAG: NoAlias: i32* %p, i32 addrspace(3)* @g0
; CHECK-DAG: MustAlias: i32* %gp, i32 addrspace(3)* @g0
define i32 @test1(i32* %p) {
load i32, i32 addrspace(3)* @g0
%gp = addrspacecast i32 addrspace(3)* @g0 to i32*
store i32 0, i32* %gp
store i32 1, i32* %p

View File

@ -9,7 +9,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
; p[i] and p[i+1] don't alias.
; CHECK: Function: loop: 3 pointers, 0 call sites
; CHECK-LABEL: Function: loop
; CHECK: NoAlias: double* %pi, double* %pi.next
define void @loop(double* nocapture %p, i64 %n) nounwind {
@ -35,7 +35,7 @@ return:
; Slightly more involved: p[j][i], p[j][i+1], and p[j+1][i] don't alias.
; CHECK: Function: nestedloop: 4 pointers, 0 call sites
; CHECK-LABEL: Function: nestedloop
; CHECK: NoAlias: double* %pi.j, double* %pi.next.j
; CHECK: NoAlias: double* %pi.j, double* %pi.j.next
; CHECK: NoAlias: double* %pi.j.next, double* %pi.next.j
@ -93,7 +93,7 @@ return:
; however the analysis currently doesn't do that.
; TODO: Make the analysis smarter and turn that MayAlias into a NoAlias.
; CHECK: Function: nestedloop_more: 4 pointers, 0 call sites
; CHECK-LABEL: Function: nestedloop_more
; CHECK: NoAlias: double* %pi.j, double* %pi.next.j
; CHECK: MayAlias: double* %pi.j, double* %pi.j.next
@ -149,14 +149,14 @@ return:
%struct.A = type { %struct.B, i32, i32 }
%struct.B = type { double }
; CHECK: Function: foo: 7 pointers, 0 call sites
; CHECK: NoAlias: %struct.B* %B, i32* %Z
; CHECK: NoAlias: %struct.B* %B, %struct.B* %C
; CHECK: MustAlias: %struct.B* %C, i32* %Z
; CHECK: NoAlias: %struct.B* %B, i32* %X
; CHECK: MustAlias: i32* %X, i32* %Z
; CHECK: MustAlias: %struct.B* %C, i32* %Y
; CHECK: MustAlias: i32* %X, i32* %Y
; CHECK-LABEL: Function: foo
; CHECK-DAG: NoAlias: %struct.B* %B, i32* %Z
; CHECK-DAG: NoAlias: %struct.B* %B, %struct.B* %C
; CHECK-DAG: MustAlias: %struct.B* %C, i32* %Z
; CHECK-DAG: NoAlias: %struct.B* %B, i32* %X
; CHECK-DAG: MustAlias: i32* %X, i32* %Z
; CHECK-DAG: MustAlias: %struct.B* %C, i32* %Y
; CHECK-DAG: MustAlias: i32* %X, i32* %Y
define void @foo() {
entry:
@ -167,17 +167,22 @@ entry:
%C = getelementptr %struct.B, %struct.B* %B, i32 1
%X = bitcast %struct.B* %C to i32*
%Y = getelementptr %struct.A, %struct.A* %A, i32 0, i32 1
load %struct.B, %struct.B* %B
load %struct.B, %struct.B* %C
load i32, i32* %X
load i32, i32* %Y
load i32, i32* %Z
ret void
}
; CHECK: Function: bar: 7 pointers, 0 call sites
; CHECK: NoAlias: %struct.B* %N, i32* %P
; CHECK: NoAlias: %struct.B* %N, %struct.B* %R
; CHECK: MustAlias: %struct.B* %R, i32* %P
; CHECK: NoAlias: %struct.B* %N, i32* %W
; CHECK: MustAlias: i32* %P, i32* %W
; CHECK: MustAlias: %struct.B* %R, i32* %V
; CHECK: MustAlias: i32* %V, i32* %W
; CHECK-LABEL: Function: bar
; CHECK-DAG: NoAlias: %struct.B* %N, i32* %P
; CHECK-DAG: NoAlias: %struct.B* %N, %struct.B* %R
; CHECK-DAG: MustAlias: i32* %P, %struct.B* %R
; CHECK-DAG: NoAlias: %struct.B* %N, i32* %W
; CHECK-DAG: MustAlias: i32* %P, i32* %W
; CHECK-DAG: MustAlias: %struct.B* %R, i32* %V
; CHECK-DAG: MustAlias: i32* %V, i32* %W
define void @bar() {
%M = alloca %struct.A
@ -187,6 +192,11 @@ define void @bar() {
%R = getelementptr %struct.B, %struct.B* %N, i32 1
%W = bitcast %struct.B* %R to i32*
%V = getelementptr %struct.A, %struct.A* %M, i32 0, i32 1
load %struct.B, %struct.B* %N
load %struct.B, %struct.B* %R
load i32, i32* %P
load i32, i32* %V
load i32, i32* %W
ret void
}
@ -210,7 +220,7 @@ for.end: ; preds = %for.body, %entry
ret void
}
; CHECK: Function: test_no_dom: 3 pointers, 0 call sites
; CHECK-LABEL: Function: test_no_dom: 3 pointers, 0 call sites
; CHECK: MayAlias: double* %addr1, double* %data
; CHECK: NoAlias: double* %addr2, double* %data
; CHECK: MayAlias: double* %addr1, double* %addr2
@ -221,6 +231,7 @@ for.end: ; preds = %for.body, %entry
; dominance order.
define void @test_no_dom(double* %data) {
entry:
load double, double* %data
br label %for.body
for.body:
@ -253,7 +264,7 @@ for.end:
declare double* @get_addr(i32 %i)
; CHECK: Function: test_no_dom2: 3 pointers, 2 call sites
; CHECK-LABEL: Function: test_no_dom2: 3 pointers, 2 call sites
; CHECK: MayAlias: double* %addr1, double* %data
; CHECK: MayAlias: double* %addr2, double* %data
; CHECK: MayAlias: double* %addr1, double* %addr2
@ -263,6 +274,7 @@ declare double* @get_addr(i32 %i)
; to test_no_dom, but involves SCEVUnknown as opposed to SCEVAddRecExpr.
define void @test_no_dom2(double* %data) {
entry:
load double, double* %data
br label %for.body
for.body:
@ -294,7 +306,7 @@ for.end:
}
; CHECK: Function: test_dom: 3 pointers, 0 call sites
; CHECK-LABEL: Function: test_dom: 3 pointers, 0 call sites
; CHECK: MayAlias: double* %addr1, double* %data
; CHECK: NoAlias: double* %addr2, double* %data
; CHECK: NoAlias: double* %addr1, double* %addr2
@ -304,6 +316,7 @@ for.end:
; addrecs and cancel out the %data base pointer.
define void @test_dom(double* %data) {
entry:
load double, double* %data
br label %for.body
for.body:
@ -333,7 +346,3 @@ for.latch:
for.end:
ret void
}
; CHECK: 17 no alias responses
; CHECK: 32 may alias responses
; CHECK: 18 must alias responses

View File

@ -1,185 +1,249 @@
; RUN: opt -mtriple=amdgcn-- -data-layout=A5 -passes=aa-eval -aa-pipeline=amdgpu-aa -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
; RUN: opt -mtriple=r600-- -data-layout=A5 -passes=aa-eval -aa-pipeline=amdgpu-aa -print-all-alias-modref-info -disable-output < %s 2>&1 | FileCheck %s
; CHECK: NoAlias: i8 addrspace(1)* %p1, i8 addrspace(5)* %p
; CHECK-LABEL: Function: test
; CHECK: NoAlias: i8 addrspace(5)* %p, i8 addrspace(1)* %p1
define void @test(i8 addrspace(5)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(5)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p1, i8 addrspace(4)* %p
; CHECK-LABEL: Function: test_constant_vs_global
; CHECK: MayAlias: i8 addrspace(4)* %p, i8 addrspace(1)* %p1
define void @test_constant_vs_global(i8 addrspace(4)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(4)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p, i8 addrspace(4)* %p1
define void @test_global_vs_constant(i8 addrspace(1)* %p, i8 addrspace(4)* %p1) {
load i8, i8 addrspace(1)* %p
load i8, i8 addrspace(4)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p1, i8 addrspace(6)* %p
; CHECK: MayAlias: i8 addrspace(6)* %p, i8 addrspace(1)* %p1
define void @test_constant_32bit_vs_global(i8 addrspace(6)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(6)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(4)* %p1, i8 addrspace(6)* %p
; CHECK: MayAlias: i8 addrspace(6)* %p, i8 addrspace(4)* %p1
define void @test_constant_32bit_vs_constant(i8 addrspace(6)* %p, i8 addrspace(4)* %p1) {
load i8, i8 addrspace(6)* %p
load i8, i8 addrspace(4)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(999)* %p0, i8* %p
; CHECK: MayAlias: i8* %p, i8 addrspace(999)* %p0
define void @test_0_999(i8 addrspace(0)* %p, i8 addrspace(999)* %p0) {
load i8, i8 addrspace(0)* %p
load i8, i8 addrspace(999)* %p0
ret void
}
; CHECK: MayAlias: i8 addrspace(999)* %p, i8* %p1
define void @test_999_0(i8 addrspace(999)* %p, i8 addrspace(0)* %p1) {
load i8, i8 addrspace(999)* %p
load i8, i8 addrspace(0)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p, i8 addrspace(999)* %p1
define void @test_1_999(i8 addrspace(1)* %p, i8 addrspace(999)* %p1) {
load i8, i8 addrspace(1)* %p
load i8, i8 addrspace(999)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p1, i8 addrspace(999)* %p
; CHECK: MayAlias: i8 addrspace(999)* %p, i8 addrspace(1)* %p1
define void @test_999_1(i8 addrspace(999)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(999)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p, i8* %p1
define void @test_region_vs_flat(i8 addrspace(2)* %p, i8 addrspace(0)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(0)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(1)* %p1, i8 addrspace(2)* %p
; CHECK: NoAlias: i8 addrspace(2)* %p, i8 addrspace(1)* %p1
define void @test_region_vs_global(i8 addrspace(2)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(2)* %p, i8 addrspace(2)* %p1
define void @test_region(i8 addrspace(2)* %p, i8 addrspace(2)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(2)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p, i8 addrspace(3)* %p1
define void @test_region_vs_group(i8 addrspace(2)* %p, i8 addrspace(3)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(3)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p, i8 addrspace(4)* %p1
define void @test_region_vs_constant(i8 addrspace(2)* %p, i8 addrspace(4)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(4)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p, i8 addrspace(5)* %p1
define void @test_region_vs_private(i8 addrspace(2)* %p, i8 addrspace(5)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(5)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p, i8 addrspace(6)* %p1
define void @test_region_vs_const32(i8 addrspace(2)* %p, i8 addrspace(6)* %p1) {
load i8, i8 addrspace(2)* %p
load i8, i8 addrspace(6)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(7)* %p, i8* %p1
define void @test_7_0(i8 addrspace(7)* %p, i8 addrspace(0)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(0)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(1)* %p1, i8 addrspace(7)* %p
; CHECK: MayAlias: i8 addrspace(7)* %p, i8 addrspace(1)* %p1
define void @test_7_1(i8 addrspace(7)* %p, i8 addrspace(1)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(1)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(2)* %p1, i8 addrspace(7)* %p
; CHECK: NoAlias: i8 addrspace(7)* %p, i8 addrspace(2)* %p1
define void @test_7_2(i8 addrspace(7)* %p, i8 addrspace(2)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(2)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(3)* %p1, i8 addrspace(7)* %p
; CHECK: NoAlias: i8 addrspace(7)* %p, i8 addrspace(3)* %p1
define void @test_7_3(i8 addrspace(7)* %p, i8 addrspace(3)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(3)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(4)* %p1, i8 addrspace(7)* %p
; CHECK: MayAlias: i8 addrspace(7)* %p, i8 addrspace(4)* %p1
define void @test_7_4(i8 addrspace(7)* %p, i8 addrspace(4)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(4)* %p1
ret void
}
; CHECK: NoAlias: i8 addrspace(5)* %p1, i8 addrspace(7)* %p
; CHECK: NoAlias: i8 addrspace(7)* %p, i8 addrspace(5)* %p1
define void @test_7_5(i8 addrspace(7)* %p, i8 addrspace(5)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(5)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(6)* %p1, i8 addrspace(7)* %p
; CHECK: MayAlias: i8 addrspace(7)* %p, i8 addrspace(6)* %p1
define void @test_7_6(i8 addrspace(7)* %p, i8 addrspace(6)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(6)* %p1
ret void
}
; CHECK: MayAlias: i8 addrspace(7)* %p, i8 addrspace(7)* %p1
define void @test_7_7(i8 addrspace(7)* %p, i8 addrspace(7)* %p1) {
load i8, i8 addrspace(7)* %p
load i8, i8 addrspace(7)* %p1
ret void
}
@cst = internal addrspace(4) global i8* undef, align 4
; CHECK-LABEL: Function: test_8_0
; CHECK: NoAlias: i8 addrspace(3)* %p, i8* %p1
; CHECK: NoAlias: i8 addrspace(3)* %p, i8* addrspace(4)* @cst
; CHECK: MayAlias: i8* %p1, i8* addrspace(4)* @cst
; CHECK-DAG: NoAlias: i8 addrspace(3)* %p, i8* %p1
; CHECK-DAG: NoAlias: i8 addrspace(3)* %p, i8* addrspace(4)* @cst
; CHECK-DAG: MayAlias: i8* %p1, i8* addrspace(4)* @cst
define void @test_8_0(i8 addrspace(3)* %p) {
%p1 = load i8*, i8* addrspace(4)* @cst
load i8, i8 addrspace(3)* %p
load i8, i8* %p1
ret void
}
; CHECK-LABEL: Function: test_8_1
; CHECK: NoAlias: i8 addrspace(5)* %p, i8* %p1
; CHECK: NoAlias: i8 addrspace(5)* %p, i8* addrspace(4)* @cst
; CHECK: MayAlias: i8* %p1, i8* addrspace(4)* @cst
; CHECK-DAG: NoAlias: i8 addrspace(5)* %p, i8* %p1
; CHECK-DAG: NoAlias: i8 addrspace(5)* %p, i8* addrspace(4)* @cst
; CHECK-DAG: MayAlias: i8* %p1, i8* addrspace(4)* @cst
define void @test_8_1(i8 addrspace(5)* %p) {
%p1 = load i8*, i8* addrspace(4)* @cst
load i8, i8 addrspace(5)* %p
load i8, i8* %p1
ret void
}
; CHECK-LABEL: Function: test_8_2
; CHECK: NoAlias: i8 addrspace(5)* %p1, i8* %p
; CHECK: NoAlias: i8* %p, i8 addrspace(5)* %p1
define amdgpu_kernel void @test_8_2(i8* %p) {
%p1 = alloca i8, align 1, addrspace(5)
load i8, i8* %p
load i8, i8 addrspace(5)* %p1
ret void
}
; CHECK-LABEL: Function: test_8_3
; CHECK: MayAlias: i8 addrspace(5)* %p1, i8* %p
; CHECK: MayAlias: i8* %p, i8 addrspace(5)* %p1
; TODO: So far, %p1 may still alias to %p. As it's not captured at all, it
; should be NoAlias.
define void @test_8_3(i8* %p) {
%p1 = alloca i8, align 1, addrspace(5)
load i8, i8* %p
load i8, i8 addrspace(5)* %p1
ret void
}
@shm = internal addrspace(3) global i8 undef, align 4
; CHECK-LABEL: Function: test_8_4
; CHECK: NoAlias: i8 addrspace(3)* %p1, i8* %p
; CHECK: NoAlias: i8 addrspace(3)* @shm, i8* %p
; CHECK: NoAlias: i8* %p, i8 addrspace(3)* %p1
; CHECK: NoAlias: i8* %p, i8 addrspace(3)* @shm
; CHECK: MayAlias: i8 addrspace(3)* %p1, i8 addrspace(3)* @shm
define amdgpu_kernel void @test_8_4(i8* %p) {
%p1 = getelementptr i8, i8 addrspace(3)* @shm, i32 0
load i8, i8* %p
load i8, i8 addrspace(3)* %p1
load i8, i8 addrspace(3)* @shm
ret void
}
; CHECK-LABEL: Function: test_8_5
; CHECK: MayAlias: i8 addrspace(3)* %p1, i8* %p
; CHECK: MayAlias: i8 addrspace(3)* @shm, i8* %p
; CHECK: MayAlias: i8* %p, i8 addrspace(3)* %p1
; CHECK: MayAlias: i8* %p, i8 addrspace(3)* @shm
; CHECK: MayAlias: i8 addrspace(3)* %p1, i8 addrspace(3)* @shm
; TODO: So far, %p1 may still alias to %p. As it's not captured at all, it
; should be NoAlias.
define void @test_8_5(i8* %p) {
%p1 = getelementptr i8, i8 addrspace(3)* @shm, i32 0
load i8, i8* %p
load i8, i8 addrspace(3)* %p1
load i8, i8 addrspace(3)* @shm
ret void
}

View File

@ -2,5 +2,7 @@
; CHECK: MayAlias: i8 addrspace(5)* %p, i8 addrspace(999)* %p1
define amdgpu_kernel void @test(i8 addrspace(5)* %p, i8 addrspace(999)* %p1) {
load volatile i8, i8 addrspace(5)* %p
load volatile i8, i8 addrspace(999)* %p1
ret void
}