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';
}
}
++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 ||
<< " 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());
// 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());
%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
}
%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
}
%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
}
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
}
}
; 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* %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_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: 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: 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* %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 <-> %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: 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: 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* %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 <-> %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: 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: 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** %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* %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_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: 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: 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* %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 @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: 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: 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%)
; 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
%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
; 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
; 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
; 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
%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
}
%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
}
%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
}
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:
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:
; 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
; 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
; 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
; 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
; 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
; 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
%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
}
%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
}
%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
}
define void @test(i8* noalias %p) {
entry:
+ load i8, i8* %p
call void @readonly_attr(i8* %p)
call void @readonly_func(i8* %p)
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
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)
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
}
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
; 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"() ]
; 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"() ]
; 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 ]
declare void @unknown_but_readonly() readonly
define void @test1(i8* %p) {
+ load i8, i8* %p
call void(...) @llvm.experimental.deoptimize.void() [ "deopt"() ]
ret void
%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"
%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"
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
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
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
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
%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
}
; 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
; 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
; 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
; 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)
; 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
; 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
; %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
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
; %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
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
; (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
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
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
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
; 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
; 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
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
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
; %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
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
; %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
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
; %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
; (((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
; 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
; 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
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
; 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
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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
; 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
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
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
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
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
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
; 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
; 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
; 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
; 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
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
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
}
%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
}
%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
}
%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
}
; 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
}
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
%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
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
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
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
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
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
}
%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
%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
%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:
}
; 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
%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:
%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
%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
}
; 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:
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:
}
; 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:
%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
}
-; 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
}
-; 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
}
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:
%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
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
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
}
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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
; 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:
%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
}
; 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
%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
}
; 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
%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
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
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
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:
; 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:
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:
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:
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:
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:
; 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
%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
}
%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
}
%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
}
%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
}
%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
}
%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
%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
}
%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
}
%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
%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
}
%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
}
; 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
%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
}
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
}
; 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
%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
}
; 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
%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
}
%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
}
%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
}
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
}
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
}
%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
}
%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
}
%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
}
%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
}
%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
}
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
}
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
}
; 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
%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
; 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
%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
}
%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
}
%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
}
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
%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
}
; 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
}
%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:
%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
}
%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
}
%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
%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
%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
}
%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
}
%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
}
%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
}
%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
}
%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
}
; 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) {
%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
-}
\ No newline at end of file
+}
; 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
%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
-}
\ No newline at end of file
+}
; 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: 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* %q
+; CHECK-DAG: NoAlias: i64* %esc, i64*** %p
+; CHECK-DAG: NoAlias: i64* %esc, i64* %q
+
+; 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
%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: 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: 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*** %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-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-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
%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
}
%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
}
%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
}
%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
}
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
; 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
}
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
-}
\ No newline at end of file
+}
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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
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)
%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)
%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
-}
\ No newline at end of file
+}
; 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
%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
-}
\ No newline at end of file
+}
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
}
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
-}
\ No newline at end of file
+}
; 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
%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)
%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
-}
\ No newline at end of file
+}
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
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
; 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
-}
\ No newline at end of file
+}
; (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
}
; 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
}
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
}
%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
}
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
%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
%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
}
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
}
i32 0),
i64 0,
i32 0
+ load i32, i32* %arg0
+ load i32, i32* %A
ret void
}
@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
%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
}
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
-}
\ No newline at end of file
+}
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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
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
-}
\ No newline at end of file
+}
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
%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)
%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
-}
\ No newline at end of file
+}
; 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:
%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
-}
\ No newline at end of file
+}
%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
}
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
-}
\ No newline at end of file
+}
; 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
%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)
%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
}
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
%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
-}
\ No newline at end of file
+}
%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
-}
\ No newline at end of file
+}
; 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
}
; 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
}
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
}
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
}
%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
}
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) {
%2 = load double, double* %arrayidx25
%3 = fneg double %1
%mul26 = fmul double %3, %2
+ load double, double* %A
+ load double, double* %Index
ret void
}
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
}
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
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
}
; 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
; 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
}
; 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
; 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 {
; 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
; 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
%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:
%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
%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
}
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
; dominance order.
define void @test_no_dom(double* %data) {
entry:
+ load double, double* %data
br label %for.body
for.body:
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
; 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:
}
-; 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
; 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:
for.end:
ret void
}
-
-; CHECK: 17 no alias responses
-; CHECK: 32 may alias responses
-; CHECK: 18 must alias responses
; 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
}
; 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
}