Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -11995,7 +11995,7 @@ :: - declare void @llvm.invariant.end.p0i8({}* , i64 , i8* nocapture ) + declare void @llvm.invariant.end.p0i8({}* readnone , i64 , i8* nocapture ) Overview: """"""""" Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -576,7 +576,8 @@ def int_invariant_end : Intrinsic<[], [llvm_descriptor_ty, llvm_i64_ty, llvm_anyptr_ty], - [IntrArgMemOnly, NoCapture<2>]>; + [IntrArgMemOnly, NoCapture<2>, + ReadNone<0>]>; def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -171,11 +171,11 @@ bool DoesAlias = false; ModRefInfo AllArgsMask = MRI_NoModRef; if (doesAccessArgPointees(MRB)) { - for (auto AI = CS.arg_begin(), AE = CS.arg_end(); AI != AE; ++AI) { - const Value *Arg = *AI; - if (!Arg->getType()->isPointerTy()) + for (const auto &A : enumerate(CS.args())) { + const Value *Arg = A.Value; + unsigned ArgIdx = A.Index; + if (!Arg->getType()->isPointerTy() || CS.doesNotAccessMemory(ArgIdx)) continue; - unsigned ArgIdx = std::distance(CS.arg_begin(), AI); MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI); AliasResult ArgAlias = alias(ArgLoc, Loc); if (ArgAlias != NoAlias) { @@ -240,11 +240,12 @@ if (onlyAccessesArgPointees(CS2B)) { ModRefInfo R = MRI_NoModRef; if (doesAccessArgPointees(CS2B)) { - for (auto I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) + for (const auto &A : enumerate(CS2.args())) { + const Value *Arg = A.Value; + unsigned CS2ArgIdx = A.Index; + if (!Arg->getType()->isPointerTy() || + CS2.doesNotAccessMemory(CS2ArgIdx)) continue; - unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence @@ -270,11 +271,12 @@ if (onlyAccessesArgPointees(CS1B)) { ModRefInfo R = MRI_NoModRef; if (doesAccessArgPointees(CS1B)) { - for (auto I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I) { - const Value *Arg = *I; - if (!Arg->getType()->isPointerTy()) + for (const auto &A : enumerate(CS1.args())) { + const Value *Arg = A.Value; + unsigned CS1ArgIdx = A.Index; + if (!Arg->getType()->isPointerTy() || + CS1.doesNotAccessMemory(CS1ArgIdx)) continue; - unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod Index: test/Analysis/BasicAA/getforargument-crash.ll =================================================================== --- /dev/null +++ test/Analysis/BasicAA/getforargument-crash.ll @@ -0,0 +1,13 @@ +; RUN: opt -basicaa -aa-eval -disable-output %s 2>/dev/null + +declare {}* @llvm.invariant.start(i64, i8* nocapture) nounwind readonly +declare void @llvm.invariant.end({}*, i64, i8* nocapture) nounwind + +; Previously caused getModRefInfo to retrieve a MemoryLocation for an invalid +; argument to the intrinsic. +define void @tests.invariant.start.end() { + %a = alloca i8 + %i = call {}* @llvm.invariant.start(i64 1, i8* %a) + call void @llvm.invariant.end({}* %i, i64 1, i8* %a) + ret void +}