diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index b2a3f3390e000..2bed294c60776 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -824,6 +824,10 @@ MemoryEffects BasicAAResult::getMemoryEffects(const CallBase *Call, FuncME |= MemoryEffects::readOnly(); if (Call->hasClobberingOperandBundles()) FuncME |= MemoryEffects::writeOnly(); + if (Call->isVolatile()) { + // Volatile operations also access inaccessible memory. + FuncME |= MemoryEffects::inaccessibleMemOnly(); + } Min &= FuncME; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index b8b2c1d7f9a85..3c69d82dfda07 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -615,6 +615,10 @@ MemoryEffects CallBase::getMemoryEffects() const { if (hasClobberingOperandBundles()) FnME |= MemoryEffects::writeOnly(); } + if (isVolatile()) { + // Volatile operations also access inaccessible memory. + FnME |= MemoryEffects::inaccessibleMemOnly(); + } ME &= FnME; } return ME; diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll index 62f217aa3f7de..b2e6c284747eb 100644 --- a/llvm/test/Transforms/FunctionAttrs/initializes.ll +++ b/llvm/test/Transforms/FunctionAttrs/initializes.ll @@ -443,7 +443,7 @@ define void @memset_neg(ptr %p) { } define void @memset_volatile(ptr %p) { -; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write) +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write, inaccessiblemem: readwrite) ; CHECK-LABEL: define void @memset_volatile( ; CHECK-SAME: ptr writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] { ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 9, i1 true) @@ -478,7 +478,7 @@ define void @memcpy(ptr %p, ptr %p2) { } define void @memcpy_volatile(ptr %p, ptr %p2) { -; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define void @memcpy_volatile( ; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true) @@ -541,7 +541,7 @@ define void @memmove(ptr %p, ptr %p2) { } define void @memmove_volatile(ptr %p, ptr %p2) { -; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: define void @memmove_volatile( ; CHECK-SAME: ptr writeonly [[P:%.*]], ptr readonly [[P2:%.*]]) #[[ATTR6]] { ; CHECK-NEXT: call void @llvm.memmove.p0.p0.i64(ptr [[P]], ptr [[P2]], i64 9, i1 true) diff --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll index de5398f17ce51..9abfbb21a71a0 100644 --- a/llvm/test/Transforms/FunctionAttrs/nosync.ll +++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll @@ -236,7 +236,7 @@ declare void @llvm.memset(ptr %dest, i8 %val, i32 %len, i1 %isvolatile) ; negative, checking volatile intrinsics. define i32 @memcpy_volatile(ptr %ptr1, ptr %ptr2) { -; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) +; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) ; CHECK-LABEL: @memcpy_volatile( ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[PTR1:%.*]], ptr [[PTR2:%.*]], i32 8, i1 true) ; CHECK-NEXT: ret i32 4