Index: include/llvm/Analysis/MemoryLocation.h =================================================================== --- include/llvm/Analysis/MemoryLocation.h +++ include/llvm/Analysis/MemoryLocation.h @@ -24,6 +24,7 @@ class LoadInst; class StoreInst; +class IntrinsicInst; class MemTransferInst; class MemIntrinsic; class TargetLibraryInfo; @@ -92,6 +93,8 @@ static MemoryLocation getForArgument(ImmutableCallSite CS, unsigned ArgIdx, const TargetLibraryInfo &TLI); + static bool validIntrinArg(const IntrinsicInst *, unsigned ArgIdx); + explicit MemoryLocation(const Value *Ptr = nullptr, uint64_t Size = UnknownSize, const AAMDNodes &AATags = AAMDNodes()) Index: lib/Analysis/AliasAnalysis.cpp =================================================================== --- lib/Analysis/AliasAnalysis.cpp +++ lib/Analysis/AliasAnalysis.cpp @@ -176,6 +176,9 @@ if (!Arg->getType()->isPointerTy()) continue; unsigned ArgIdx = std::distance(CS.arg_begin(), AI); + if (auto *II = dyn_cast(CS.getInstruction())) + if (!MemoryLocation::validIntrinArg(II, ArgIdx)) + continue; MemoryLocation ArgLoc = MemoryLocation::getForArgument(CS, ArgIdx, TLI); AliasResult ArgAlias = alias(ArgLoc, Loc); if (ArgAlias != NoAlias) { @@ -245,6 +248,9 @@ if (!Arg->getType()->isPointerTy()) continue; unsigned CS2ArgIdx = std::distance(CS2.arg_begin(), I); + if (auto *II = dyn_cast(CS2.getInstruction())) + if (!MemoryLocation::validIntrinArg(II, CS2ArgIdx)) + continue; auto CS2ArgLoc = MemoryLocation::getForArgument(CS2, CS2ArgIdx, TLI); // ArgMask indicates what CS2 might do to CS2ArgLoc, and the dependence @@ -275,6 +281,9 @@ if (!Arg->getType()->isPointerTy()) continue; unsigned CS1ArgIdx = std::distance(CS1.arg_begin(), I); + if (auto *II = dyn_cast(CS1.getInstruction())) + if (!MemoryLocation::validIntrinArg(II, CS1ArgIdx)) + continue; auto CS1ArgLoc = MemoryLocation::getForArgument(CS1, CS1ArgIdx, TLI); // ArgMask indicates what CS1 might do to CS1ArgLoc; if CS1 might Mod Index: lib/Analysis/MemoryLocation.cpp =================================================================== --- lib/Analysis/MemoryLocation.cpp +++ lib/Analysis/MemoryLocation.cpp @@ -90,6 +90,29 @@ return MemoryLocation(MTI->getRawDest(), Size, AATags); } +bool MemoryLocation::validIntrinArg(const IntrinsicInst *II, unsigned ArgIdx) { + switch (II->getIntrinsicID()) { + default: + return true; + case Intrinsic::memset: + case Intrinsic::memcpy: + case Intrinsic::memmove: + return ArgIdx <= 1; + + case Intrinsic::lifetime_start: + case Intrinsic::lifetime_end: + case Intrinsic::invariant_start: + return ArgIdx == 1; + + case Intrinsic::invariant_end: + return ArgIdx == 2; + + case Intrinsic::arm_neon_vld1: + case Intrinsic::arm_neon_vst1: + return ArgIdx == 0; + } +} + MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, unsigned ArgIdx, const TargetLibraryInfo &TLI) { @@ -101,14 +124,13 @@ if (const IntrinsicInst *II = dyn_cast(CS.getInstruction())) { const DataLayout &DL = II->getModule()->getDataLayout(); + assert(validIntrinArg(II, ArgIdx) && "Invalid argument index"); switch (II->getIntrinsicID()) { default: break; case Intrinsic::memset: case Intrinsic::memcpy: case Intrinsic::memmove: - assert((ArgIdx == 0 || ArgIdx == 1) && - "Invalid argument index for memory intrinsic"); if (ConstantInt *LenCI = dyn_cast(II->getArgOperand(2))) return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); break; @@ -116,23 +138,19 @@ case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::invariant_start: - assert(ArgIdx == 1 && "Invalid argument index"); return MemoryLocation( Arg, cast(II->getArgOperand(0))->getZExtValue(), AATags); case Intrinsic::invariant_end: - assert(ArgIdx == 2 && "Invalid argument index"); return MemoryLocation( Arg, cast(II->getArgOperand(1))->getZExtValue(), AATags); case Intrinsic::arm_neon_vld1: - assert(ArgIdx == 0 && "Invalid argument index"); // LLVM's vld1 and vst1 intrinsics currently only support a single // vector register. return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags); case Intrinsic::arm_neon_vst1: - assert(ArgIdx == 0 && "Invalid argument index"); return MemoryLocation( Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags); } 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 +}