diff --git a/llvm/lib/Analysis/MemoryLocation.cpp b/llvm/lib/Analysis/MemoryLocation.cpp index 3b42bb412b9ba..c8daab7abde18 100644 --- a/llvm/lib/Analysis/MemoryLocation.cpp +++ b/llvm/lib/Analysis/MemoryLocation.cpp @@ -111,7 +111,9 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) { std::optional MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) { - if (!CB->onlyAccessesArgMemory()) + // Check that the only possible writes are to arguments. + MemoryEffects WriteME = CB->getMemoryEffects() & MemoryEffects::writeOnly(); + if (!WriteME.onlyAccessesArgPointees()) return std::nullopt; if (CB->hasOperandBundles()) diff --git a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll index 030d315bfd925..df2feb087e397 100644 --- a/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll +++ b/llvm/test/Transforms/DeadStoreElimination/trivial-dse-calls.ll @@ -286,3 +286,35 @@ define void @test_dse_non_alloca() { ret void } +define void @test_other_read_effects() { +; CHECK-LABEL: @test_other_read_effects( +; CHECK-NEXT: ret void +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(read, argmem: readwrite) nounwind willreturn + ret void +} + +define i32 @test_other_read_effects_read_after() { +; CHECK-LABEL: @test_other_read_effects_read_after( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4 +; CHECK-NEXT: ret i32 [[V]] +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(read, argmem: readwrite) nounwind willreturn + %v = load i32, ptr %a + ret i32 %v +} + +define void @test_other_write_effects() { +; CHECK-LABEL: @test_other_write_effects( +; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT: call void @f(ptr [[A]]) #[[ATTR6:[0-9]+]] +; CHECK-NEXT: ret void +; + %a = alloca i32, align 4 + call void @f(ptr %a) memory(write, argmem: readwrite) nounwind willreturn + ret void +}