[llvm] f2fe289 - [FunctionAttrs] Volatile operations can access inaccessible memory
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 20 02:57:20 PDT 2022
Author: Nikita Popov
Date: 2022-10-20T11:57:10+02:00
New Revision: f2fe289374b03d7a11559fa5ea2c6a0c225d0aec
URL: https://github.com/llvm/llvm-project/commit/f2fe289374b03d7a11559fa5ea2c6a0c225d0aec
DIFF: https://github.com/llvm/llvm-project/commit/f2fe289374b03d7a11559fa5ea2c6a0c225d0aec.diff
LOG: [FunctionAttrs] Volatile operations can access inaccessible memory
Per LangRef, volatile operations are allowed to access the location
of their pointer argument, plus inaccessible memory:
> Any volatile operation can have side effects, and any volatile
> operation can read and/or modify state which is not accessible
> via a regular load or store in this module.
> [...]
> The allowed side-effects for volatile accesses are limited. If
> a non-volatile store to a given address would be legal, a volatile
> operation may modify the memory at that address. A volatile
> operation may not modify any other memory accessible by the
> module being compiled. A volatile operation may not call any
> code in the current module.
FunctionAttrs currently does not model this and ends up marking
functions with volatile accesses on arguments as argmemonly,
even though they should be inaccessiblemem_or_argmemonly.
Differential Revision: https://reviews.llvm.org/D135863
Added:
Modified:
llvm/lib/Transforms/IPO/FunctionAttrs.cpp
llvm/test/Transforms/FunctionAttrs/nosync.ll
llvm/test/Transforms/FunctionAttrs/readattrs.ll
llvm/test/Transforms/FunctionAttrs/writeonly.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index d0c1350664f97..013e806207b42 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -217,8 +217,12 @@ static MemoryEffects checkFunctionMemoryAccess(Function &F, bool ThisBody,
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
index 25d517bc8208c..77f208e6b0302 100644
--- a/llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nosync.ll
@@ -161,7 +161,7 @@ define void @store_unordered(ptr nocapture %0) norecurse nounwind uwtable {
; 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 @@ define void @load_release(ptr nocapture %0) norecurse nounwind uwtable {
; 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 @@ define void @load_volatile_release(ptr nocapture %0) norecurse nounwind uwtable
; 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 @@ define void @volatile_store(ptr %0) norecurse nounwind uwtable {
; 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 @@ declare void @nosync_function() noinline nounwind uwtable nosync
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 @@ declare void @might_sync() noinline nounwind uwtable
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
index f2ea7e4772bf5..511fc8d5c5d9a 100644
--- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -175,7 +175,7 @@ define <4 x i32> @test12_2(<4 x ptr> %ptrs) {
}
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
index 7828d2f81bb18..0ad158500c24e 100644
--- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll
+++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll
@@ -96,7 +96,7 @@ define void @test_readwrite(ptr %p) {
}
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
More information about the llvm-commits
mailing list