diff options
author | Luigi Sartor Piucco <luigipiucco@gmail.com> | 2025-05-22 10:12:34 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-22 15:12:34 +0200 |
commit | 83de1efae389707f7fd03bf3ed2e42934122b4fb (patch) | |
tree | afafc2fb7d228d47eb12f6cb0e9508593098c4f7 /llvm | |
parent | 229aa6627a63012ac5e0b3587c87e94c2b5ad36f (diff) | |
download | llvm-83de1efae389707f7fd03bf3ed2e42934122b4fb.zip llvm-83de1efae389707f7fd03bf3ed2e42934122b4fb.tar.gz llvm-83de1efae389707f7fd03bf3ed2e42934122b4fb.tar.bz2 |
[LangRef] Comment on validity of volatile ops on null (#139803)
Some hardware (for example, certain AVR chips) have peripheral registers
mapped to the data space address 0. Although a volatile load/store on
`ptr null` already generates expected code, the wording in the LangRef
makes operations on null seem like undefined behavior in all cases. This
commit adds a comment that, for volatile operations, it may be defined
behavior to access the address null, if the architecture permits it. The
intended use case is MMIO registers with hard-coded addresses that
include bit-value 0. A simple CodeGen test is included for AVR, as an
architecture known to have this quirk, that does `load volatile` and
`store volatile` to `ptr null`, expecting to generate `lds <reg>, 0` and
`sts 0, <reg>`.
See [this
thread](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Adding.20the.20possibility.20of.20volatile.20access.20to.20address.200)
and [the
RFC](https://discourse.llvm.org/t/rfc-volatile-access-to-non-dereferenceable-memory-may-be-well-defined/86303)
for discussion and context.
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/docs/LangRef.rst | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/AVR/volatile-null.ll | 15 |
2 files changed, 21 insertions, 2 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index b59f94e..ad0755e 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3573,7 +3573,8 @@ can read and/or modify state which is not accessible via a regular load or store in this module. Volatile operations may use addresses which do not point to memory (like MMIO registers). This means the compiler may not use a volatile operation to prove a non-volatile access to that -address has defined behavior. +address has defined behavior. This includes addresses typically forbidden, +such as the pointer with bit-value 0. The allowed side-effects for volatile accesses are limited. If a non-volatile store to a given address would be legal, a volatile @@ -4292,7 +4293,10 @@ The semantics of non-zero address spaces are target-specific. Memory access through a non-dereferenceable pointer is undefined behavior in any address space. Pointers with the bit-value 0 are only assumed to be non-dereferenceable in address space 0, unless the function is -marked with the ``null_pointer_is_valid`` attribute. +marked with the ``null_pointer_is_valid`` attribute. However, *volatile* +access to any non-dereferenceable address may have defined behavior +(according to the target), and in this case the attribute is not needed +even for address 0. If an object can be proven accessible through a pointer with a different address space, the access may be modified to use that diff --git a/llvm/test/CodeGen/AVR/volatile-null.ll b/llvm/test/CodeGen/AVR/volatile-null.ll new file mode 100644 index 0000000..fa49e07 --- /dev/null +++ b/llvm/test/CodeGen/AVR/volatile-null.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=avr | FileCheck %s + +define i8 @load_volatile_null() { +; CHECK-LABEL: load_volatile_null: +; CHECK: lds r24, 0 + %result = load volatile i8, ptr null + ret i8 %result +} + +define void @store_volatile_null(i8 %a) { +; CHECK-LABEL: store_volatile_null: +; CHECK: sts 0, r24 + store volatile i8 %a, ptr null + ret void +} |