diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -217,8 +217,12 @@ continue; } - // Ignore non-volatile accesses from local memory. (Atomic is okay here.) - if (!I.isVolatile() && AAR.pointsToConstantMemory(*Loc, /*OrLocal=*/true)) + // Volatile operations may access inaccessible memory. + if (I.isVolatile()) + ME |= MemoryEffects::inaccessibleMemOnly(MR); + + // Ignore accesses to local memory. + if (AAR.pointsToConstantMemory(*Loc, /*OrLocal=*/true)) continue; // The accessed location can be either only argument memory, or diff --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll --- a/llvm/test/Transforms/FunctionAttrs/nosync.ll +++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll @@ -161,7 +161,7 @@ ; negative, should not deduce nosync ; atomic load with release ordering define void @load_release(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable ; CHECK-LABEL: @load_release( ; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -172,7 +172,7 @@ ; negative volatile, relaxed atomic define void @load_volatile_release(ptr nocapture %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable ; CHECK-LABEL: @load_volatile_release( ; CHECK-NEXT: store atomic volatile i32 10, ptr [[TMP0:%.*]] release, align 4 ; CHECK-NEXT: ret void @@ -183,7 +183,7 @@ ; volatile store. define void @volatile_store(ptr %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind uwtable ; CHECK-LABEL: @volatile_store( ; CHECK-NEXT: store volatile i32 14, ptr [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret void @@ -195,7 +195,7 @@ ; negative, should not deduce nosync ; volatile load. define i32 @volatile_load(ptr %0) norecurse nounwind uwtable { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn uwtable +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly mustprogress nofree norecurse nounwind willreturn uwtable ; CHECK-LABEL: @volatile_load( ; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, ptr [[TMP0:%.*]], align 4 ; CHECK-NEXT: ret i32 [[TMP2]] @@ -211,7 +211,7 @@ define void @call_nosync_function() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nosync nounwind uwtable ; CHECK-LABEL: @call_nosync_function( -; CHECK-NEXT: tail call void @nosync_function() #[[ATTR10:[0-9]+]] +; CHECK-NEXT: tail call void @nosync_function() #[[ATTR11:[0-9]+]] ; CHECK-NEXT: ret void ; tail call void @nosync_function() noinline nounwind uwtable @@ -225,7 +225,7 @@ define void @call_might_sync() nounwind uwtable noinline { ; CHECK: Function Attrs: noinline nounwind uwtable ; CHECK-LABEL: @call_might_sync( -; CHECK-NEXT: tail call void @might_sync() #[[ATTR10]] +; CHECK-NEXT: tail call void @might_sync() #[[ATTR11]] ; CHECK-NEXT: ret void ; tail call void @might_sync() noinline nounwind uwtable diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll --- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll @@ -175,7 +175,7 @@ } define i32 @volatile_load(ptr %p) { -; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly mustprogress nofree norecurse nounwind willreturn ; CHECK-LABEL: define {{[^@]+}}@volatile_load ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR13:[0-9]+]] { ; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr [[P]], align 4 diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll --- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll @@ -96,7 +96,7 @@ } define void @test_volatile(ptr %p) { -; CHECK: Function Attrs: argmemonly nofree norecurse nounwind +; CHECK: Function Attrs: inaccessiblemem_or_argmemonly nofree norecurse nounwind ; CHECK-LABEL: define {{[^@]+}}@test_volatile ; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { ; CHECK-NEXT: store volatile i8 0, ptr [[P]], align 1