diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -213,6 +213,16 @@ LibFunc F; if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) { switch (F) { + case LibFunc_memset_chk: { + assert(ArgIdx == 0 && "Invalid argument index for memset_chk"); + LocationSize Size = LocationSize::afterPointer(); + if (const auto *Len = dyn_cast(Call->getArgOperand(2))) { + // memset_chk writes at most Len bytes. It may write less, if it exceed + // the specified max size and aborts. + Size = LocationSize::upperBound(Len->getZExtValue()); + } + return MemoryLocation(Arg, Size, AATags); + } case LibFunc_memset_pattern16: assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memset_pattern16"); diff --git a/llvm/test/Analysis/BasicAA/libfuncs.ll b/llvm/test/Analysis/BasicAA/libfuncs.ll --- a/llvm/test/Analysis/BasicAA/libfuncs.ll +++ b/llvm/test/Analysis/BasicAA/libfuncs.ll @@ -183,7 +183,7 @@ ; CHECK: Just Mod (MustAlias): Ptr: i8* %a <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n) ; CHECK-NEXT: Just Mod: Ptr: i8* %res <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n) ; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.1 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n) -; CHECK-NEXT: Just Mod: Ptr: i8* %a.gep.5 <-> %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, 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: %res = tail call i8* @__memset_chk(i8* %a, i32 0, i64 4, i64 %n)