From 57d57b1afd87d714d622b4287f891d17a474ecb6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 15 Mar 2022 10:18:19 +0100 Subject: [PATCH] [AAEval] Make compatible with opaque pointers With opaque pointers, we cannot use the pointer element type to determine the LocationSize for the AA query. Instead, -aa-eval tests are now required to have an explicit load or store for any pointer they want to compute alias results for, and the load/store types are used to determine the location size. This may affect ordering of results, and sorting within one result, as the type is not considered part of the sorted string anymore. To somewhat minimize the churn, printing still uses faux typed pointer notation. --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp | 102 +++-- llvm/test/Analysis/BasicAA/128-bit-ptr.ll | 9 + .../BasicAA/2006-03-03-BadArraySubscript.ll | 1 + .../Analysis/BasicAA/args-rets-allocas-loads.ll | 448 ++++++++++++--------- .../test/Analysis/BasicAA/assume-index-positive.ll | 30 +- llvm/test/Analysis/BasicAA/assume.ll | 4 + .../Analysis/BasicAA/atomic-memory-intrinsics.ll | 10 + llvm/test/Analysis/BasicAA/bug.23540.ll | 2 + llvm/test/Analysis/BasicAA/bug.23626.ll | 6 + llvm/test/Analysis/BasicAA/call-attrs.ll | 1 + llvm/test/Analysis/BasicAA/cs-cs.ll | 42 ++ llvm/test/Analysis/BasicAA/dag.ll | 3 + llvm/test/Analysis/BasicAA/deoptimize.ll | 5 + llvm/test/Analysis/BasicAA/dereferenceable.ll | 8 +- .../Analysis/BasicAA/gep-decomposition-limit.ll | 9 + .../BasicAA/gep-implicit-trunc-32-bit-pointers.ll | 6 + llvm/test/Analysis/BasicAA/gep-modulo.ll | 96 +++-- llvm/test/Analysis/BasicAA/guards.ll | 2 + llvm/test/Analysis/BasicAA/index-size.ll | 1 + llvm/test/Analysis/BasicAA/invariant_group.ll | 3 + llvm/test/Analysis/BasicAA/libfuncs-darwin.ll | 12 + llvm/test/Analysis/BasicAA/libfuncs.ll | 31 ++ llvm/test/Analysis/BasicAA/negoffset.ll | 30 ++ llvm/test/Analysis/BasicAA/noalias-geps.ll | 7 +- llvm/test/Analysis/BasicAA/noalias-scope-decl.ll | 2 + llvm/test/Analysis/BasicAA/phi-aa.ll | 10 +- llvm/test/Analysis/BasicAA/phi-spec-order.ll | 4 + llvm/test/Analysis/BasicAA/phi-speculation.ll | 56 ++- llvm/test/Analysis/BasicAA/pr31761.ll | 2 + llvm/test/Analysis/BasicAA/pr35821.ll | 8 +- llvm/test/Analysis/BasicAA/pr35843.ll | 8 +- llvm/test/Analysis/BasicAA/pr52735.ll | 3 +- llvm/test/Analysis/BasicAA/ptrmask.ll | 8 +- llvm/test/Analysis/BasicAA/q.bad.ll | 32 ++ llvm/test/Analysis/BasicAA/range.ll | 120 +++--- llvm/test/Analysis/BasicAA/recphi.ll | 152 ++++--- llvm/test/Analysis/BasicAA/returned.ll | 14 +- llvm/test/Analysis/BasicAA/sequential-gep.ll | 49 ++- llvm/test/Analysis/BasicAA/struct-geps.ll | 61 ++- llvm/test/Analysis/BasicAA/vscale.ll | 111 +++-- llvm/test/Analysis/BasicAA/zext.ll | 54 ++- .../Analysis/CFLAliasAnalysis/Andersen/assign.ll | 15 +- .../Analysis/CFLAliasAnalysis/Andersen/assign2.ll | 11 +- .../CFLAliasAnalysis/Andersen/attrs-below.ll | 68 ++-- .../Analysis/CFLAliasAnalysis/Andersen/attrs.ll | 49 ++- .../CFLAliasAnalysis/Andersen/basic-interproc.ll | 2 + .../Analysis/CFLAliasAnalysis/Andersen/cycle.ll | 13 +- .../Andersen/interproc-arg-deref-escape.ll | 23 +- .../Andersen/interproc-arg-escape.ll | 24 +- .../CFLAliasAnalysis/Andersen/interproc-ret-arg.ll | 5 +- .../Andersen/interproc-ret-deref-arg-multilevel.ll | 7 +- .../Andersen/interproc-ret-deref-arg.ll | 6 +- .../Andersen/interproc-ret-escape.ll | 6 +- .../Andersen/interproc-ret-ref-arg-multilevel.ll | 34 +- .../Andersen/interproc-ret-ref-arg.ll | 9 +- .../Andersen/interproc-ret-unknown.ll | 22 +- .../Andersen/interproc-store-arg-multilevel.ll | 8 +- .../Andersen/interproc-store-arg-unknown.ll | 8 +- .../Andersen/interproc-store-arg.ll | 6 +- .../Analysis/CFLAliasAnalysis/Andersen/memalias.ll | 12 +- .../Steensgaard/arguments-globals.ll | 18 +- .../CFLAliasAnalysis/Steensgaard/arguments.ll | 4 + .../Steensgaard/asm-global-bugfix.ll | 2 + .../CFLAliasAnalysis/Steensgaard/attr-escape.ll | 57 ++- .../Steensgaard/basic-interproc.ll | 2 + .../CFLAliasAnalysis/Steensgaard/branch-alias.ll | 1 + .../CFLAliasAnalysis/Steensgaard/const-expr-gep.ll | 8 + .../CFLAliasAnalysis/Steensgaard/const-exprs.ll | 21 +- .../Steensgaard/gep-index-no-alias.ll | 4 + .../Steensgaard/interproc-arg-deref-escape.ll | 23 +- .../Steensgaard/interproc-arg-escape.ll | 24 +- .../Steensgaard/interproc-ret-arg.ll | 5 +- .../interproc-ret-deref-arg-multilevel.ll | 7 +- .../Steensgaard/interproc-ret-deref-arg.ll | 6 +- .../Steensgaard/interproc-ret-escape.ll | 24 +- .../interproc-ret-ref-arg-multilevel.ll | 30 +- .../Steensgaard/interproc-ret-ref-arg.ll | 9 +- .../Steensgaard/interproc-ret-unknown.ll | 12 +- .../Steensgaard/interproc-store-arg-multilevel.ll | 6 +- .../Steensgaard/interproc-store-arg-unknown.ll | 8 +- .../Steensgaard/interproc-store-arg.ll | 6 +- .../Steensgaard/malloc-and-free.ll | 6 + .../Steensgaard/multilevel-combine.ll | 4 + .../CFLAliasAnalysis/Steensgaard/multilevel.ll | 4 + .../Steensgaard/must-and-partial.ll | 4 +- .../Steensgaard/opaque-call-alias.ll | 3 + .../CFLAliasAnalysis/Steensgaard/pr27213.ll | 1 + .../Steensgaard/stratified-attrs-indexing.ll | 22 +- .../Analysis/CFLAliasAnalysis/Steensgaard/va.ll | 13 +- llvm/test/Analysis/GlobalsModRef/addrspacecast.ll | 5 +- llvm/test/Analysis/ScalarEvolution/scev-aa.ll | 61 +-- llvm/test/CodeGen/AMDGPU/amdgpu-alias-analysis.ll | 114 ++++-- .../CodeGen/AMDGPU/r600.amdgpu-alias-analysis.ll | 2 + 93 files changed, 1647 insertions(+), 759 deletions(-) diff --git a/llvm/lib/Analysis/AliasAnalysisEvaluator.cpp b/llvm/lib/Analysis/AliasAnalysisEvaluator.cpp index 215517e..7ba6320 100644 --- a/llvm/lib/Analysis/AliasAnalysisEvaluator.cpp +++ b/llvm/lib/Analysis/AliasAnalysisEvaluator.cpp @@ -39,30 +39,48 @@ static cl::opt PrintMustModRef("print-mustmodref", cl::ReallyHidden); static cl::opt 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 Loc1, + std::pair 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 Loc, Module *M) { if (PrintAll || P) { errs() << " " << Msg << ": Ptr: "; - Ptr->printAsOperand(errs(), true, M); + Loc.second->print(errs(), false, /* NoDetails */ true); + errs() << "* "; + Loc.first->printAsOperand(errs(), false, M); errs() << "\t<->" << *I << '\n'; } } @@ -97,38 +115,21 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) { ++FunctionCount; - SetVector Pointers; + SetVector> Pointers; SmallSetVector Calls; SetVector Loads; SetVector 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(&Inst)) - Loads.insert(&Inst); - if (EvalAAMD && isa(&Inst)) - Stores.insert(&Inst); - if (auto *Call = dyn_cast(&Inst)) { - Value *Callee = Call->getCalledOperand(); - // Skip actual functions for direct function calls. - if (!isa(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(&Inst)) { + Pointers.insert({LI->getPointerOperand(), LI->getType()}); + Loads.insert(LI); + } else if (auto *SI = dyn_cast(&Inst)) { + Pointers.insert({SI->getPointerOperand(), + SI->getValueOperand()->getType()}); + Stores.insert(SI); + } else if (auto *CB = dyn_cast(&Inst)) + Calls.insert(CB); } if (PrintAll || PrintNoAlias || PrintMayAlias || PrintPartialAlias || @@ -137,20 +138,12 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) { << " pointers, " << Calls.size() << " call sites\n"; // iterate over the worklist, and run the full (n^2)/2 disambiguations - for (SetVector::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::iterator I2 = Pointers.begin(); I2 != I1; ++I2) { - auto I2Size = LocationSize::afterPointer(); - Type *I2ElTy = (*I2)->getType()->getPointerElementType(); - if (I2ElTy->isSized()) - I2Size = LocationSize::precise(DL.getTypeStoreSize(I2ElTy)); - - AliasResult AR = AA.alias(*I1, I1Size, *I2, I2Size); + for (auto I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { + LocationSize Size1 = LocationSize::precise(DL.getTypeStoreSize(I1->second)); + for (auto I2 = Pointers.begin(); I2 != I1; ++I2) { + LocationSize Size2 = + LocationSize::precise(DL.getTypeStoreSize(I2->second)); + AliasResult AR = AA.alias(I1->first, Size1, I2->first, Size2); switch (AR) { case AliasResult::NoAlias: PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent()); @@ -229,13 +222,10 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) { // Mod/ref alias analysis: compare all pairs of calls and values for (CallBase *Call : Calls) { - for (auto Pointer : Pointers) { - auto Size = LocationSize::afterPointer(); - Type *ElTy = Pointer->getType()->getPointerElementType(); - if (ElTy->isSized()) - Size = LocationSize::precise(DL.getTypeStoreSize(ElTy)); - - switch (AA.getModRefInfo(Call, Pointer, Size)) { + for (const auto &Pointer : Pointers) { + LocationSize Size = + LocationSize::precise(DL.getTypeStoreSize(Pointer.second)); + switch (AA.getModRefInfo(Call, Pointer.first, Size)) { case ModRefInfo::NoModRef: PrintModRefResults("NoModRef", PrintNoModRef, Call, Pointer, F.getParent()); diff --git a/llvm/test/Analysis/BasicAA/128-bit-ptr.ll b/llvm/test/Analysis/BasicAA/128-bit-ptr.ll index 23e3c25..6525410 100644 --- a/llvm/test/Analysis/BasicAA/128-bit-ptr.ll +++ b/llvm/test/Analysis/BasicAA/128-bit-ptr.ll @@ -18,6 +18,11 @@ define void @test0(%T addrspace(100)* %P) { %C = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1 %D = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 0 %E = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 5 + load %T, %T addrspace(100)* %A + load i32, i32 addrspace(100)* %B + load [10 x i8], [10 x i8] addrspace(100)* %C + load i8, i8 addrspace(100)* %D + load i8, i8 addrspace(100)* %E ret void } @@ -37,6 +42,8 @@ define void @test1(double addrspace(100)* %P, i128 %i) { %i69 = add i128 %i, 590295810358705651712 %A = getelementptr double, double addrspace(100)* %P, i128 %i70 %B = getelementptr double, double addrspace(100)* %P, i128 %i69 + load double, double addrspace(100)* %A + load double, double addrspace(100)* %B ret void } @@ -56,5 +63,7 @@ define void @test2(double addrspace(100)* %P, i128 %i) { %j70 = add i128 %i69, 590295810358705651712 %A = getelementptr double, double addrspace(100)* %P, i128 %i70 %C = getelementptr double, double addrspace(100)* %P, i128 %j70 + load double, double addrspace(100)* %A + load double, double addrspace(100)* %C ret void } diff --git a/llvm/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll b/llvm/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll index 114d63c..af0f8c3 100644 --- a/llvm/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll +++ b/llvm/test/Analysis/BasicAA/2006-03-03-BadArraySubscript.ll @@ -26,6 +26,7 @@ no_exit: ; preds = %no_exit, %entry loopexit: ; preds = %no_exit, %entry %Y.0.1 = phi i32 [ 0, %entry ], [ %tmp.13, %no_exit ] ; [#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 ) ; [#uses=0] ret void } diff --git a/llvm/test/Analysis/BasicAA/args-rets-allocas-loads.ll b/llvm/test/Analysis/BasicAA/args-rets-allocas-loads.ll index 5bef2ed..725252d 100644 --- a/llvm/test/Analysis/BasicAA/args-rets-allocas-loads.ll +++ b/llvm/test/Analysis/BasicAA/args-rets-allocas-loads.ll @@ -48,254 +48,310 @@ define void @caller_a(double* %arg_a0, } ; CHECK: Function: caller_a: 16 pointers, 8 call sites -; CHECK-NEXT: MayAlias: double* %arg_a0, double* %arg_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a1 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_arg_a1 -; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double** %indirect_a0, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %escape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a1 -; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a1 -; CHECK-NEXT: MayAlias: double* %normal_ret_a1, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %normal_ret_a1, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a1 -; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double** %indirect_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double** %indirect_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a1 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a0 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noalias_ret_a1 -; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a0 -; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a1 -; CHECK-NEXT: MayAlias: double* %loaded_a0, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %loaded_a0, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a0 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a1 -; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a1 -; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a1 -; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a1 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a1 -; CHECK-NEXT: MayAlias: double* %loaded_a1, double** %indirect_a0 -; CHECK-NEXT: MayAlias: double* %loaded_a1, double** %indirect_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a1 -; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a1 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a1 -; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a0 -; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a1 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a0 -; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a1 -; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %loaded_a1 -; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a0 <-> %normal_ret_a0 = call double* @normal_returner() -; CHECK-NEXT: Both ModRef: Ptr: double* %arg_a1 <-> %normal_ret_a0 = call double* @normal_returner() -; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a0 <-> %normal_ret_a0 = call double* @normal_returner() -; CHECK-NEXT: NoModRef: Ptr: double* %noalias_arg_a1 <-> %normal_ret_a0 = call double* @normal_returner() +; CHECK-NEXT: MayAlias: double** %indirect_a0, double** %indirect_a1 +; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %loaded_a1 +; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %loaded_a1 +; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %loaded_a1 +; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a0 +; CHECK-NEXT: MayAlias: double* %arg_a0, double** %indirect_a1 +; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double* %arg_a0, double* %loaded_a1 +; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a0 +; CHECK-NEXT: MayAlias: double* %arg_a1, double** %indirect_a1 +; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double* %arg_a1, double* %loaded_a1 +; CHECK-NEXT: MayAlias: double* %arg_a0, double* %arg_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double** %indirect_a1 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %loaded_a1 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double** %indirect_a1 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a0 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %loaded_a1 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %escape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %escape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_arg_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %escape_alloca_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a0 +; CHECK-NEXT: MayAlias: double** %indirect_a0, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double** %indirect_a1, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %loaded_a0, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %loaded_a1, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %arg_a0, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %arg_a1, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a0, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %escape_alloca_a1, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double* %noescape_alloca_a0, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double* %noescape_alloca_a1, double* %normal_ret_a1 +; CHECK-NEXT: MayAlias: double* %normal_ret_a0, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a0, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double** %indirect_a1, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a0, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %loaded_a1, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %arg_a0, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %arg_a1, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a0, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_arg_a1, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a0, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %escape_alloca_a1, double* %noalias_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a0 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %noescape_alloca_a1 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a0 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a1, double* %normal_ret_a1 +; CHECK-NEXT: NoAlias: double* %noalias_ret_a0, double* %noalias_ret_a1 ; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a0 <-> %normal_ret_a0 = call double* @normal_returner() ; CHECK-NEXT: Both ModRef: Ptr: double** %indirect_a1 <-> %normal_ret_a0 = call double* @normal_returner() +; CHECK-NEXT: Both ModRef: Ptr: double* %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%) diff --git a/llvm/test/Analysis/BasicAA/assume-index-positive.ll b/llvm/test/Analysis/BasicAA/assume-index-positive.ll index b24bd74..6c25b8a 100644 --- a/llvm/test/Analysis/BasicAA/assume-index-positive.ll +++ b/llvm/test/Analysis/BasicAA/assume-index-positive.ll @@ -10,12 +10,13 @@ define void @test1(double* %ptr, i32 %skip) { ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast -; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 +; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast ; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) ; + load double, double* %ptr %gt = icmp sgt i32 %skip, -1 call void @llvm.assume(i1 %gt) %stride = add nsw nuw i32 %skip, 6 @@ -23,6 +24,7 @@ define void @test1(double* %ptr, i32 %skip) { %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 %col.ptr.2= getelementptr double, double* %ptr, i32 %stride %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* + load double, double* %col.ptr.2 %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 %res.1 = fadd <6 x double> %lv.1, %lv.1 %res.2 = fadd <6 x double> %lv.2, %lv.2 @@ -39,12 +41,14 @@ define void @test2(double* %ptr, i32 %skip) { ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2.cast, double* %ptr ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast -; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 +; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast ; + load double, double* %ptr %stride = add nsw nuw i32 %skip, 6 %col.ptr.1 = bitcast double* %ptr to <6 x double>* %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 - %col.ptr.2= getelementptr double, double* %ptr, i32 %stride + %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride + load double, double* %col.ptr.2 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 %res.1 = fadd <6 x double> %lv.1, %lv.1 @@ -65,18 +69,20 @@ define void @test3(double* %ptr, i32 %skip) { ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr ; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast -; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 +; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast ; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) ; + load double, double* %ptr %gt = icmp sgt i32 %skip, -3 call void @llvm.assume(i1 %gt) %stride = add nsw nuw i32 %skip, 6 %col.ptr.1 = bitcast double* %ptr to <6 x double>* %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 - %col.ptr.2= getelementptr double, double* %ptr, i32 %stride + %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride + load double, double* %col.ptr.2 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 %res.1 = fadd <6 x double> %lv.1, %lv.1 @@ -94,18 +100,20 @@ define void @test4(double* %ptr, i32 %skip) { ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr ; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast -; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 +; CHECK-NEXT: MustAlias: double* %col.ptr.2, <6 x double>* %col.ptr.2.cast ; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) ; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) ; + load double, double* %ptr %gt = icmp sge i32 %skip, 0 call void @llvm.assume(i1 %gt) %stride = add nsw nuw i32 %skip, 6 %col.ptr.1 = bitcast double* %ptr to <6 x double>* %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 - %col.ptr.2= getelementptr double, double* %ptr, i32 %stride + %col.ptr.2 = getelementptr double, double* %ptr, i32 %stride + load double, double* %col.ptr.2 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 %res.1 = fadd <6 x double> %lv.1, %lv.1 @@ -122,11 +130,13 @@ define void @symmetry([0 x i8]* %ptr, i32 %a, i32 %b, i32 %c) { %b.cmp = icmp slt i32 %b, 0 call void @llvm.assume(i1 %b.cmp) %gep1 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %b + load i8, i8* %gep1 call void @barrier() %c.cmp = icmp sgt i32 %c, -1 call void @llvm.assume(i1 %c.cmp) %c.off = add nuw nsw i32 %c, 1 %gep2 = getelementptr [0 x i8], [0 x i8]* %ptr, i32 %a, i32 %c.off + load i8, i8* %gep2 ret void } @@ -142,6 +152,9 @@ define void @shl_of_non_negative(i8* %ptr, i64 %a) { %ptr.a = getelementptr i8, i8* %ptr, i64 %a %shl = shl i64 %a, 1 %ptr.shl = getelementptr i8, i8* %ptr, i64 %shl + load i8, i8* %ptr.a + load i8, i8* %ptr.neg + load i8, i8* %ptr.shl ret void } @@ -157,6 +170,9 @@ define void @shl_nsw_of_non_negative(i8* %ptr, i64 %a) { %ptr.a = getelementptr i8, i8* %ptr, i64 %a %shl = shl nsw i64 %a, 1 %ptr.shl = getelementptr i8, i8* %ptr, i64 %shl + load i8, i8* %ptr.a + load i8, i8* %ptr.neg + load i8, i8* %ptr.shl ret void } diff --git a/llvm/test/Analysis/BasicAA/assume.ll b/llvm/test/Analysis/BasicAA/assume.ll index 5e28053..6579aae 100644 --- a/llvm/test/Analysis/BasicAA/assume.ll +++ b/llvm/test/Analysis/BasicAA/assume.ll @@ -7,6 +7,8 @@ declare void @llvm.assume(i1) #0 define void @test1(i8* %P, i8* %Q) nounwind ssp { tail call void @llvm.assume(i1 true) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + load i8, i8* %P + load i8, i8* %Q ret void ; CHECK-LABEL: Function: test1: @@ -24,6 +26,8 @@ define void @test1(i8* %P, i8* %Q) nounwind ssp { define void @test2(i8* %P, i8* %Q) nounwind ssp { tail call void @llvm.assume(i1 true) [ "nonnull"(i8* %P) ] tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) + load i8, i8* %P + load i8, i8* %Q ret void ; CHECK-LABEL: Function: test2: diff --git a/llvm/test/Analysis/BasicAA/atomic-memory-intrinsics.ll b/llvm/test/Analysis/BasicAA/atomic-memory-intrinsics.ll index 6716159..3b70f18 100644 --- a/llvm/test/Analysis/BasicAA/atomic-memory-intrinsics.ll +++ b/llvm/test/Analysis/BasicAA/atomic-memory-intrinsics.ll @@ -9,6 +9,7 @@ define void @test_memset_element_unordered_atomic_const_size(i8* noalias %a) { ; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %a, i8 0, i64 4, i32 1) ; entry: + load i8, i8* %a call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 1 %a, i8 0, i64 4, i32 1) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -24,6 +25,7 @@ define void @test_memset_element_unordered_atomic_variable_size(i8* noalias %a, ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> call void @llvm.memset.element.unordered.atomic.p0i8.i64(i8* align 1 %a, i8 0, i64 %n, i32 1) ; entry: + load i8, i8* %a call void @llvm.memset.element.unordered.atomic.p0i8.i32(i8* align 1 %a, i8 0, i64 %n, i32 1) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -44,6 +46,8 @@ define void @test_memcpy_element_unordered_atomic_const_size(i8* noalias %a, i8* ; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 4, i32 1) ; entry: + load i8, i8* %a + load i8, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -66,6 +70,8 @@ define void @test_memcpy_element_unordered_atomic_variable_size(i8* noalias %a, ; CHECK-NEXT: Just Mod: Ptr: i8* %b.gep.5 <-> call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 %n, i32 1) ; entry: + load i8, i8* %a + load i8, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -90,6 +96,8 @@ define void @test_memmove_element_unordered_atomic_const_size(i8* noalias %a, i8 ; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 4, i32 1) ; entry: + load i8, i8* %a + load i8, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -112,6 +120,8 @@ define void @test_memmove_element_unordered_atomic_variable_size(i8* noalias %a, ; CHECK-NEXT: Just Mod: Ptr: i8* %b.gep.5 <-> call void @llvm.memmove.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %b, i8* align 1 %a, i64 %n, i32 1) ; entry: + load i8, i8* %a + load i8, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 diff --git a/llvm/test/Analysis/BasicAA/bug.23540.ll b/llvm/test/Analysis/BasicAA/bug.23540.ll index 496b4ea..16d0118 100644 --- a/llvm/test/Analysis/BasicAA/bug.23540.ll +++ b/llvm/test/Analysis/BasicAA/bug.23540.ll @@ -12,6 +12,8 @@ define void @f() { %idxprom5 = zext i32 %add4 to i64 %arrayidx6 = getelementptr inbounds i32, i32* @c, i64 %idxprom5 %arrayidx = getelementptr inbounds i32, i32* @c, i64 %idxprom + load i32, i32* %arrayidx + load i32, i32* %arrayidx6 ret void } diff --git a/llvm/test/Analysis/BasicAA/bug.23626.ll b/llvm/test/Analysis/BasicAA/bug.23626.ll index 4875483..f3ffda5 100644 --- a/llvm/test/Analysis/BasicAA/bug.23626.ll +++ b/llvm/test/Analysis/BasicAA/bug.23626.ll @@ -18,6 +18,10 @@ define void @compute1(i32 %num.0.lcssa, i32* %out) { %add12 = or i32 %num.0.lcssa, 2 %idxprom13 = zext i32 %add12 to i64 %arrayidx14 = getelementptr inbounds i32, i32* %out, i64 %idxprom13 + load i32, i32* %out + load i32, i32* %arrayidx8 + load i32, i32* %arrayidx11 + load i32, i32* %arrayidx14 ret void } @@ -27,5 +31,7 @@ define void @compute2(i32 %num, i32* %out.addr) { %add9 = add i32 %num, 1 %idxprom10 = zext i32 %add9 to i64 %arrayidx11 = getelementptr inbounds i32, i32* %out.addr, i64 %idxprom10 + load i32, i32* %out.addr + load i32, i32* %arrayidx11 ret void } diff --git a/llvm/test/Analysis/BasicAA/call-attrs.ll b/llvm/test/Analysis/BasicAA/call-attrs.ll index ee35efa..6813c94 100644 --- a/llvm/test/Analysis/BasicAA/call-attrs.ll +++ b/llvm/test/Analysis/BasicAA/call-attrs.ll @@ -14,6 +14,7 @@ declare void @func() define void @test(i8* noalias %p) { entry: + load i8, i8* %p call void @readonly_attr(i8* %p) call void @readonly_func(i8* %p) diff --git a/llvm/test/Analysis/BasicAA/cs-cs.ll b/llvm/test/Analysis/BasicAA/cs-cs.ll index 5bc4c7a..95cf5b4 100644 --- a/llvm/test/Analysis/BasicAA/cs-cs.ll +++ b/llvm/test/Analysis/BasicAA/cs-cs.ll @@ -10,6 +10,8 @@ declare void @a_readonly_func(i8*) #1 declare void @a_writeonly_func(i8*) #2 define void @test2(i8* %P, i8* %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void @@ -26,6 +28,8 @@ define void @test2(i8* %P, i8* %Q) #3 { } define void @test2_atomic(i8* %P, i8* %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1) tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1) ret void @@ -42,6 +46,8 @@ define void @test2_atomic(i8* %P, i8* %Q) #3 { } define void @test2a(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void @@ -58,8 +64,11 @@ define void @test2a(i8* noalias %P, i8* noalias %Q) #3 { } define void @test2b(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) %R = getelementptr i8, i8* %P, i64 12 + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) ret void @@ -79,8 +88,11 @@ define void @test2b(i8* noalias %P, i8* noalias %Q) #3 { } define void @test2c(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) %R = getelementptr i8, i8* %P, i64 11 + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) ret void @@ -100,8 +112,11 @@ define void @test2c(i8* noalias %P, i8* noalias %Q) #3 { } define void @test2d(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) %R = getelementptr i8, i8* %P, i64 -12 + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) ret void @@ -121,8 +136,11 @@ define void @test2d(i8* noalias %P, i8* noalias %Q) #3 { } define void @test2e(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) %R = getelementptr i8, i8* %P, i64 -11 + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) ret void @@ -142,6 +160,8 @@ define void @test2e(i8* noalias %P, i8* noalias %Q) #3 { } define void @test3(i8* %P, i8* %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void @@ -158,6 +178,8 @@ define void @test3(i8* %P, i8* %Q) #3 { } define void @test3a(i8* noalias %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void @@ -174,6 +196,8 @@ define void @test3a(i8* noalias %P, i8* noalias %Q) #3 { } define void @test4(i8* %P, i8* noalias %Q) #3 { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void @@ -190,6 +214,9 @@ define void @test4(i8* %P, i8* noalias %Q) #3 { } define void @test5(i8* %P, i8* %Q, i8* %R) #3 { + load i8, i8* %P + load i8, i8* %Q + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) ret void @@ -210,6 +237,9 @@ define void @test5(i8* %P, i8* %Q, i8* %R) #3 { } define void @test5a(i8* noalias %P, i8* noalias %Q, i8* noalias %R) nounwind ssp { + load i8, i8* %P + load i8, i8* %Q + load i8, i8* %R tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) ret void @@ -230,6 +260,7 @@ define void @test5a(i8* noalias %P, i8* noalias %Q, i8* noalias %R) nounwind ssp } define void @test6(i8* %P) #3 { + load i8, i8* %P call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false) call void @a_readonly_func(i8* %P) ret void @@ -243,6 +274,7 @@ define void @test6(i8* %P) #3 { } define void @test7(i8* %P) #3 { + load i8, i8* %P call void @a_writeonly_func(i8* %P) call void @a_readonly_func(i8* %P) ret void @@ -262,6 +294,8 @@ declare void @an_argmemonly_func(i8*) #0 define void @test8(i8* %p) { entry: %q = getelementptr i8, i8* %p, i64 16 + load i8, i8* %p + load i8, i8* %q call void @a_readonly_func(i8* %p) call void @an_inaccessiblememonly_func() call void @a_writeonly_func(i8* %q) @@ -302,6 +336,8 @@ entry: declare void @another_argmemonly_func(i8*, i8*) #0 define void @test8a(i8* noalias %p, i8* noalias %q) { entry: + load i8, i8* %p + load i8, i8* %q call void @another_argmemonly_func(i8* %p, i8* %q) ret void @@ -311,6 +347,8 @@ entry: } define void @test8b(i8* %p, i8* %q) { entry: + load i8, i8* %p + load i8, i8* %q call void @another_argmemonly_func(i8* %p, i8* %q) ret void @@ -325,6 +363,8 @@ define void @test9(i8* %p) { ; CHECK-LABEL: Function: test9 entry: %q = getelementptr i8, i8* %p, i64 16 + load i8, i8* %p + load i8, i8* %q call void @a_readonly_func(i8* %p) [ "unknown"() ] call void @an_inaccessiblememonly_func() [ "unknown"() ] call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] @@ -358,6 +398,8 @@ define void @test10(i8* %p) { ; CHECK-LABEL: Function: test10 entry: %q = getelementptr i8, i8* %p, i64 16 + load i8, i8* %p + load i8, i8* %q call void @a_readonly_func(i8* %p) #6 [ "unknown"() ] call void @an_inaccessiblememonly_func() #7 [ "unknown"() ] call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ] diff --git a/llvm/test/Analysis/BasicAA/dag.ll b/llvm/test/Analysis/BasicAA/dag.ll index 23518d5..bf1397c 100644 --- a/llvm/test/Analysis/BasicAA/dag.ll +++ b/llvm/test/Analysis/BasicAA/dag.ll @@ -11,12 +11,15 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; CHECK: MustAlias: i16* %bigbase, i8* %phi define i8 @foo(i8* %base, i1 %x, i1 %w) { entry: + load i8, i8* %base br i1 %w, label %wa, label %wb wa: %wwa = bitcast i8* %base to i8* + load i8, i8* %wwa br label %wc wb: %wwb = bitcast i8* %base to i8* + load i8, i8* %wwb br label %wc wc: %first = phi i8* [ %wwa, %wa ], [ %wwb, %wb ] diff --git a/llvm/test/Analysis/BasicAA/deoptimize.ll b/llvm/test/Analysis/BasicAA/deoptimize.ll index acdafff..b8f9f97 100644 --- a/llvm/test/Analysis/BasicAA/deoptimize.ll +++ b/llvm/test/Analysis/BasicAA/deoptimize.ll @@ -9,6 +9,7 @@ declare void @llvm.experimental.deoptimize.void(...) declare void @unknown_but_readonly() readonly define void @test1(i8* %p) { + load i8, i8* %p call void(...) @llvm.experimental.deoptimize.void() [ "deopt"() ] ret void @@ -26,6 +27,8 @@ define i32 @test_memcpy_with_deopt() { %A = alloca i8 %B = alloca i8 + load i8, i8* %A + load i8, i8* %B store i32 2, i32* @G1 ;; Not referenced by semantics of memcpy but still may be read due to "deopt" @@ -43,6 +46,8 @@ define i32 @test_memmove_with_deopt() { %A = alloca i8 %B = alloca i8 + load i8, i8* %A + load i8, i8* %B store i32 2, i32* @G1 ;; Not referenced by semantics of memcpy but still may be read due to "deopt" diff --git a/llvm/test/Analysis/BasicAA/dereferenceable.ll b/llvm/test/Analysis/BasicAA/dereferenceable.ll index f96ead9..bab8df5 100644 --- a/llvm/test/Analysis/BasicAA/dereferenceable.ll +++ b/llvm/test/Analysis/BasicAA/dereferenceable.ll @@ -7,7 +7,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define i64 @global_and_deref_arg_1(i64* dereferenceable(8) %arg) nofree nosync { ; CHECK: Function: global_and_deref_arg_1: 2 pointers, 0 call sites -; CHECK-NEXT: NoAlias: i32* @G, i64* %arg +; CHECK-NEXT: NoAlias: i64* %arg, i32* @G bb: store i64 1, i64* %arg, align 8 store i32 0, i32* @G, align 4 @@ -27,7 +27,7 @@ bb: define i32 @byval_and_deref_arg_1(i32* byval(i32) %obj, i64* dereferenceable(8) %arg) nofree nosync { ; CHECK: Function: byval_and_deref_arg_1: 2 pointers, 0 call sites -; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg +; CHECK-NEXT: NoAlias: i64* %arg, i32* %obj bb: store i32 1, i32* %obj, align 4 store i64 0, i64* %arg, align 8 @@ -80,7 +80,7 @@ bb: define i64 @global_and_deref_arg_non_deref_1(i64* dereferenceable(2) %arg) nofree nosync { ; CHECK: Function: global_and_deref_arg_non_deref_1: 2 pointers, 0 call sites -; CHECK-NEXT: NoAlias: i32* @G, i64* %arg +; CHECK-NEXT: NoAlias: i64* %arg, i32* @G bb: store i64 1, i64* %arg, align 8 store i32 0, i32* @G, align 4 @@ -101,7 +101,7 @@ bb: define i32 @byval_and_deref_arg_non_deref_1(i32* byval(i32) %obj, i64* dereferenceable(2) %arg) nofree nosync { ; CHECK: Function: byval_and_deref_arg_non_deref_1: 2 pointers, 0 call sites -; CHECK-NEXT: NoAlias: i32* %obj, i64* %arg +; CHECK-NEXT: NoAlias: i64* %arg, i32* %obj bb: store i32 1, i32* %obj, align 4 store i64 0, i64* %arg, align 8 diff --git a/llvm/test/Analysis/BasicAA/gep-decomposition-limit.ll b/llvm/test/Analysis/BasicAA/gep-decomposition-limit.ll index dbf2fb0..76362d3 100644 --- a/llvm/test/Analysis/BasicAA/gep-decomposition-limit.ll +++ b/llvm/test/Analysis/BasicAA/gep-decomposition-limit.ll @@ -27,5 +27,14 @@ define void @test(i8* %base) { %gep.inc6 = getelementptr i8, i8* %gep.inc5, i64 1 %gep.inc7 = getelementptr i8, i8* %gep.inc6, i64 1 + load i8, i8* %gep.add5 + load i8, i8* %gep.add6 + load i8, i8* %gep.add7 + load i8, i8* %gep.inc3 + load i8, i8* %gep.inc4 + load i8, i8* %gep.inc5 + load i8, i8* %gep.inc6 + load i8, i8* %gep.inc7 + ret void } diff --git a/llvm/test/Analysis/BasicAA/gep-implicit-trunc-32-bit-pointers.ll b/llvm/test/Analysis/BasicAA/gep-implicit-trunc-32-bit-pointers.ll index 3b903fa..8c79275 100644 --- a/llvm/test/Analysis/BasicAA/gep-implicit-trunc-32-bit-pointers.ll +++ b/llvm/test/Analysis/BasicAA/gep-implicit-trunc-32-bit-pointers.ll @@ -13,6 +13,7 @@ define void @mustalias_overflow_in_32_bit_constants(i8* %ptr) { ; CHECK-NEXT: MustAlias: i8* %gep.2, i8* %ptr ; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %gep.2 ; + load i8, i8* %ptr %gep.1 = getelementptr i8, i8* %ptr, i64 4294967296 store i8 0, i8* %gep.1 %gep.2 = getelementptr i8, i8* %ptr, i64 0 @@ -24,6 +25,7 @@ define void @mustalias_overflow_in_32_with_var_index([1 x i8]* %ptr, i64 %n) { ; CHECK-LABEL: Function: mustalias_overflow_in_32_with_var_index ; CHECK: MustAlias: i8* %gep.1, i8* %gep.2 ; + load [1 x i8], [1 x i8]* %ptr %gep.1 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 4294967296 store i8 0, i8* %gep.1 %gep.2 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 0 @@ -37,6 +39,7 @@ define void @noalias_overflow_in_32_bit_constants(i8* %ptr) { ; CHECK-NEXT: NoAlias: i8* %gep.2, i8* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.1, i8* %gep.2 ; + load i8, i8* %ptr %gep.1 = getelementptr i8, i8* %ptr, i64 4294967296 store i8 0, i8* %gep.1 %gep.2 = getelementptr i8, i8* %ptr, i64 1 @@ -53,6 +56,7 @@ define void @mustalias_overflow_in_32_bit_add_mul_gep(i8* %ptr, i64 %i) { ; CHECK-NEXT: MayAlias: i8* %gep.2, i8* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %gep.2 ; + load i8, i8* %ptr %s.1 = icmp sgt i64 %i, 0 call void @llvm.assume(i1 %s.1) @@ -69,6 +73,7 @@ define void @mayalias_overflow_in_32_bit_non_zero(i8* %ptr, i64 %n) { ; CHECK-LABEL: Function: mayalias_overflow_in_32_bit_non_zero ; CHECK: MayAlias: i8* %gep, i8* %ptr ; + load i8, i8* %ptr %c = icmp ne i64 %n, 0 call void @llvm.assume(i1 %c) store i8 0, i8* %ptr @@ -83,6 +88,7 @@ define void @mayalias_overflow_in_32_bit_positive(i8* %ptr, i64 %n) { ; CHECK: MayAlias: i8* %gep.2, i8* %ptr ; CHECK: MayAlias: i8* %gep.1, i8* %gep.2 ; + load i8, i8* %ptr %c = icmp sgt i64 %n, 0 call void @llvm.assume(i1 %c) %gep.1 = getelementptr i8, i8* %ptr, i64 -1 diff --git a/llvm/test/Analysis/BasicAA/gep-modulo.ll b/llvm/test/Analysis/BasicAA/gep-modulo.ll index 39ac0fd..6e17796 100644 --- a/llvm/test/Analysis/BasicAA/gep-modulo.ll +++ b/llvm/test/Analysis/BasicAA/gep-modulo.ll @@ -5,10 +5,11 @@ target datalayout = "p:64:64:64" ; %gep.idx and %gep.6 must-alias if %mul overflows (e.g. %idx == 52). define void @may_overflow_mul_add_i8([16 x i8]* %ptr, i8 %idx) { ; CHECK-LABEL: Function: may_overflow_mul_add_i8: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 6): [16 x i8]* %ptr, i8* %gep.6 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -6): i8* %gep.6, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.6, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i8 %idx, 5 %add = add i8 %mul, 2 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %add @@ -20,10 +21,11 @@ define void @may_overflow_mul_add_i8([16 x i8]* %ptr, i8 %idx) { define void @nuw_nsw_mul_add_i8([16 x i8]* %ptr, i8 %idx) { ; CHECK-LABEL: Function: nuw_nsw_mul_add_i8: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 6): [16 x i8]* %ptr, i8* %gep.6 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -6): i8* %gep.6, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.6, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw nsw i8 %idx, 5 %add = add nuw nsw i8 %mul, 2 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %add @@ -36,10 +38,11 @@ define void @nuw_nsw_mul_add_i8([16 x i8]* %ptr, i8 %idx) { ; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 52). define void @may_overflow_mul_sub_i8([16 x i8]* %ptr, i8 %idx) { ; CHECK-LABEL: Function: may_overflow_mul_sub_i8: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i8 %idx, 5 %sub = sub i8 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %sub @@ -51,10 +54,11 @@ define void @may_overflow_mul_sub_i8([16 x i8]* %ptr, i8 %idx) { define void @nuw_nsw_mul_sub_i8([16 x i8]* %ptr, i8 %idx) { ; CHECK-LABEL: Function: nuw_nsw_mul_sub_i8: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw nsw i8 %idx, 5 %sub = sub nuw nsw i8 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i8 %sub @@ -68,10 +72,11 @@ define void @nuw_nsw_mul_sub_i8([16 x i8]* %ptr, i8 %idx) { ; (e.g. %idx == 3689348814741910323). define void @may_overflow_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: may_overflow_mul_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i64 %idx, 5 %sub = sub i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -83,10 +88,11 @@ define void @may_overflow_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { define void @nuw_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: nuw_nsw_mul_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw nsw i64 %idx, 5 %sub = sub nuw nsw i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -98,10 +104,11 @@ define void @nuw_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { define void @only_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: only_nsw_mul_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nsw i64 %idx, 5 %sub = sub nsw i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -113,10 +120,11 @@ define void @only_nsw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { define void @only_nuw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: only_nuw_mul_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw i64 %idx, 5 %sub = sub nuw i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -130,10 +138,11 @@ define void @only_nuw_mul_sub_i64([16 x i8]* %ptr, i64 %idx) { ; because we multiply by a power-of-2. define void @may_overflow_mul_pow2_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: may_overflow_mul_pow2_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i64 %idx, 8 %sub = sub i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -146,10 +155,11 @@ define void @may_overflow_mul_pow2_sub_i64([16 x i8]* %ptr, i64 %idx) { ; Multiplies by power-of-2 preserves modulo and the sub does not wrap. define void @mul_pow2_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: mul_pow2_sub_nsw_nuw_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i64 %idx, 8 %sub = sub nuw nsw i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -161,10 +171,11 @@ define void @mul_pow2_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) { define void @may_overflow_shl_sub_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: may_overflow_shl_sub_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = shl i64 %idx, 2 %sub = sub i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -176,10 +187,11 @@ define void @may_overflow_shl_sub_i64([16 x i8]* %ptr, i64 %idx) { define void @shl_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: shl_sub_nsw_nuw_i64: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = shl i64 %idx, 3 %sub = sub nsw nuw i64 %mul, 1 %gep.idx = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %sub @@ -192,10 +204,11 @@ define void @shl_sub_nsw_nuw_i64([16 x i8]* %ptr, i64 %idx) { ; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 110). define void @may_overflow_i32_sext([16 x i8]* %ptr, i32 %idx) { ; CHECK-LABEL: Function: may_overflow_i32_sext: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i32 %idx, 678152731 %sub = sub i32 %mul, 1582356375 %sub.ext = sext i32 %sub to i64 @@ -208,10 +221,11 @@ define void @may_overflow_i32_sext([16 x i8]* %ptr, i32 %idx) { define void @nuw_nsw_i32_sext([16 x i8]* %ptr, i32 %idx) { ; CHECK-LABEL: Function: nuw_nsw_i32_sext: 3 pointers, 0 call sites -; CHECK-NEXT: NoAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: NoAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw nsw i32 %idx, 678152731 %sub = sub nuw nsw i32 %mul, 1582356375 %sub.ext = sext i32 %sub to i64 @@ -225,10 +239,11 @@ define void @nuw_nsw_i32_sext([16 x i8]* %ptr, i32 %idx) { ; %gep.idx and %gep.3 must-alias if %mul overflows (e.g. %idx == 110). define void @may_overflow_i32_zext([16 x i8]* %ptr, i32 %idx) { ; CHECK-LABEL: Function: may_overflow_i32_zext: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: MayAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul i32 %idx, 678152731 %sub = sub i32 %mul, 1582356375 %sub.ext = zext i32 %sub to i64 @@ -241,10 +256,11 @@ define void @may_overflow_i32_zext([16 x i8]* %ptr, i32 %idx) { define void @nuw_nsw_i32_zext([16 x i8]* %ptr, i32 %idx) { ; CHECK-LABEL: Function: nuw_nsw_i32_zext: 3 pointers, 0 call sites -; CHECK-NEXT: NoAlias: [16 x i8]* %ptr, i8* %gep.idx -; CHECK-NEXT: PartialAlias (off 3): [16 x i8]* %ptr, i8* %gep.3 +; CHECK-NEXT: NoAlias: i8* %gep.idx, [16 x i8]* %ptr +; CHECK-NEXT: PartialAlias (off -3): i8* %gep.3, [16 x i8]* %ptr ; CHECK-NEXT: NoAlias: i8* %gep.3, i8* %gep.idx ; + load [16 x i8], [16 x i8]* %ptr %mul = mul nuw nsw i32 %idx, 678152731 %sub = sub nuw nsw i32 %mul, 1582356375 %sub.ext = zext i32 %sub to i64 @@ -259,10 +275,11 @@ define void @nuw_nsw_i32_zext([16 x i8]* %ptr, i32 %idx) { ; %gep.mul.1 and %gep.sub.2 may alias. define void @may_overflow_pointer_diff([16 x i8]* %ptr, i64 %idx) { ; CHECK-LABEL: Function: may_overflow_pointer_diff: 3 pointers, 0 call sites -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.mul.1 -; CHECK-NEXT: MayAlias: [16 x i8]* %ptr, i8* %gep.sub.2 +; CHECK-NEXT: MayAlias: i8* %gep.mul.1, [16 x i8]* %ptr +; CHECK-NEXT: MayAlias: i8* %gep.sub.2, [16 x i8]* %ptr ; CHECK-NEXT: MayAlias: i8* %gep.mul.1, i8* %gep.sub.2 ; + load [16 x i8], [16 x i8]* %ptr %mul.1 = mul i64 %idx, 6148914691236517207 %gep.mul.1 = getelementptr [16 x i8], [16 x i8]* %ptr, i32 0, i64 %mul.1 store i8 1, i8* %gep.mul.1, align 1 @@ -278,19 +295,21 @@ define void @may_overflow_pointer_diff([16 x i8]* %ptr, i64 %idx) { ; (((18446744073709551614 * 8) % 2^64 + 6 * 2) % 2^64 + 10) % 2^64 == 6. define void @may_overflow_mul_scale_neg([200 x [ 6 x i8]]* %ptr, i64 %idx.1,i64 %idx.2) { ; CHECK-LABEL: Function: may_overflow_mul_scale_neg: 4 pointers, 2 call sites -; CHECK-NEXT: MustAlias: [200 x [6 x i8]]* %ptr, i8* %bc -; CHECK-NEXT: PartialAlias (off 6): [200 x [6 x i8]]* %ptr, i8* %gep.1 +; CHECK-NEXT: MustAlias: i8* %bc, [200 x [6 x i8]]* %ptr +; CHECK-NEXT: PartialAlias (off -6): i8* %gep.1, [200 x [6 x i8]]* %ptr ; CHECK-NEXT: NoAlias: i8* %bc, i8* %gep.1 -; CHECK-NEXT: MayAlias: [200 x [6 x i8]]* %ptr, i8* %gep.idx +; CHECK-NEXT: MayAlias: i8* %gep.idx, [200 x [6 x i8]]* %ptr ; CHECK-NEXT: MayAlias: i8* %bc, i8* %gep.idx ; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %gep.idx ; + load [200 x [6 x i8]], [200 x [6 x i8]]* %ptr %idx.1.pos = icmp sge i64 %idx.1, 0 call void @llvm.assume(i1 %idx.1.pos) %idx.2.pos = icmp sge i64 %idx.2, 0 call void @llvm.assume(i1 %idx.2.pos) %bc = bitcast [ 200 x [ 6 x i8 ] ]* %ptr to i8* + load i8, i8* %bc %gep.1 = getelementptr i8, i8* %bc, i64 6 store i8 1, i8* %gep.1, align 1 @@ -311,6 +330,7 @@ define i8 @mul_may_overflow_var_nonzero_minabsvarindex_one_index([2000 x i8]* %a ; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.idx ; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.917 ; + load [2000 x i8], [2000 x i8]* %arr %or = or i64 %v, 1 %idx = mul i64 %or, 1844674407370955 %gep.idx = getelementptr inbounds [2000 x i8], [2000 x i8]* %arr, i32 0, i64 %idx @@ -331,7 +351,7 @@ define i8 @mul_nsw_var_nonzero_minabsvarindex_one_index([2000 x i8]* %arr, i8 %x ; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.idx ; CHECK-NEXT: NoAlias: i8* %gep.0, i8* %gep.917 ; - + load [2000 x i8], [2000 x i8]* %arr %or = or i64 %v, 1 %idx = mul nsw i64 %or, 1844674407370955 %gep.idx = getelementptr inbounds [2000 x i8], [2000 x i8]* %arr, i32 0, i64 %idx diff --git a/llvm/test/Analysis/BasicAA/guards.ll b/llvm/test/Analysis/BasicAA/guards.ll index 47a14aa..8ab8b36 100644 --- a/llvm/test/Analysis/BasicAA/guards.ll +++ b/llvm/test/Analysis/BasicAA/guards.ll @@ -6,6 +6,8 @@ declare void @llvm.experimental.guard(i1, ...) declare void @unknown_but_readonly() readonly define void @test1(i8* %P, i8* %Q) { + load i8, i8* %P + load i8, i8* %Q tail call void(i1,...) @llvm.experimental.guard(i1 true) [ "deopt"() ] tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void diff --git a/llvm/test/Analysis/BasicAA/index-size.ll b/llvm/test/Analysis/BasicAA/index-size.ll index 6c081be..0d360ec 100644 --- a/llvm/test/Analysis/BasicAA/index-size.ll +++ b/llvm/test/Analysis/BasicAA/index-size.ll @@ -10,6 +10,7 @@ define void @mustalias_due_to_index_size(i8* %ptr) { ; CHECK-NEXT: MustAlias: i8* %gep.2, i8* %ptr ; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %gep.2 ; + load i8, i8* %ptr %gep.1 = getelementptr i8, i8* %ptr, i64 4294967296 store i8 0, i8* %gep.1 %gep.2 = getelementptr i8, i8* %ptr, i64 0 diff --git a/llvm/test/Analysis/BasicAA/invariant_group.ll b/llvm/test/Analysis/BasicAA/invariant_group.ll index 3de6d70..16438a9 100644 --- a/llvm/test/Analysis/BasicAA/invariant_group.ll +++ b/llvm/test/Analysis/BasicAA/invariant_group.ll @@ -35,9 +35,12 @@ define i8 @testLaunderInvariantGroupIsNotEscapeSource() { entry: %a = alloca %struct.A, align 8 %a.bitcast = bitcast %struct.A* %a to i8* + load %struct.A, %struct.A* %a + load i8, i8* %a.bitcast %n = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 1 store i8 42, i8* %n %a.laundered = call i8* @llvm.launder.invariant.group.p0i8(i8* nonnull %a.bitcast) + load i8, i8* %a.laundered %n.laundered = getelementptr inbounds i8, i8* %a.laundered, i64 8 %v = load i8, i8* %n.laundered ; make sure that the load from %n.laundered to %v aliases the store of 42 to %n diff --git a/llvm/test/Analysis/BasicAA/libfuncs-darwin.ll b/llvm/test/Analysis/BasicAA/libfuncs-darwin.ll index fd9ac3e..8b80514 100644 --- a/llvm/test/Analysis/BasicAA/libfuncs-darwin.ll +++ b/llvm/test/Analysis/BasicAA/libfuncs-darwin.ll @@ -14,6 +14,8 @@ define void @test_memset_pattern4_const_size(i8* noalias %a, i8* noalias %patter ; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.4 <-> call void @memset_pattern4(i8* %a, i8* %pattern, i64 17) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern4(i8* %a, i8* %pattern, i64 17) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -35,6 +37,8 @@ define void @test_memset_pattern4_variable_size(i8* noalias %a, i8* noalias %pat ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern4(i8* %a, i8* %pattern, i64 %n) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern4(i8* %a, i8* %pattern, i64 %n) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -53,6 +57,8 @@ define void @test_memset_pattern8_const_size(i8* noalias %a, i8* noalias %patter ; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.8 <-> call void @memset_pattern8(i8* %a, i8* %pattern, i64 17) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern8(i8* %a, i8* %pattern, i64 17) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -74,6 +80,8 @@ define void @test_memset_pattern8_variable_size(i8* noalias %a, i8* noalias %pat ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern8(i8* %a, i8* %pattern, i64 %n) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern8(i8* %a, i8* %pattern, i64 %n) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -92,6 +100,8 @@ define void @test_memset_pattern16_const_size(i8* noalias %a, i8* noalias %patte ; CHECK-NEXT: NoModRef: Ptr: i8* %pattern.gep.16 <-> call void @memset_pattern16(i8* %a, i8* %pattern, i64 17) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern16(i8* %a, i8* %pattern, i64 17) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -113,6 +123,8 @@ define void @test_memset_pattern16_variable_size(i8* noalias %a, i8* noalias %pa ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.17 <-> call void @memset_pattern16(i8* %a, i8* %pattern, i64 %n) ; entry: + load i8, i8* %a + load i8, i8* %pattern call void @memset_pattern16(i8* %a, i8* %pattern, i64 %n) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 diff --git a/llvm/test/Analysis/BasicAA/libfuncs.ll b/llvm/test/Analysis/BasicAA/libfuncs.ll index d4ab42e..e64d9a8 100644 --- a/llvm/test/Analysis/BasicAA/libfuncs.ll +++ b/llvm/test/Analysis/BasicAA/libfuncs.ll @@ -9,6 +9,8 @@ ; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) define i32 @test_memcmp_const_size(i8* noalias %a, i8* noalias %b) { entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -30,6 +32,8 @@ entry: ; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 %n) define i32 @test_memcmp_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) { entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 %n) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -54,6 +58,8 @@ declare i32 @bcmp(i8*, i8*, i64) ; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 4) define i32 @test_bcmp_const_size(i8* noalias %a, i8* noalias %b) { entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 4) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -75,6 +81,8 @@ entry: ; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 %n) define i32 @test_bcmp_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) { entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i32 @bcmp(i8* %a, i8* %b, i64 %n) %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 @@ -96,6 +104,7 @@ declare i8* @memchr(i8*, i32, i64) define i8* @test_memchr_const_size(i8* noalias %a) { entry: %res = call i8* @memchr(i8* %a, i32 42, i64 4) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -116,7 +125,10 @@ declare i8* @memccpy(i8*, i8*, i32, i64) define i8* @test_memccpy_const_size(i8* noalias %a, i8* noalias %b) { entry: + load i8, i8* %a + load i8, i8* %b %res = call i8* @memccpy(i8* %a, i8* %b, i32 42, i64 4) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -144,8 +156,11 @@ entry: store i8 0, i8* %a store i8 2, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 + load i8, i8* %a.gep.1 %b.gep.1 = getelementptr i8, i8* %b, i32 1 + load i8, i8* %b.gep.1 %res = tail call i8* @strcat(i8* %a.gep.1, i8* %b.gep.1) + load i8, i8* %res %a.gep.5 = getelementptr i8, i8* %a, i32 5 store i8 1, i8* %a.gep.5 %b.gep.5 = getelementptr i8, i8* %b, i32 5 @@ -169,8 +184,11 @@ entry: store i8 0, i8* %a store i8 2, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 + load i8, i8* %a.gep.1 %b.gep.1 = getelementptr i8, i8* %b, i32 1 + load i8, i8* %b.gep.1 %res = tail call i8* @strncat(i8* %a.gep.1, i8* %b.gep.1, i64 %n) + load i8, i8* %res %a.gep.5 = getelementptr i8, i8* %a, i32 5 store i8 1, i8* %a.gep.5 %b.gep.5 = getelementptr i8, i8* %b, i32 5 @@ -194,8 +212,11 @@ entry: store i8 0, i8* %a store i8 2, i8* %b %a.gep.1 = getelementptr i8, i8* %a, i32 1 + load i8, i8* %a.gep.1 %b.gep.1 = getelementptr i8, i8* %b, i32 1 + load i8, i8* %b.gep.1 %res = tail call i8* @strcpy(i8* %a.gep.1, i8* %b.gep.1) + load i8, i8* %res %a.gep.5 = getelementptr i8, i8* %a, i32 5 store i8 1, i8* %a.gep.5 %b.gep.5 = getelementptr i8, i8* %b, i32 5 @@ -216,7 +237,10 @@ define i8* @test_strncpy_const_size(i8* noalias %a, i8* noalias %b) { ; CHECK-NEXT: NoModRef: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 4) ; entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 4) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -239,7 +263,10 @@ define i8* @test_strncpy_variable_size(i8* noalias %a, i8* noalias %b, i64 %n) { ; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 %n) ; entry: + load i8, i8* %a + load i8, i8* %b %res = tail call i8* @strncpy(i8* %a, i8* %b, i64 %n) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -261,7 +288,9 @@ define i8* @test_memset_chk_const_size(i8* noalias %a, i64 %n) { ; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n) ; entry: + load i8, i8* %a %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 @@ -277,7 +306,9 @@ define i8* @test_memset_chk_variable_size(i8* noalias %a, i64 %n.1, i64 %n.2) { ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 %n.1, i64 %n.2) ; entry: + load i8, i8* %a %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 %n.1, i64 %n.2) + load i8, i8* %res %a.gep.1 = getelementptr i8, i8* %a, i32 1 store i8 0, i8* %a.gep.1 %a.gep.5 = getelementptr i8, i8* %a, i32 5 diff --git a/llvm/test/Analysis/BasicAA/negoffset.ll b/llvm/test/Analysis/BasicAA/negoffset.ll index ecc681d..2e5122a 100644 --- a/llvm/test/Analysis/BasicAA/negoffset.ll +++ b/llvm/test/Analysis/BasicAA/negoffset.ll @@ -14,6 +14,9 @@ define void @arr() { %random = call i32* @random.i32(i32* %alloca) %p0 = getelementptr inbounds i32, i32* %random, i32 0 %p1 = getelementptr inbounds i32, i32* %random, i32 1 + load i32, i32* %alloca + load i32, i32* %p0 + load i32, i32* %p1 ret void } @@ -24,6 +27,9 @@ define void @arg(i32* %arg) { %random = call i32* @random.i32(i32* %arg) %p0 = getelementptr inbounds i32, i32* %random, i32 0 %p1 = getelementptr inbounds i32, i32* %random, i32 1 + load i32, i32* %arg + load i32, i32* %p0 + load i32, i32* %p1 ret void } @@ -35,6 +41,9 @@ define void @global() { %random = call i32* @random.i32(i32* @gv) %p0 = getelementptr inbounds i32, i32* %random, i32 0 %p1 = getelementptr inbounds i32, i32* %random, i32 1 + load i32, i32* @gv + load i32, i32* %p0 + load i32, i32* %p1 ret void } @@ -52,6 +61,10 @@ define void @struct() { %f1 = getelementptr inbounds %struct, %struct* %alloca, i32 0, i32 1 %p0 = getelementptr inbounds i32, i32* %random, i32 0 %p1 = getelementptr inbounds i32, i32* %random, i32 1 + load i32, i32* %f0 + load i32, i32* %f1 + load i32, i32* %p0 + load i32, i32* %p1 ret void } @@ -76,6 +89,12 @@ define void @complex1(i32 %i) { %r2.1 = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 1 %r2.i = getelementptr inbounds %complex, %complex* %random, i32 0, i32 2, i32 %i %r2.1i = getelementptr inbounds i32, i32* %r2.1, i32 %i + load i32, i32* %a2.0 + load i32, i32* %a1 + load i32, i32* %r2.0 + load i32, i32* %r2.1 + load i32, i32* %r2.i + load i32, i32* %r2.1i ret void } @@ -94,6 +113,11 @@ define void @complex2(i32 %i, i32 %j) { %p120 = getelementptr inbounds %outer, %outer* %random, i32 1, i32 2, i32 2, i32 0 %pi20 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 2, i32 0 %pij1 = getelementptr inbounds %outer, %outer* %random, i32 %i, i32 2, i32 %j, i32 1 + load i32, i32* %alloca + load i32, i32* %a3 + load i32, i32* %p120 + load i32, i32* %pi20 + load i32, i32* %pij1 ret void } @@ -124,6 +148,7 @@ entry: define void @one_size_unknown(i8* %p, i32 %size) { %p.minus1 = getelementptr inbounds i8, i8* %p, i32 -1 call void @llvm.memset.p0i8.i32(i8* %p, i8 0, i32 %size, i1 false) + load i8, i8* %p.minus1 ret void } @@ -141,6 +166,9 @@ define void @all_inbounds() { %p0 = getelementptr inbounds i8, i8* %random, i8 0 %step = getelementptr i8, i8* %random, i8 4 %p1 = getelementptr inbounds i8, i8* %step, i8 2 + load i32, i32* %alloca + load i8, i8* %p0 + load i8, i8* %p1 ret void } @@ -156,6 +184,8 @@ define void @common_factor(i32 %x) { %step = getelementptr inbounds i8, i8* %random, i8 4 %step.bitcast = bitcast i8* %step to i32* %p1 = getelementptr inbounds i32, i32* %step.bitcast, i32 %x + load i32, i32* %p0 + load i32, i32* %p1 ret void } diff --git a/llvm/test/Analysis/BasicAA/noalias-geps.ll b/llvm/test/Analysis/BasicAA/noalias-geps.ll index 245ace3..a7cfc40 100644 --- a/llvm/test/Analysis/BasicAA/noalias-geps.ll +++ b/llvm/test/Analysis/BasicAA/noalias-geps.ll @@ -26,8 +26,11 @@ bb3: %f1 = getelementptr i32, i32* %ptr_phi , i32 1 %g1 = getelementptr i32, i32* %ptr_phi2 , i32 1 ; This should also work if the access size is not the same. -; CHECK: NoAlias: i16* %h1, i32* %f1 +; CHECK: NoAlias: i32* %f1, i16* %h1 %h1 = bitcast i32* %g1 to i16* + load i32, i32* %f1 + load i32, i32* %g1 + load i16, i16* %h1 ret i32 0 } @@ -54,6 +57,8 @@ bb3: ; CHECK: NoAlias: i32* %f1, i32* %g1 %f1 = getelementptr [2 x i32], [2 x i32]* %ptr_phi , i32 1, i32 %i %g1 = getelementptr [2 x i32], [2 x i32]* %ptr_phi2 , i32 1, i32 %i + load i32, i32* %f1 + load i32, i32* %g1 ret i32 0 } diff --git a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll index a9785ef..3262f8d 100644 --- a/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll +++ b/llvm/test/Analysis/BasicAA/noalias-scope-decl.ll @@ -5,6 +5,8 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i1) # declare void @llvm.experimental.noalias.scope.decl(metadata) define void @test1(i8* %P, i8* %Q) nounwind ssp { + load i8, i8* %P + load i8, i8* %Q tail call void @llvm.experimental.noalias.scope.decl(metadata !0) tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) ret void diff --git a/llvm/test/Analysis/BasicAA/phi-aa.ll b/llvm/test/Analysis/BasicAA/phi-aa.ll index 6aed183..9eb63cf 100644 --- a/llvm/test/Analysis/BasicAA/phi-aa.ll +++ b/llvm/test/Analysis/BasicAA/phi-aa.ll @@ -64,6 +64,7 @@ for.body: %sub11 = add i32 %1, -1 %idxprom12 = zext i32 %sub11 to i64 %arrayidx13 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i64 %idxprom12 + load i32, i32* %arrayidx13 call void @inc(i32* %jj7) br label %codeRepl @@ -90,6 +91,7 @@ entry: loop1: %n1 = phi i32 [ 0, %entry ], [ %add1, %loop2 ] %val1 = phi i32* [ @X, %entry ], [ %val2, %loop2 ] + load i32, i32* %val1 %add1 = add i32 %n1, 1 %cmp1 = icmp ne i32 %n1, 32 br i1 %cmp1, label %loop2, label %end @@ -97,6 +99,7 @@ loop1: loop2: %n2 = phi i32 [ 0, %loop1 ], [ %add2, %loop3 ] %val2 = phi i32* [ %val1, %loop1 ], [ %val3, %loop3 ] + load i32, i32* %val2 %add2 = add i32 %n2, 1 %cmp2 = icmp ne i32 %n2, 32 br i1 %cmp2, label %loop3, label %loop1 @@ -174,8 +177,8 @@ exit: declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1) ; CHECK-LABEL: unsound_inequality -; CHECK: MayAlias: i32* %arrayidx13, i32* %phi ; CHECK: MayAlias: i32* %arrayidx5, i32* %phi +; CHECK: MayAlias: i32* %arrayidx13, i32* %phi ; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5 ; When recursively reasoning about phis, we can't use predicates between @@ -187,6 +190,7 @@ entry: for.body: ; preds = %for.body, %entry %phi = phi i32* [ %arrayidx13, %for.body ], [ %j, %entry ] + load i32, i32* %phi %idx = load i32, i32* %jj7, align 4 %arrayidx5 = getelementptr inbounds [100 x i32], [100 x i32]* %oa5, i64 0, i32 %idx store i32 0, i32* %arrayidx5, align 4 @@ -208,10 +212,14 @@ entry: loop: %ptr = phi i32* [ %ptr.base, %entry ], [ %ptr.next, %split ] %ptr.next = getelementptr inbounds i32, i32* %ptr, i64 1 + load i32, i32* %ptr + load i32, i32* %ptr.next br label %split split: %ptr.phi = phi i32* [ %ptr, %loop ] %ptr.next.phi = phi i32* [ %ptr.next, %loop ] + load i32, i32* %ptr.phi + load i32, i32* %ptr.next.phi br label %loop } diff --git a/llvm/test/Analysis/BasicAA/phi-spec-order.ll b/llvm/test/Analysis/BasicAA/phi-spec-order.ll index aa3d0df..2dcf21f 100644 --- a/llvm/test/Analysis/BasicAA/phi-spec-order.ll +++ b/llvm/test/Analysis/BasicAA/phi-spec-order.ll @@ -27,6 +27,8 @@ for.body4: ; preds = %for.body4, %for.con %lsr.iv1 = phi [16000 x double]* [ %i10, %for.body4 ], [ @X, %for.cond2.preheader ] %lsr.iv = phi i32 [ %lsr.iv.next, %for.body4 ], [ 16000, %for.cond2.preheader ] + load [16000 x double], [16000 x double]* %lsr.iv4 + load [16000 x double], [16000 x double]* %lsr.iv1 %lsr.iv46 = bitcast [16000 x double]* %lsr.iv4 to <4 x double>* %lsr.iv12 = bitcast [16000 x double]* %lsr.iv1 to <4 x double>* %scevgep11 = getelementptr <4 x double>, <4 x double>* %lsr.iv46, i64 -2 @@ -50,8 +52,10 @@ for.body4: ; preds = %for.body4, %for.con %lsr.iv.next = add i32 %lsr.iv, -16 %scevgep = getelementptr [16000 x double], [16000 x double]* %lsr.iv1, i64 0, i64 16 + load double, double* %scevgep %i10 = bitcast double* %scevgep to [16000 x double]* %scevgep5 = getelementptr [16000 x double], [16000 x double]* %lsr.iv4, i64 0, i64 16 + load double, double* %scevgep5 %i11 = bitcast double* %scevgep5 to [16000 x double]* %exitcond.15 = icmp eq i32 %lsr.iv.next, 0 br i1 %exitcond.15, label %for.end, label %for.body4 diff --git a/llvm/test/Analysis/BasicAA/phi-speculation.ll b/llvm/test/Analysis/BasicAA/phi-speculation.ll index 2fca428..d738d82 100644 --- a/llvm/test/Analysis/BasicAA/phi-speculation.ll +++ b/llvm/test/Analysis/BasicAA/phi-speculation.ll @@ -27,6 +27,8 @@ while.body: %tobool = icmp eq i32 %dec, 0 %ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1 %ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 + load i32, i32* %ptr_inc + load i32, i32* %ptr2_inc br i1 %tobool, label %the_exit, label %while.body the_exit: @@ -34,10 +36,10 @@ the_exit: } ; CHECK: test_noalias_2 -; CHECK: NoAlias: i32* %ptr_outer_phi, i32* %ptr_outer_phi2 -; CHECK: NoAlias: i32* %ptr2_inc_outer, i32* %ptr_inc_outer -; CHECK: NoAlias: i32* %ptr2_phi, i32* %ptr_phi -; CHECK: NoAlias: i32* %ptr2_inc, i32* %ptr_inc +; CHECK-DAG: NoAlias: i32* %ptr_outer_phi, i32* %ptr_outer_phi2 +; CHECK-DAG: NoAlias: i32* %ptr2_inc_outer, i32* %ptr_inc_outer +; CHECK-DAG: NoAlias: i32* %ptr2_phi, i32* %ptr_phi +; CHECK-DAG: NoAlias: i32* %ptr2_inc, i32* %ptr_inc define i32 @test_noalias_2(i32* %ptr2, i32 %count, i32* %coeff) { entry: %ptr = getelementptr inbounds i32, i32* %ptr2, i64 1 @@ -47,6 +49,8 @@ outer.while.header: %ptr_outer_phi = phi i32* [%ptr_inc_outer, %outer.while.backedge], [ %ptr, %entry] %ptr_outer_phi2 = phi i32* [%ptr2_inc_outer, %outer.while.backedge], [ %ptr2, %entry] %num.outer = phi i32 [ %count, %entry ], [ %dec.outer, %outer.while.backedge ] + %ignore1 = load i32, i32* %ptr_outer_phi + %ignore2 = load i32, i32* %ptr_outer_phi2 br label %while.body while.body: @@ -64,11 +68,15 @@ while.body: %tobool = icmp eq i32 %dec, 0 %ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1 %ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 + load i32, i32* %ptr_inc + load i32, i32* %ptr2_inc br i1 %tobool, label %outer.while.backedge, label %while.body outer.while.backedge: %ptr_inc_outer = getelementptr inbounds i32, i32* %ptr_phi, i64 1 %ptr2_inc_outer = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 + load i32, i32* %ptr_inc_outer + load i32, i32* %ptr2_inc_outer %dec.outer = add nsw i32 %num.outer, -1 %br.cond = icmp eq i32 %dec.outer, 0 br i1 %br.cond, label %the_exit, label %outer.while.header @@ -88,6 +96,8 @@ while.body: %num = phi i32 [ %count, %entry ], [ %dec, %while.body ] %ptr_phi = phi i8* [ %x, %entry ], [ %z, %while.body ] %ptr2_phi = phi i8* [ %y, %entry ], [ %ptr_phi, %while.body ] + load i8, i8* %ptr_phi + load i8, i8* %ptr2_phi %dec = add nsw i32 %num, -1 %tobool = icmp eq i32 %dec, 0 br i1 %tobool, label %the_exit, label %while.body @@ -97,18 +107,24 @@ the_exit: } ; CHECK-LABEL: test_different_stride_noalias -; CHECK: NoAlias: i16* %y.base, i8* %x.base -; CHECK: NoAlias: i16* %y, i8* %x -; CHECK: NoAlias: i16* %y.next, i8* %x.next +; CHECK: NoAlias: i8* %x.base, i16* %y.base +; CHECK: NoAlias: i8* %x, i16* %y +; CHECK: NoAlias: i8* %x.next, i16* %y.next define void @test_different_stride_noalias(i1 %c, i8* noalias %x.base, i16* noalias %y.base) { entry: + load i8, i8* %x.base + load i16, i16* %y.base br label %loop loop: %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] %y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ] + load i8, i8* %x + load i16, i16* %y %x.next = getelementptr i8, i8* %x, i64 1 %y.next = getelementptr i16, i16* %y, i64 1 + load i8, i8* %x.next + load i16, i16* %y.next br i1 %c, label %loop, label %exit exit: @@ -131,24 +147,32 @@ else: end: %z8 = phi i8* [ %x8, %if ], [ %y8, %else ] %z16 = phi i16* [ %x16, %if ], [ %y16, %else ] + load i8, i8* %z8 + load i16, i16* %z16 ret void } ; CHECK-LABEL: test_same_stride_mustalias -; CHECK: MustAlias: i4* %y.base, i8* %x.base -; CHECK: MayAlias: i4* %y, i8* %x -; CHECK: MayAlias: i4* %y.next, i8* %x.next +; CHECK: MustAlias: i8* %x.base, i4* %y.base +; CHECK: MayAlias: i8* %x, i4* %y +; CHECK: MayAlias: i8* %x.next, i4* %y.next ; TODO: (x, y) could be MustAlias define void @test_same_stride_mustalias(i1 %c, i8* noalias %x.base) { entry: %y.base = bitcast i8* %x.base to i4* + load i8, i8* %x.base + load i4, i4* %y.base br label %loop loop: %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] %y = phi i4* [ %y.base, %entry ], [ %y.next, %loop ] + load i8, i8* %x + load i4, i4* %y %x.next = getelementptr i8, i8* %x, i64 1 %y.next = getelementptr i4, i4* %y, i64 1 + load i8, i8* %x.next + load i4, i4* %y.next br i1 %c, label %loop, label %exit exit: @@ -156,21 +180,27 @@ exit: } ; CHECK-LABEL: test_different_stride_mustalias -; CHECK: MustAlias: i16* %y.base, i8* %x.base -; CHECK: MayAlias: i16* %y, i8* %x -; CHECK: MayAlias: i16* %y.next, i8* %x.next +; CHECK: MustAlias: i8* %x.base, i16* %y.base +; CHECK: MayAlias: i8* %x, i16* %y +; CHECK: MayAlias: i8* %x.next, i16* %y.next ; Even though the base pointers MustAlias, the different strides don't preserve ; this property across iterations. define void @test_different_stride_mustalias(i1 %c, i8* noalias %x.base) { entry: %y.base = bitcast i8* %x.base to i16* + load i8, i8* %x.base + load i16, i16* %y.base br label %loop loop: %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] %y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ] + load i8, i8* %x + load i16, i16* %y %x.next = getelementptr i8, i8* %x, i64 1 %y.next = getelementptr i16, i16* %y, i64 1 + load i8, i8* %x.next + load i16, i16* %y.next br i1 %c, label %loop, label %exit exit: diff --git a/llvm/test/Analysis/BasicAA/pr31761.ll b/llvm/test/Analysis/BasicAA/pr31761.ll index 6153553..55df470 100644 --- a/llvm/test/Analysis/BasicAA/pr31761.ll +++ b/llvm/test/Analysis/BasicAA/pr31761.ll @@ -15,5 +15,7 @@ define i1 @ham(%struct.blam* %arg) { %tmp2 = getelementptr %struct.blam, %struct.blam* %arg, i64 0, i32 1 %select = select i1 %isNull, i32* null, i32* %tmp2 %tmp3 = getelementptr i32, i32* %select, i32 -1 + load i32, i32* %tmp + load i32, i32* %tmp3 ret i1 true } diff --git a/llvm/test/Analysis/BasicAA/pr35821.ll b/llvm/test/Analysis/BasicAA/pr35821.ll index 658aaab..dbd21bd 100644 --- a/llvm/test/Analysis/BasicAA/pr35821.ll +++ b/llvm/test/Analysis/BasicAA/pr35821.ll @@ -1,11 +1,13 @@ -; RUN: opt %s -passes=aa-eval -disable-output 2>&1 | FileCheck %s +; RUN: opt %s -passes=aa-eval -disable-output -print-all-alias-modref-info 2>&1 | FileCheck %s -; CHECK: 6 Total Alias Queries Performed -; CHECK-NEXT: 6 no alias responses +; CHECK-LABEL: Function: patatino +; CHECK: NoAlias: i1* %G26, i1** %G47 define void @patatino() { %G26 = getelementptr i1, i1* undef, i1 undef %B20 = shl i8 -128, 16 %G47 = getelementptr i1*, i1** undef, i8 %B20 + load i1, i1* %G26 + load i1*, i1** %G47 ret void } diff --git a/llvm/test/Analysis/BasicAA/pr35843.ll b/llvm/test/Analysis/BasicAA/pr35843.ll index cbd6eae..a2504a5 100644 --- a/llvm/test/Analysis/BasicAA/pr35843.ll +++ b/llvm/test/Analysis/BasicAA/pr35843.ll @@ -1,12 +1,14 @@ -; RUN: opt %s -passes=aa-eval -disable-output 2>&1 | FileCheck %s +; RUN: opt %s -passes=aa-eval -disable-output -print-all-alias-modref-info 2>&1 | FileCheck %s -; CHECK: 6 Total Alias Queries Performed -; CHECK-NEXT: 6 no alias responses +; CHECK-LABEL: Function: patatino +; CHECK: NoAlias: i1** %G22, i1*** %G45 define void @patatino() { BB: %G22 = getelementptr i1*, i1** undef, i8 -1 %B1 = mul i66 undef, 9223372036854775808 %G45 = getelementptr i1**, i1*** undef, i66 %B1 + load i1*, i1** %G22 + load i1**, i1*** %G45 ret void } diff --git a/llvm/test/Analysis/BasicAA/pr52735.ll b/llvm/test/Analysis/BasicAA/pr52735.ll index 2cf9236..ed62a3e 100644 --- a/llvm/test/Analysis/BasicAA/pr52735.ll +++ b/llvm/test/Analysis/BasicAA/pr52735.ll @@ -11,7 +11,8 @@ target triple = "x86_64-unknown-linux-gnu" -; CHECK: MayAlias: i32* %v, void (i32*, i8*)* asm "movl $$1, $0", "=*m,X,~{dirflag},~{fpsr},~{flags}" +; CHECK: Both ModRef: Ptr: i32* %v <-> callbr void asm "movl $$1, $0", "=*m,X,~{dirflag},~{fpsr},~{flags}"(i32* nonnull elementtype(i32) %v, i8* blockaddress(@foo, %out)) + define dso_local i32 @foo() { entry: diff --git a/llvm/test/Analysis/BasicAA/ptrmask.ll b/llvm/test/Analysis/BasicAA/ptrmask.ll index af5f274..b9041ad 100644 --- a/llvm/test/Analysis/BasicAA/ptrmask.ll +++ b/llvm/test/Analysis/BasicAA/ptrmask.ll @@ -2,24 +2,28 @@ %struct = type <{ [20 x i64] }> -; CHECK-LABEL: Function: test_noalias: 4 pointers, 1 call sites +; CHECK-LABEL: Function: test_noalias ; CHECK-NEXT: NoAlias: %struct* %ptr1, i64* %ptr2 ; CHECK-NEXT: NoAlias: %struct* %addr.ptr, i64* %ptr2 ; CHECK-NEXT: NoAlias: i64* %gep, i64* %ptr2 define void @test_noalias(%struct* noalias %ptr1, i64* %ptr2, i64 %offset) { entry: %addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928) + load %struct, %struct* %ptr1 + load %struct, %struct* %addr.ptr store i64 10, i64* %ptr2 %gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset store i64 1, i64* %gep, align 8 ret void } -; CHECK-NEXT: Function: test_alias: 4 pointers, 1 call sites +; CHECK-NEXT: Function: test_alias ; CHECK-NOT: NoAlias define void @test_alias(%struct* %ptr1, i64* %ptr2, i64 %offset) { entry: %addr.ptr = call %struct* @llvm.ptrmask.p0s_struct.p0s.struct.i64(%struct* %ptr1, i64 72057594037927928) + load %struct, %struct* %ptr1 + load %struct, %struct* %addr.ptr store i64 10, i64* %ptr2 %gep = getelementptr inbounds %struct, %struct* %addr.ptr, i64 0, i32 0, i64 %offset store i64 1, i64* %gep, align 8 diff --git a/llvm/test/Analysis/BasicAA/q.bad.ll b/llvm/test/Analysis/BasicAA/q.bad.ll index 78559d3..0d2dbb9 100644 --- a/llvm/test/Analysis/BasicAA/q.bad.ll +++ b/llvm/test/Analysis/BasicAA/q.bad.ll @@ -11,6 +11,8 @@ define void @test_zext_sext_amounts255(i8* %mem) { %sext.zext.2 = zext i32 %sext.2 to i64 %a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1 %b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2 + load i8, i8* %a + load i8, i8* %b ret void } @@ -25,6 +27,8 @@ define void @test_zext_sext_amounts(i8* %mem, i8 %num) { %sext.zext.2 = zext i32 %sext.2 to i64 %a = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.1 %b = getelementptr inbounds i8, i8* %mem, i64 %sext.zext.2 + load i8, i8* %a + load i8, i8* %b ret void } @@ -40,6 +44,9 @@ define void @based_on_pr18068(i32 %loaded, i8* %mem) { %a = getelementptr inbounds i8, i8* %mem, i64 %loaded.64 %b = getelementptr inbounds i8, i8* %mem, i64 %add1.64 %c = getelementptr inbounds i8, i8* %mem, i64 %sub1.64 + load i8, i8* %a + load i8, i8* %b + load i8, i8* %c ret void } @@ -65,6 +72,10 @@ define void @test_path_dependence(i16 %p, i8* %mem) { %b = getelementptr inbounds i8, i8* %mem, i64 %p.64.again %c = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.nuw.64.again %d = getelementptr inbounds i8, i8* %mem, i64 %p.nsw.64.again + load i8, i8* %a + load i8, i8* %b + load i8, i8* %c + load i8, i8* %d ret void } @@ -79,6 +90,8 @@ define void @test_zext_sext_255(i8* %mem) { %zext.sext.zext.255 = zext i32 %sext.zext.255 to i64 %a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.255 %b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.255 + load i8, i8* %a + load i8, i8* %b ret void } @@ -94,6 +107,8 @@ define void @test_zext_sext_num(i8* %mem, i8 %num) { %zext.sext.zext.num = zext i32 %sext.zext.num to i64 %a = getelementptr inbounds i8, i8* %mem, i64 %zext.zext.sext.num %b = getelementptr inbounds i8, i8* %mem, i64 %zext.sext.zext.num + load i8, i8* %a + load i8, i8* %b ret void } @@ -106,6 +121,9 @@ define void @uncompressStream(i8* %mem) { %a = getelementptr inbounds i8, i8* %mem, i32 255 %b = getelementptr inbounds i8, i8* %mem, i32 %zext.255 %c = getelementptr inbounds i8, i8* %mem, i32 %sext.255 + load i8, i8* %a + load i8, i8* %b + load i8, i8* %c ret void } @@ -122,6 +140,9 @@ define void @constantOffsetHeuristic_i3_i32(i32* %mem, i3 %val) { %a = getelementptr inbounds i32, i32* %mem, i32 %zext.4 %b = getelementptr inbounds i32, i32* %mem, i32 %zext.7 %c = getelementptr inbounds i32, i32* %mem, i32 %zext.val + load i32, i32* %a + load i32, i32* %b + load i32, i32* %c ret void } @@ -138,6 +159,9 @@ define void @constantOffsetHeuristic_i8_i32(i32* %mem, i8 %val) { %a = getelementptr inbounds i32, i32* %mem, i32 %zext.4 %b = getelementptr inbounds i32, i32* %mem, i32 %zext.7 %c = getelementptr inbounds i32, i32* %mem, i32 %zext.val + load i32, i32* %a + load i32, i32* %b + load i32, i32* %c ret void } @@ -157,6 +181,9 @@ define void @constantOffsetHeuristic_i3_i8(i8* %mem, i3 %val) { %a = bitcast i8* %a.8 to i32* %b = bitcast i8* %b.8 to i32* %c = bitcast i8* %c.8 to i32* + load i32, i32* %a + load i32, i32* %b + load i32, i32* %c ret void } @@ -176,6 +203,9 @@ define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) { %a = bitcast i8* %a.8 to i32* %b = bitcast i8* %b.8 to i32* %c = bitcast i8* %c.8 to i32* + load i32, i32* %a + load i32, i32* %b + load i32, i32* %c ret void } @@ -184,5 +214,7 @@ define void @constantOffsetHeuristic_i8_i8(i8* %mem, i8 %val) { define void @different_large_bitwidths(i8* %a, i64 %i, i128 %j) { %p1 = getelementptr i8, i8* %a, i64 %i %p2 = getelementptr i8, i8* %a, i128 %j + load i8, i8* %p1 + load i8, i8* %p2 ret void } diff --git a/llvm/test/Analysis/BasicAA/range.ll b/llvm/test/Analysis/BasicAA/range.ll index 9d129e0..7235bef 100644 --- a/llvm/test/Analysis/BasicAA/range.ll +++ b/llvm/test/Analysis/BasicAA/range.ll @@ -8,6 +8,8 @@ define void @t1(%struct.S* %s) { %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1 %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0 + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -17,6 +19,8 @@ define void @t2_fwd(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0 + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -26,6 +30,8 @@ define void @t2_rev(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 0 %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -35,6 +41,8 @@ define void @t3_fwd(%struct.S* %s, i32* %q) { %knownzero = load i32, i32* %q, !range !1 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1 + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -44,6 +52,8 @@ define void @t3_rev(%struct.S* %s, i32* %q) { %knownzero = load i32, i32* %q, !range !1 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 1 %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %knownzero + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -53,6 +63,8 @@ define void @member_after(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2 + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -62,6 +74,8 @@ define void @member_after_rev(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 2 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -71,6 +85,8 @@ define void @member_before(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0 + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -80,101 +96,104 @@ define void @member_before_rev(%struct.S* %s, i32* %q) { %in_array = load i32, i32* %q, !range !0 %gep2 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0 %gep1 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 1, i32 %in_array + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t5 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 4): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t5 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s +; CHECK: NoAlias: i32* %gep1, i32* %gep2 define void @t5(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !3 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0 + load %struct.S2, %struct.S2* %s + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t6 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 16): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t6 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -16): i32* %gep2, %struct.S2* %s +; CHECK: MayAlias: i32* %gep1, i32* %gep2 define void @t6(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !3 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 3 + load %struct.S2, %struct.S2* %s + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t7 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 20): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t7 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s +; CHECK: NoAlias: i32* %gep1, i32* %gep2 define void @t7(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !4 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0 + load %struct.S2, %struct.S2* %s + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t8 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 24): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t8 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -24): i32* %gep2, %struct.S2* %s +; CHECK: MayAlias: i32* %gep1, i32* %gep2 define void @t8(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !4 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 1 + load %struct.S2, %struct.S2* %s + load i32, i32* %q + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t9 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 20): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: NoAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t9 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -20): i32* %gep2, %struct.S2* %s +; CHECK: NoAlias: i32* %gep1, i32* %gep2 define void @t9(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !5 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 0 + load %struct.S2, %struct.S2* %s + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: t10 -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %q -; CHECK-NEXT: MayAlias: %struct.S2* %s, i32* %gep1 -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %q -; CHECK-NEXT: PartialAlias (off 4): %struct.S2* %s, i32* %gep2 -; CHECK-NEXT: MayAlias: i32* %gep2, i32* %q -; CHECK-NEXT: MayAlias: i32* %gep1, i32* %gep2 +; CHECK-LABEL: Function: t10 +; CHECK: MayAlias: i32* %gep1, %struct.S2* %s +; CHECK: PartialAlias (off -4): i32* %gep2, %struct.S2* %s +; CHECK: MayAlias: i32* %gep1, i32* %gep2 define void @t10(%struct.S2* %s, i32* %q) { %in_array = load i32, i32* %q, !range !5 %gep1 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 2, i32 %in_array %gep2 = getelementptr inbounds %struct.S2, %struct.S2* %s, i64 0, i32 1, i32 0 + load %struct.S2, %struct.S2* %s + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } -; CHECK: Function: zeroext_index -; CHECK-NEXT: MayAlias: [256 x i32]* %s, i8* %q -; CHECK-NEXT: MayAlias: [256 x i32]* %s, i32* %gep -; CHECK-NEXT: MayAlias: i32* %gep, i8* %q +; CHECK-LABEL: Function: zeroext_index +; CHECK: MayAlias: i32* %gep, [256 x i32]* %s define void @zeroext_index([256 x i32]* %s, i8* %q) { %a = load i8, i8* %q, !range !6 %in_array = zext i8 %a to i32 %gep = getelementptr inbounds [256 x i32], [256 x i32]* %s, i64 0, i32 %in_array + load [256 x i32], [256 x i32]* %s + load i32, i32* %gep ret void } @@ -193,6 +212,11 @@ define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) { %p.02 = getelementptr i32, i32* %p.01, i32 %o2 ; p + [0, 2] %p.2 = getelementptr i32, i32* %p, i32 2 %p.3 = getelementptr i32, i32* %p, i32 3 + load i32, i32* %p + load i32, i32* %p.01 + load i32, i32* %p.02 + load i32, i32* %p.2 + load i32, i32* %p.3 ret void } @@ -210,6 +234,10 @@ define void @benign_overflow(i8* %p, i64 %o) { %p.neg1 = getelementptr i8, i8* %p, i64 -1 %p.o = getelementptr i8, i8* %p, i64 %o %p.o.1 = getelementptr i8, i8* %p.o, i64 1 + load i8, i8* %p + load i8, i8* %p.neg1 + load i8, i8* %p.o + load i8, i8* %p.o.1 ret void } diff --git a/llvm/test/Analysis/BasicAA/recphi.ll b/llvm/test/Analysis/BasicAA/recphi.ll index ea1d2a1..cc9b573 100644 --- a/llvm/test/Analysis/BasicAA/recphi.ll +++ b/llvm/test/Analysis/BasicAA/recphi.ll @@ -14,6 +14,8 @@ ; CHECK: NoAlias: float* %g, float* %next define void @simple(float *%src1, float * noalias %src2, i32 %n) nounwind { entry: + load float, float* %src1 + load float, float* %src2 br label %loop loop: @@ -22,6 +24,7 @@ loop: %next = getelementptr inbounds float, float* %phi, i32 1 %g = getelementptr inbounds float, float* %src1, i32 3 %l = load float, float* %phi + load float, float* %next %a = fadd float %l, 1.0 store float %a, float* %g %idxn = add nsw nuw i32 %idx, 1 @@ -33,25 +36,27 @@ end: } ; CHECK-LABEL: Function: notmust: 6 pointers, 0 call sites -; CHECK: MustAlias: [2 x i32]* %tab, i8* %0 -; CHECK: PartialAlias (off 4): [2 x i32]* %tab, i32* %arrayidx -; CHECK: NoAlias: i32* %arrayidx, i8* %0 -; CHECK: MustAlias: [2 x i32]* %tab, i32* %arrayidx1 -; CHECK: MustAlias: i32* %arrayidx1, i8* %0 -; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1 -; CHECK: MayAlias: [2 x i32]* %tab, i32* %p.addr.05.i -; CHECK: MayAlias: i32* %p.addr.05.i, i8* %0 -; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i -; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i -; CHECK: MayAlias: [2 x i32]* %tab, i32* %incdec.ptr.i -; CHECK: NoAlias: i32* %incdec.ptr.i, i8* %0 -; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i -; CHECK: NoAlias: i32* %arrayidx1, i32* %incdec.ptr.i -; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i +; CHECK: MustAlias: i8* %0, [2 x i32]* %tab +; CHECK: PartialAlias (off -4): i32* %arrayidx, [2 x i32]* %tab +; CHECK: NoAlias: i8* %0, i32* %arrayidx +; CHECK: MustAlias: i32* %arrayidx1, [2 x i32]* %tab +; CHECK: MustAlias: i8* %0, i32* %arrayidx1 +; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1 +; CHECK: MayAlias: i32* %incdec.ptr.i, [2 x i32]* %tab +; CHECK: NoAlias: i8* %0, i32* %incdec.ptr.i +; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i +; CHECK: NoAlias: i32* %arrayidx1, i32* %incdec.ptr.i +; CHECK: MayAlias: i32* %p.addr.05.i, [2 x i32]* %tab +; CHECK: MayAlias: i8* %0, i32* %p.addr.05.i +; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i +; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i +; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i define i32 @notmust() nounwind { entry: %tab = alloca [2 x i32], align 4 + %ignore1 = load [2 x i32], [2 x i32]* %tab %0 = bitcast [2 x i32]* %tab to i8* + %ignore2 = load i8, i8* %0 %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %tab, i32 0, i32 1 store i32 0, i32* %arrayidx, align 4 %arrayidx1 = getelementptr inbounds [2 x i32], [2 x i32]* %tab, i32 0, i32 0 @@ -66,6 +71,7 @@ while.body.i: ; preds = %while.body.i, %entry %p.addr.05.i = phi i32* [ %incdec.ptr.i, %while.body.i ], [ %arrayidx1, %entry ] %sub.i = sub nsw i32 %foo.06.i, %2 %incdec.ptr.i = getelementptr inbounds i32, i32* %p.addr.05.i, i32 1 + %ignore3 = load i32, i32* %incdec.ptr.i store i32 %sub.i, i32* %p.addr.05.i, align 4 %cmp.i = icmp sgt i32 %sub.i, 1 br i1 %cmp.i, label %while.body.i, label %f.exit @@ -86,25 +92,27 @@ if.end: ; preds = %f.exit } ; CHECK-LABEL: Function: reverse: 6 pointers, 0 call sites -; CHECK: MustAlias: [10 x i32]* %tab, i8* %0 -; CHECK: MustAlias: [10 x i32]* %tab, i32* %arrayidx -; CHECK: MustAlias: i32* %arrayidx, i8* %0 -; CHECK: PartialAlias (off 36): [10 x i32]* %tab, i32* %arrayidx1 -; CHECK: NoAlias: i32* %arrayidx1, i8* %0 -; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1 -; CHECK: MayAlias: [10 x i32]* %tab, i32* %p.addr.05.i -; CHECK: MayAlias: i32* %p.addr.05.i, i8* %0 -; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i -; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i -; CHECK: MayAlias: [10 x i32]* %tab, i32* %incdec.ptr.i -; CHECK: MayAlias: i32* %incdec.ptr.i, i8* %0 -; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i -; CHECK: MayAlias: i32* %arrayidx1, i32* %incdec.ptr.i -; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i +; CHECK: MustAlias: i8* %0, [10 x i32]* %tab +; CHECK: MustAlias: i32* %arrayidx, [10 x i32]* %tab +; CHECK: MustAlias: i8* %0, i32* %arrayidx +; CHECK: PartialAlias (off -36): i32* %arrayidx1, [10 x i32]* %tab +; CHECK: NoAlias: i8* %0, i32* %arrayidx1 +; CHECK: NoAlias: i32* %arrayidx, i32* %arrayidx1 +; CHECK: MayAlias: i32* %incdec.ptr.i, [10 x i32]* %tab +; CHECK: MayAlias: i8* %0, i32* %incdec.ptr.i +; CHECK: MayAlias: i32* %arrayidx, i32* %incdec.ptr.i +; CHECK: MayAlias: i32* %arrayidx1, i32* %incdec.ptr.i +; CHECK: MayAlias: i32* %p.addr.05.i, [10 x i32]* %tab +; CHECK: MayAlias: i8* %0, i32* %p.addr.05.i +; CHECK: MayAlias: i32* %arrayidx, i32* %p.addr.05.i +; CHECK: MayAlias: i32* %arrayidx1, i32* %p.addr.05.i +; CHECK: NoAlias: i32* %incdec.ptr.i, i32* %p.addr.05.i define i32 @reverse() nounwind { entry: %tab = alloca [10 x i32], align 4 + %ignore1 = load [10 x i32], [10 x i32]* %tab %0 = bitcast [10 x i32]* %tab to i8* + %ignore2 = load i8, i8* %0 %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %tab, i32 0, i32 0 store i32 0, i32* %arrayidx, align 4 %arrayidx1 = getelementptr inbounds [10 x i32], [10 x i32]* %tab, i32 0, i32 9 @@ -119,6 +127,7 @@ while.body.i: ; preds = %while.body.i, %entry %p.addr.05.i = phi i32* [ %incdec.ptr.i, %while.body.i ], [ %arrayidx1, %entry ] %sub.i = sub nsw i32 %foo.06.i, %2 %incdec.ptr.i = getelementptr inbounds i32, i32* %p.addr.05.i, i32 -1 + %ignore3 = load i32, i32* %incdec.ptr.i store i32 %sub.i, i32* %p.addr.05.i, align 4 %cmp.i = icmp sgt i32 %sub.i, 1 br i1 %cmp.i, label %while.body.i, label %f.exit @@ -138,31 +147,27 @@ if.end: ; preds = %f.exit ret i32 0 } -; CHECK-LABEL: Function: negative: 6 pointers, 1 call sites -; CHECK: NoAlias: [3 x i16]* %int_arr.10, i16** %argv.6.par -; CHECK: NoAlias: i16* %_tmp1, i16** %argv.6.par -; CHECK: PartialAlias (off 4): [3 x i16]* %int_arr.10, i16* %_tmp1 -; CHECK: NoAlias: i16* %ls1.9.0, i16** %argv.6.par -; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0 -; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0 -; CHECK: NoAlias: i16* %_tmp7, i16** %argv.6.par -; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %_tmp7 -; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7 -; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0 -; CHECK: NoAlias: i16* %_tmp11, i16** %argv.6.par -; CHECK: PartialAlias (off 2): [3 x i16]* %int_arr.10, i16* %_tmp11 -; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11 -; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0 -; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7 -; CHECK: Both ModRef: Ptr: i16** %argv.6.par <-> %_tmp16 = call i16 @call(i32 %_tmp13) -; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13) -; CHECK: NoModRef: Ptr: i16* %_tmp1 <-> %_tmp16 = call i16 @call(i32 %_tmp13) -; CHECK: Both ModRef: Ptr: i16* %ls1.9.0 <-> %_tmp16 = call i16 @call(i32 %_tmp13) -; CHECK: Both ModRef: Ptr: i16* %_tmp7 <-> %_tmp16 = call i16 @call(i32 %_tmp13) -; CHECK: NoModRef: Ptr: i16* %_tmp11 <-> %_tmp16 = call i16 @call(i32 %_tmp13) -define i16 @negative(i16 %argc.5.par, i16** nocapture readnone %argv.6.par) { +; CHECK-LABEL: Function: negative: 5 pointers, 1 call sites +; CHECK: PartialAlias (off -4): i16* %_tmp1, [3 x i16]* %int_arr.10 +; CHECK: MayAlias: [3 x i16]* %int_arr.10, i16* %ls1.9.0 +; CHECK: MayAlias: i16* %_tmp1, i16* %ls1.9.0 +; CHECK: MayAlias: i16* %_tmp7, [3 x i16]* %int_arr.10 +; CHECK: MayAlias: i16* %_tmp1, i16* %_tmp7 +; CHECK: NoAlias: i16* %_tmp7, i16* %ls1.9.0 +; CHECK: PartialAlias (off -2): i16* %_tmp11, [3 x i16]* %int_arr.10 +; CHECK: NoAlias: i16* %_tmp1, i16* %_tmp11 +; CHECK: MayAlias: i16* %_tmp11, i16* %ls1.9.0 +; CHECK: MayAlias: i16* %_tmp11, i16* %_tmp7 +; CHECK: NoModRef: Ptr: [3 x i16]* %int_arr.10 <-> %_tmp16 = call i16 @call(i32 %_tmp13) +; CHECK: NoModRef: Ptr: i16* %_tmp1 <-> %_tmp16 = call i16 @call(i32 %_tmp13) +; CHECK: Both ModRef: Ptr: i16* %ls1.9.0 <-> %_tmp16 = call i16 @call(i32 %_tmp13) +; CHECK: Both ModRef: Ptr: i16* %_tmp7 <-> %_tmp16 = call i16 @call(i32 %_tmp13) +; CHECK: NoModRef: Ptr: i16* %_tmp11 <-> %_tmp16 = call i16 @call(i32 %_tmp13) +define i16 @negative(i16 %argc.5.par) { %int_arr.10 = alloca [3 x i16], align 1 + load [3 x i16], [3 x i16]* %int_arr.10 %_tmp1 = getelementptr inbounds [3 x i16], [3 x i16]* %int_arr.10, i16 0, i16 2 + load i16, i16* %_tmp1 br label %bb1 bb1: ; preds = %bb1, %0 @@ -171,6 +176,7 @@ bb1: ; preds = %bb1, %0 store i16 %i.7.0, i16* %ls1.9.0, align 1 %_tmp5 = add nsw i16 %i.7.0, -1 %_tmp7 = getelementptr i16, i16* %ls1.9.0, i16 -1 + load i16, i16* %_tmp7 %_tmp9 = icmp sgt i16 %i.7.0, 0 br i1 %_tmp9, label %bb1, label %bb3 @@ -199,12 +205,16 @@ bb5: ; preds = %bb3, %bb4 define void @dynamic_offset(i1 %c, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %loop loop: %p = phi i8* [ %p.base, %entry ], [ %p.next, %loop ] %offset = call i16 @call(i32 0) %p.next = getelementptr inbounds i8, i8* %p, i16 %offset + load i8, i8* %p + load i8, i8* %p.next br i1 %c, label %loop, label %exit exit: @@ -221,41 +231,51 @@ exit: ; CHECK: MustAlias: i32* %p.next, i32* %result define i32* @symmetry(i32* %p.base, i1 %c) { entry: + load i32, i32* %p.base br label %loop loop: %p = phi i32* [ %p.base, %entry ], [ %p.next, %loop ] %p.next = getelementptr inbounds i32, i32* %p, i32 1 + load i32, i32* %p + load i32, i32* %p.next br i1 %c, label %loop, label %exit exit: %result = phi i32* [ %p.next, %loop ] + load i32, i32* %result ret i32* %result } ; CHECK-LABEL: Function: nested_loop ; CHECK: NoAlias: i8* %a, i8* %p.base ; CHECK: NoAlias: i8* %a, i8* %p.outer -; CHECK: NoAlias: i8* %a, i8* %p.outer.next ; NO-PHI-VALUES: MayAlias: i8* %a, i8* %p.inner ; PHI-VALUES: NoAlias: i8* %a, i8* %p.inner ; CHECK: NoAlias: i8* %a, i8* %p.inner.next +; CHECK: NoAlias: i8* %a, i8* %p.outer.next define void @nested_loop(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %outer_loop outer_loop: %p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ] + load i8, i8* %p.outer br label %inner_loop inner_loop: %p.inner = phi i8* [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ] %p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1 + load i8, i8* %p.inner + load i8, i8* %p.inner.next br i1 %c, label %inner_loop, label %outer_loop_latch outer_loop_latch: %p.outer.next = getelementptr inbounds i8, i8* %p.inner, i64 10 + load i8, i8* %p.outer.next br i1 %c2, label %outer_loop, label %exit exit: @@ -273,16 +293,22 @@ exit: define void @nested_loop2(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %outer_loop outer_loop: %p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ] %p.outer.next = getelementptr inbounds i8, i8* %p.outer, i64 10 + load i8, i8* %p.outer + load i8, i8* %p.outer.next br label %inner_loop inner_loop: %p.inner = phi i8* [ %p.outer.next, %outer_loop ], [ %p.inner.next, %inner_loop ] %p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1 + load i8, i8* %p.inner + load i8, i8* %p.inner.next br i1 %c, label %inner_loop, label %outer_loop_latch outer_loop_latch: @@ -302,16 +328,22 @@ exit: define void @nested_loop3(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %outer_loop outer_loop: %p.outer = phi i8* [ %p.base, %entry ], [ %p.outer.next, %outer_loop_latch ] %p.outer.next = getelementptr inbounds i8, i8* %p.outer, i64 10 + load i8, i8* %p.outer + load i8, i8* %p.outer.next br label %inner_loop inner_loop: %p.inner = phi i8* [ %p.outer, %outer_loop ], [ %p.inner.next, %inner_loop ] %p.inner.next = getelementptr inbounds i8, i8* %p.inner, i64 1 + load i8, i8* %p.inner + load i8, i8* %p.inner.next br i1 %c, label %inner_loop, label %outer_loop_latch outer_loop_latch: @@ -331,16 +363,22 @@ exit: define void @sibling_loop(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %loop1 loop1: %p1 = phi i8* [ %p.base, %entry ], [ %p1.next, %loop1 ] %p1.next = getelementptr inbounds i8, i8* %p1, i64 10 + load i8, i8* %p1 + load i8, i8* %p1.next br i1 %c, label %loop1, label %loop2 loop2: %p2 = phi i8* [ %p1.next, %loop1 ], [ %p2.next, %loop2 ] %p2.next = getelementptr inbounds i8, i8* %p2, i64 1 + load i8, i8* %p2 + load i8, i8* %p2.next br i1 %c2, label %loop2, label %exit exit: @@ -357,16 +395,22 @@ exit: define void @sibling_loop2(i1 %c, i1 %c2, i8* noalias %p.base) { entry: %a = alloca i8 + load i8, i8* %p.base + load i8, i8* %a br label %loop1 loop1: %p1 = phi i8* [ %p.base, %entry ], [ %p1.next, %loop1 ] %p1.next = getelementptr inbounds i8, i8* %p1, i64 10 + load i8, i8* %p1 + load i8, i8* %p1.next br i1 %c, label %loop1, label %loop2 loop2: %p2 = phi i8* [ %p1, %loop1 ], [ %p2.next, %loop2 ] %p2.next = getelementptr inbounds i8, i8* %p2, i64 1 + load i8, i8* %p2 + load i8, i8* %p2.next br i1 %c2, label %loop2, label %exit exit: diff --git a/llvm/test/Analysis/BasicAA/returned.ll b/llvm/test/Analysis/BasicAA/returned.ll index 58c0c7b..934a5481d 100644 --- a/llvm/test/Analysis/BasicAA/returned.ll +++ b/llvm/test/Analysis/BasicAA/returned.ll @@ -17,14 +17,14 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK-DAG: NoAlias: i32* %y, i32* %z ; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12 -; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x +; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12 ; CHECK-DAG: MayAlias: i32* %x, i80* %y_10 ; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8 -; CHECK-DAG: MayAlias: i32* %z, i64* %y_8 +; CHECK-DAG: MayAlias: i64* %y_8, i32* %z ; CHECK-DAG: NoAlias: i32* %x, i64* %y_8 -; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y +; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12 ; CHECK-DAG: MustAlias: i32* %y, i64* %y_8 ; CHECK-DAG: MustAlias: i32* %y, i80* %y_10 @@ -37,6 +37,14 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) { %y_10 = bitcast i32* %y to i80* %ya = call i32* @func1(i32* %y) %y_8 = bitcast i32* %ya to i64* + load %struct, %struct* %st + load %struct, %struct* %sta + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load %struct, %struct* %y_12 + load i80, i80* %y_10 + load i64, i64* %y_8 ret void } diff --git a/llvm/test/Analysis/BasicAA/sequential-gep.ll b/llvm/test/Analysis/BasicAA/sequential-gep.ll index fce331a..1b607f2 100644 --- a/llvm/test/Analysis/BasicAA/sequential-gep.ll +++ b/llvm/test/Analysis/BasicAA/sequential-gep.ll @@ -7,6 +7,8 @@ define void @t1([8 x i32]* %p, i32 %addend, i32* %q) { %add = add nsw nuw i32 %addend, %knownnonzero %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -17,6 +19,8 @@ define void @t2([8 x i32]* %p, i32 %addend, i32* %q) { %add = add nsw nuw i32 %addend, %knownnonzero %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -27,6 +31,8 @@ define void @t3([8 x i32]* %p, i32 %addend, i32* %q) { %add = add nsw nuw i32 %addend, %knownnonzero %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 0, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -37,17 +43,21 @@ define void @t4([8 x i32]* %p, i32 %addend, i32* %q) { %add = add nsw nuw i32 %addend, %knownnonzero %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 1, i32 %addend %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 %add, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } ; CHECK: Function: t5 -; CHECK: MayAlias: i32* %gep2, i64* %bc +; CHECK: MayAlias: i64* %bc, i32* %gep2 define void @t5([8 x i32]* %p, i32 %addend, i32* %q) { %knownnonzero = load i32, i32* %q, !range !0 %add = add nsw nuw i32 %addend, %knownnonzero %gep1 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %addend %gep2 = getelementptr [8 x i32], [8 x i32]* %p, i32 2, i32 %add %bc = bitcast i32* %gep1 to i64* + load i32, i32* %gep2 + load i64, i64* %bc ret void } @@ -58,26 +68,30 @@ define void @add_non_zero_simple(i32* %p, i32 %addend, i32* %q) { %add = add i32 %addend, %knownnonzero %gep1 = getelementptr i32, i32* %p, i32 %addend %gep2 = getelementptr i32, i32* %p, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } ; CHECK-LABEL: Function: add_non_zero_different_scales -; CHECK: MayAlias: i16* %gep2, i32* %gep1 +; CHECK: MayAlias: i32* %gep1, i16* %gep2 define void @add_non_zero_different_scales(i32* %p, i32 %addend, i32* %q) { %knownnonzero = load i32, i32* %q, !range !0 %add = add i32 %addend, %knownnonzero %p16 = bitcast i32* %p to i16* %gep1 = getelementptr i32, i32* %p, i32 %addend %gep2 = getelementptr i16, i16* %p16, i32 %add + load i32, i32* %gep1 + load i16, i16* %gep2 ret void } ; CHECK-LABEL: Function: add_non_zero_different_sizes ; CHECK: NoAlias: i16* %gep1.16, i32* %gep2 -; CHECK: NoAlias: i16* %gep2.16, i32* %gep1 +; CHECK: NoAlias: i32* %gep1, i16* %gep2.16 ; CHECK: NoAlias: i16* %gep1.16, i16* %gep2.16 -; CHECK: MayAlias: i32* %gep2, i64* %gep1.64 -; CHECK: MayAlias: i16* %gep2.16, i64* %gep1.64 +; CHECK: MayAlias: i64* %gep1.64, i32* %gep2 +; CHECK: MayAlias: i64* %gep1.64, i16* %gep2.16 ; CHECK: MayAlias: i32* %gep1, i64* %gep2.64 ; CHECK: MayAlias: i16* %gep1.16, i64* %gep2.64 ; CHECK: MayAlias: i64* %gep1.64, i64* %gep2.64 @@ -90,6 +104,12 @@ define void @add_non_zero_different_sizes(i32* %p, i32 %addend, i32* %q) { %gep2.16 = bitcast i32* %gep2 to i16* %gep1.64 = bitcast i32* %gep1 to i64* %gep2.64 = bitcast i32* %gep2 to i64* + load i32, i32* %gep1 + load i32, i32* %gep2 + load i16, i16* %gep1.16 + load i16, i16* %gep2.16 + load i64, i64* %gep1.64 + load i64, i64* %gep2.64 ret void } @@ -107,6 +127,10 @@ define void @add_non_zero_with_offset(i32* %p, i32 %addend, i32* %q) { %gep2 = getelementptr i32, i32* %p, i32 %add %gep1.16 = bitcast i32* %gep1 to i16* %gep2.16 = bitcast i32* %gep2 to i16* + load i32, i32* %gep1 + load i32, i32* %gep2 + load i16, i16* %gep1.16 + load i16, i16* %gep2.16 ret void } @@ -118,23 +142,29 @@ define void @add_non_zero_assume(i32* %p, i32 %addend, i32 %knownnonzero) { %add = add i32 %addend, %knownnonzero %gep1 = getelementptr i32, i32* %p, i32 %addend %gep2 = getelementptr i32, i32* %p, i32 %add + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } ; CHECK-LABEL: non_zero_index_simple ; CHECK: NoAlias: i32* %gep, i32* %p ; CHECK: NoAlias: i16* %gep.16, i32* %p -; CHECK: MayAlias: i32* %p, i64* %gep.64 +; CHECK: MayAlias: i64* %gep.64, i32* %p define void @non_zero_index_simple(i32* %p, i32* %q) { %knownnonzero = load i32, i32* %q, !range !0 %gep = getelementptr i32, i32* %p, i32 %knownnonzero %gep.16 = bitcast i32* %gep to i16* %gep.64 = bitcast i32* %gep to i64* + load i32, i32* %p + load i32, i32* %gep + load i16, i16* %gep.16 + load i64, i64* %gep.64 ret void } ; CHECK-LABEL: non_zero_index_with_offset -; CHECK: NoAlias: i32* %gep, i32* %p +; CHECK: MayAlias: i32* %gep, i32* %p ; CHECK: NoAlias: i16* %gep.16, i32* %p define void @non_zero_index_with_offset(i32* %p, i32* %q) { %knownnonzero = load i32, i32* %q, !range !0 @@ -143,6 +173,9 @@ define void @non_zero_index_with_offset(i32* %p, i32* %q) { %p.off = bitcast i8* %p.off.8 to i32* %gep = getelementptr i32, i32* %p.off, i32 %knownnonzero %gep.16 = bitcast i32* %gep to i16* + load i32, i32* %p + load i32, i32* %gep + load i16, i16* %gep.16 ret void } @@ -152,6 +185,8 @@ define void @non_zero_index_assume(i32* %p, i32 %knownnonzero) { %cmp = icmp ne i32 %knownnonzero, 0 call void @llvm.assume(i1 %cmp) %gep = getelementptr i32, i32* %p, i32 %knownnonzero + load i32, i32* %p + load i32, i32* %gep ret void } diff --git a/llvm/test/Analysis/BasicAA/struct-geps.ll b/llvm/test/Analysis/BasicAA/struct-geps.ll index 9c97098..6cffe0c 100644 --- a/llvm/test/Analysis/BasicAA/struct-geps.ll +++ b/llvm/test/Analysis/BasicAA/struct-geps.ll @@ -15,14 +15,14 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK-DAG: NoAlias: i32* %y, i32* %z ; CHECK-DAG: MayAlias: %struct* %st, %struct* %y_12 -; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x +; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12 ; CHECK-DAG: MayAlias: i32* %x, i80* %y_10 ; CHECK-DAG: MayAlias: %struct* %st, i64* %y_8 -; CHECK-DAG: MayAlias: i32* %z, i64* %y_8 +; CHECK-DAG: MayAlias: i64* %y_8, i32* %z ; CHECK-DAG: NoAlias: i32* %x, i64* %y_8 -; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y +; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12 ; CHECK-DAG: MustAlias: i32* %y, i64* %y_8 ; CHECK-DAG: MustAlias: i32* %y, i80* %y_10 @@ -33,6 +33,13 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) { %y_12 = bitcast i32* %y to %struct* %y_10 = bitcast i32* %y to i80* %y_8 = bitcast i32* %y to i64* + load %struct, %struct* %st + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load %struct, %struct* %y_12 + load i80, i80* %y_10 + load i64, i64* %y_8 ret void } @@ -42,6 +49,8 @@ define void @test_simple(%struct* %st, i64 %i, i64 %j, i64 %k) { define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) { %x = getelementptr %struct, %struct* %st, i64 %i, i32 0 %y = getelementptr %struct, %struct* %st, i64 %j, i32 1 + load i32, i32* %x + load i32, i32* %y ret void } @@ -55,15 +64,15 @@ define void @test_not_inbounds(%struct* %st, i64 %i, i64 %j, i64 %k) { ; CHECK-DAG: NoAlias: i32* %x, i32* %z ; CHECK-DAG: NoAlias: i32* %y, i32* %z -; CHECK-DAG: MayAlias: %struct* %y_12, [1 x %struct]* %st -; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x +; CHECK-DAG: MayAlias: [1 x %struct]* %st, %struct* %y_12 +; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12 ; CHECK-DAG: MayAlias: i32* %x, i80* %y_10 ; CHECK-DAG: MayAlias: [1 x %struct]* %st, i64* %y_8 -; CHECK-DAG: MayAlias: i32* %z, i64* %y_8 +; CHECK-DAG: MayAlias: i64* %y_8, i32* %z ; CHECK-DAG: NoAlias: i32* %x, i64* %y_8 -; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y +; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12 ; CHECK-DAG: MustAlias: i32* %y, i64* %y_8 ; CHECK-DAG: MustAlias: i32* %y, i80* %y_10 @@ -74,6 +83,13 @@ define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, %y_12 = bitcast i32* %y to %struct* %y_10 = bitcast i32* %y to i80* %y_8 = bitcast i32* %y to i64* + load [1 x %struct], [1 x %struct]* %st + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load %struct, %struct* %y_12 + load i80, i80* %y_10 + load i64, i64* %y_8 ret void } @@ -87,15 +103,15 @@ define void @test_in_array([1 x %struct]* %st, i64 %i, i64 %j, i64 %k, i64 %i1, ; CHECK-DAG: NoAlias: i32* %x, i32* %z ; CHECK-DAG: NoAlias: i32* %y, i32* %z -; CHECK-DAG: MayAlias: %struct* %y_12, [1 x [1 x [1 x %struct]]]* %st -; CHECK-DAG: MayAlias: %struct* %y_12, i32* %x +; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, %struct* %y_12 +; CHECK-DAG: MayAlias: i32* %x, %struct* %y_12 ; CHECK-DAG: MayAlias: i32* %x, i80* %y_10 ; CHECK-DAG: MayAlias: [1 x [1 x [1 x %struct]]]* %st, i64* %y_8 -; CHECK-DAG: MayAlias: i32* %z, i64* %y_8 +; CHECK-DAG: MayAlias: i64* %y_8, i32* %z ; CHECK-DAG: NoAlias: i32* %x, i64* %y_8 -; CHECK-DAG: MustAlias: %struct* %y_12, i32* %y +; CHECK-DAG: MustAlias: i32* %y, %struct* %y_12 ; CHECK-DAG: MustAlias: i32* %y, i64* %y_8 ; CHECK-DAG: MustAlias: i32* %y, i80* %y_10 @@ -106,6 +122,13 @@ define void @test_in_3d_array([1 x [1 x [1 x %struct]]]* %st, i64 %i, i64 %j, i6 %y_12 = bitcast i32* %y to %struct* %y_10 = bitcast i32* %y to i80* %y_8 = bitcast i32* %y to i64* + load [1 x [1 x [1 x %struct]]], [1 x [1 x [1 x %struct]]]* %st + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load %struct, %struct* %y_12 + load i80, i80* %y_10 + load i64, i64* %y_8 ret void } @@ -132,6 +155,12 @@ define void @test_same_underlying_object_same_indices(%struct* %st, i64 %i, i64 %x = getelementptr inbounds %struct, %struct* %st, i64 %i, i32 0 %y = getelementptr inbounds %struct, %struct* %st, i64 %j, i32 1 %z = getelementptr inbounds %struct, %struct* %st, i64 %k, i32 2 + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load i32, i32* %x2 + load i32, i32* %y2 + load i32, i32* %z2 ret void } @@ -158,6 +187,12 @@ define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1 %x = getelementptr inbounds %struct, %struct* %st, i64 %i1, i32 0 %y = getelementptr inbounds %struct, %struct* %st, i64 %j1, i32 1 %z = getelementptr inbounds %struct, %struct* %st, i64 %k1, i32 2 + load i32, i32* %x + load i32, i32* %y + load i32, i32* %z + load i32, i32* %x2 + load i32, i32* %y2 + load i32, i32* %z2 ret void } @@ -169,6 +204,8 @@ define void @test_same_underlying_object_different_indices(%struct* %st, i64 %i1 define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) { %x = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 1, i32 1, i32 0 %y = getelementptr inbounds %struct2, %struct2* %st, i32 0, i32 0, i32 1, i32 1 + load i32, i32* %x + load i32, i32* %y ret void } @@ -178,5 +215,7 @@ define void @test_struct_in_array(%struct2* %st, i64 %i, i64 %j, i64 %k) { define void @test_different_index_types([2 x i16]* %arr) { %tmp1 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i32 1 %tmp2 = getelementptr inbounds [2 x i16], [2 x i16]* %arr, i16 0, i16 1 + load i16, i16* %tmp1 + load i16, i16* %tmp2 ret void } diff --git a/llvm/test/Analysis/BasicAA/vscale.ll b/llvm/test/Analysis/BasicAA/vscale.ll index 1240c18..d26fc14 100644 --- a/llvm/test/Analysis/BasicAA/vscale.ll +++ b/llvm/test/Analysis/BasicAA/vscale.ll @@ -10,6 +10,9 @@ define void @gep_alloca_const_offset_1() { %alloc = alloca %gep1 = getelementptr , * %alloc, i64 0 %gep2 = getelementptr , * %alloc, i64 1 + load , * %alloc + load , * %gep1 + load , * %gep2 ret void } @@ -22,6 +25,9 @@ define void @gep_alloca_const_offset_2() { %alloc = alloca %gep1 = getelementptr , * %alloc, i64 1 %gep2 = getelementptr , * %alloc, i64 1 + load , * %alloc + load , * %gep1 + load , * %gep2 ret void } @@ -33,6 +39,9 @@ define void @gep_alloca_const_offset_3() { %alloc = alloca %gep1 = getelementptr , * %alloc, i64 0 %gep2 = getelementptr , * %alloc, i64 0, i64 1 + load , * %alloc + load , * %gep1 + load i32, i32* %gep2 ret void } @@ -44,6 +53,9 @@ define void @gep_alloca_const_offset_4() { %alloc = alloca %gep1 = getelementptr , * %alloc, i64 0 %gep2 = getelementptr , * %alloc, i64 0, i64 0 + load , * %alloc + load , * %gep1 + load i32, i32* %gep2 ret void } @@ -55,17 +67,23 @@ define void @gep_alloca_symbolic_offset(i64 %idx1, i64 %idx2) { %alloc = alloca %gep1 = getelementptr , * %alloc, i64 %idx1 %gep2 = getelementptr , * %alloc, i64 %idx2 + load , * %alloc + load , * %gep1 + load , * %gep2 ret void } ; CHECK-LABEL: gep_same_base_const_offset -; CHECK-DAG: MayAlias: * %p, i32* %gep1 -; CHECK-DAG: MayAlias: * %p, i32* %gep2 +; CHECK-DAG: MayAlias: i32* %gep1, * %p +; CHECK-DAG: MayAlias: i32* %gep2, * %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(* %p) { %gep1 = getelementptr , * %p, i64 1, i64 0 %gep2 = getelementptr , * %p, i64 1, i64 1 + load , * %p + load i32, i32* %gep1 + load i32, i32* %gep2 ret void } @@ -76,6 +94,9 @@ define void @gep_same_base_const_offset(* %p) { define void @gep_same_base_symbolic_offset(* %p, i64 %idx1, i64 %idx2) { %gep1 = getelementptr , * %p, i64 %idx1 %gep2 = getelementptr , * %p, i64 %idx2 + load , * %p + load , * %gep1 + load , * %gep2 ret void } @@ -89,6 +110,10 @@ define void @gep_same_base_symbolic_offset(* %p, i64 %idx1, i6 define void @gep_different_base_const_offset(* noalias %p1, * noalias %p2) { %gep1 = getelementptr , * %p1, i64 1 %gep2 = getelementptr , * %p2, i64 1 + load , * %p1 + load , * %p2 + load , * %gep1 + load , * %gep2 ret void } @@ -96,69 +121,85 @@ define void @gep_different_base_const_offset(* noalias %p1, * %p, i32* %p2 -; CHECK-DAG: MayAlias: * %p, i32* %gep1 +; CHECK-DAG: MayAlias: i32* %gep1, * %p ; CHECK-DAG: MayAlias: i32* %gep1, i32* %p2 -; CHECK-DAG: MayAlias: * %p, i32* %gep2 +; CHECK-DAG: MayAlias: i32* %gep2, * %p ; CHECK-DAG: MayAlias: i32* %gep1, i32* %gep2 ; CHECK-DAG: NoAlias: i32* %gep2, i32* %p2 define void @gep_bitcast_1(* %p) { %gep1 = getelementptr , * %p, i64 1, i64 0 %p2 = bitcast * %p to i32* %gep2 = getelementptr i32, i32* %p2, i64 4 + load , * %p + load i32, i32* %gep1 + load i32, i32* %gep2 + load i32, i32* %p2 ret void } ; CHECK-LABEL: gep_bitcast_2 -; CHECK-DAG: MustAlias: * %p2, * %p -; CHECK-DAG: MayAlias: * %p, i32* %gep1 -; CHECK-DAG: MayAlias: * %p2, i32* %gep1 -; CHECK-DAG: MayAlias: * %p, float* %gep2 -; CHECK-DAG: MayAlias: float* %gep2, i32* %gep1 -; CHECK-DAG: MayAlias: * %p2, float* %gep2 +; CHECK-DAG: MustAlias: * %p, * %p2 +; CHECK-DAG: MayAlias: i32* %gep1, * %p +; CHECK-DAG: MayAlias: i32* %gep1, * %p2 +; CHECK-DAG: MayAlias: float* %gep2, * %p +; CHECK-DAG: MayAlias: i32* %gep1, float* %gep2 +; CHECK-DAG: MayAlias: float* %gep2, * %p2 define void @gep_bitcast_2(* %p) { %gep1 = getelementptr , * %p, i64 1, i64 0 %p2 = bitcast * %p to * %gep2 = getelementptr , * %p2, i64 1, i64 0 + load i32, i32* %gep1 + load float, float* %gep2 + load , * %p + load , * %p2 ret void } ; getelementptr recursion ; CHECK-LABEL: gep_recursion_level_1 -; CHECK-DAG: MayAlias: * %p, i32* %a +; CHECK-DAG: MayAlias: i32* %a, * %p ; CHECK-DAG: MayAlias: i32* %a, i32* %gep ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: * %p, i32* %gep -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 +; CHECK-DAG: MayAlias: i32* %gep, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_1, * %p ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 define void @gep_recursion_level_1(i32* %a, * %p) { %gep = getelementptr , * %p, i64 1, i64 2 %gep_rec_1 = getelementptr i32, i32* %gep, i64 1 + load , * %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: * %p, i32* %a +; CHECK-DAG: MustAlias: i32* %a, * %p ; CHECK-DAG: MayAlias: i32* %a, i32* %gep ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: * %p, i32* %gep -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 +; CHECK-DAG: MayAlias: i32* %gep, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_1, * %p ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 define void @gep_recursion_level_1_bitcast(i32* %a) { %p = bitcast i32* %a to * %gep = getelementptr , * %p, i64 1, i64 2 %gep_rec_1 = getelementptr i32, i32* %gep, i64 1 + load , * %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: * %p, i32* %a +; CHECK-DAG: MayAlias: i32* %a, * %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: * %p, i32* %gep -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_2 +; CHECK-DAG: MayAlias: i32* %gep, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_1, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_2, * %p ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2 ; CHECK-DAG: NoAlias: i32* %gep_rec_1, i32* %gep_rec_2 @@ -166,11 +207,16 @@ define void @gep_recursion_level_2(i32* %a, * %p) { %gep = getelementptr , * %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 , * %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: * %p, i32* %a +; CHECK-DAG: MayAlias: i32* %a, * %p ; CHECK-DAG: MayAlias: i32* %a, i32* %gep ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_1 ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_2 @@ -178,13 +224,13 @@ define void @gep_recursion_level_2(i32* %a, * %p) { ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_4 ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_5 ; CHECK-DAG: MayAlias: i32* %a, i32* %gep_rec_6 -; CHECK-DAG: MayAlias: * %p, i32* %gep -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_1 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_2 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_3 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_4 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_5 -; CHECK-DAG: MayAlias: * %p, i32* %gep_rec_6 +; CHECK-DAG: MayAlias: i32* %gep, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_1, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_2, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_3, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_4, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_5, * %p +; CHECK-DAG: MayAlias: i32* %gep_rec_6, * %p ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_1 ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_2 ; CHECK-DAG: NoAlias: i32* %gep, i32* %gep_rec_3 @@ -215,5 +261,14 @@ define void @gep_recursion_max_lookup_depth_reached(i32* %a, * %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 , * %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 } diff --git a/llvm/test/Analysis/BasicAA/zext.ll b/llvm/test/Analysis/BasicAA/zext.ll index 0197106..0e271d8 100644 --- a/llvm/test/Analysis/BasicAA/zext.ll +++ b/llvm/test/Analysis/BasicAA/zext.ll @@ -11,6 +11,8 @@ define void @test_with_zext() { %2 = getelementptr inbounds i8, i8* %1, i64 16 %3 = zext i32 3 to i64 %b = getelementptr inbounds i8, i8* %2, i64 %3 + load i8, i8* %a + load i8, i8* %b ret void } @@ -23,19 +25,23 @@ define void @test_with_lshr(i64 %i) { %2 = getelementptr inbounds i8, i8* %1, i64 16 %3 = lshr i64 %i, 2 %b = getelementptr inbounds i8, i8* %2, i64 %3 + load i8, i8* %a + load i8, i8* %b ret void } ; CHECK-LABEL: test_with_lshr_different_sizes -; CHECK: NoAlias: i16* %m2.idx, i8* %m1 +; CHECK: NoAlias: i8* %m1, i16* %m2.idx define void @test_with_lshr_different_sizes(i64 %i) { %m0 = tail call i8* @malloc(i64 120) %m1 = getelementptr inbounds i8, i8* %m0, i64 1 + load i8, i8* %m1 %m2 = getelementptr inbounds i8, i8* %m0, i64 2 %idx = lshr i64 %i, 2 %m2.i16 = bitcast i8* %m2 to i16* %m2.idx = getelementptr inbounds i16, i16* %m2.i16, i64 %idx + load i16, i16* %m2.idx ret void } @@ -48,9 +54,11 @@ define void @test_with_a_loop(i8* %mem) { for.loop: %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ] %a = getelementptr inbounds i8, i8* %mem, i64 8 + load i8, i8* %a %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16 %i.64 = zext i32 %i to i64 %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64 + load i8, i8* %b %i.plus1 = add nuw nsw i32 %i, 1 %cmp = icmp eq i32 %i.plus1, 10 br i1 %cmp, label %for.loop.exit, label %for.loop @@ -69,9 +77,11 @@ for.loop: %mem = phi i8* [ %mem.orig, %0 ], [ %mem.plus1, %for.loop ] %i = phi i32 [ 0, %0 ], [ %i.plus1, %for.loop ] %a = getelementptr inbounds i8, i8* %mem, i64 8 + load i8, i8* %a %a.plus1 = getelementptr inbounds i8, i8* %mem, i64 16 %i.64 = zext i32 %i to i64 %b = getelementptr inbounds i8, i8* %a.plus1, i64 %i.64 + load i8, i8* %b %i.plus1 = add nuw nsw i32 %i, 1 %mem.plus1 = getelementptr inbounds i8, i8* %mem, i64 8 %cmp = icmp eq i32 %i.plus1, 10 @@ -82,16 +92,18 @@ for.loop.exit: } ; CHECK-LABEL: test_sign_extension -; CHECK: MayAlias: i64* %b.i64, i8* %a +; CHECK: MayAlias: i8* %a, i64* %b.i64 define void @test_sign_extension(i32 %p) { %1 = tail call i8* @malloc(i64 120) %p.64 = zext i32 %p to i64 %a = getelementptr inbounds i8, i8* %1, i64 %p.64 + load i8, i8* %a %p.minus1 = add i32 %p, -1 %p.minus1.64 = zext i32 %p.minus1 to i64 %b.i8 = getelementptr inbounds i8, i8* %1, i64 %p.minus1.64 %b.i64 = bitcast i8* %b.i8 to i64* + load i64, i64* %b.i64 ret void } @@ -105,12 +117,14 @@ for.loop: %i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ] %idxprom = zext i32 %i to i64 %b = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 %idxprom + load i32, i32* %b %i.next = add nuw nsw i32 %i, 1 - %1 = icmp eq i32 %i.next, 10 - br i1 %1, label %for.loop.exit, label %for.loop + %cmp = icmp eq i32 %i.next, 10 + br i1 %cmp, label %for.loop.exit, label %for.loop reorder: %a = getelementptr inbounds [8 x i32], [8 x i32]* %values, i64 0, i64 1 + load i32, i32* %a br label %for.loop for.loop.exit: @@ -128,21 +142,23 @@ define void @test_spec2006() { %d.val = load i32, i32* @d, align 4 %d.promoted = sext i32 %d.val to i64 %1 = icmp slt i32 %d.val, 2 - br i1 %1, label %.lr.ph, label %3 + br i1 %1, label %.lr.ph, label %bb3 .lr.ph: ; preds = %0 - br label %2 + br label %bb2 -;