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 @@ -210,17 +210,30 @@ // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. LibFunc F; - if (TLI && Call->getCalledFunction() && - TLI->getLibFunc(*Call->getCalledFunction(), F) && - F == LibFunc_memset_pattern16 && TLI->has(F)) { - assert((ArgIdx == 0 || ArgIdx == 1) && - "Invalid argument index for memset_pattern16"); - if (ArgIdx == 1) - return MemoryLocation(Arg, LocationSize::precise(16), AATags); - if (const ConstantInt *LenCI = - dyn_cast(Call->getArgOperand(2))) - return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), - AATags); + if (TLI && Call->getCalledFunction() && TLI->getLibFunc(*Call, F) && + TLI->has(F)) { + switch (F) { + case LibFunc_memset_pattern16: + assert((ArgIdx == 0 || ArgIdx == 1) && + "Invalid argument index for memset_pattern16"); + if (ArgIdx == 1) + return MemoryLocation(Arg, LocationSize::precise(16), AATags); + if (const ConstantInt *LenCI = + dyn_cast(Call->getArgOperand(2))) + return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), + AATags); + break; + case LibFunc_memcmp: + assert((ArgIdx == 0 || ArgIdx == 1) && + "Invalid argument index for memcmp"); + if (const ConstantInt *LenCI = + dyn_cast(Call->getArgOperand(2))) + return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()), + AATags); + break; + default: + break; + }; } // FIXME: Handle memset_pattern4 and memset_pattern8 also. 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 @@ -7,9 +7,9 @@ ; CHECK: Just Ref: Ptr: i8* %a <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) ; CHECK-NEXT: Just Ref: Ptr: i8* %b <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) ; CHECK-NEXT: Just Ref: Ptr: i8* %a.gep.1 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) -; CHECK-NEXT: Just Ref: Ptr: i8* %a.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) +; CHECK-NEXT: NoModRef: Ptr: i8* %a.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) ; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.1 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) -; CHECK-NEXT: Just Ref: Ptr: i8* %b.gep.5 <-> %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) +; 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: %res = tail call i32 @memcmp(i8* %a, i8* %b, i64 4) diff --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll b/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll --- a/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/libcalls.ll @@ -85,10 +85,6 @@ ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1 -; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2 -; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1 -; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3 -; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1 ; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[FOO:%.*]], i8* nonnull dereferenceable(2) [[STACK_PTR]], i64 2) ; CHECK-NEXT: ret i32 [[RES]] ;