[LangRef] Comment on validity of volatile ops on null by LuigiPiucco · Pull Request #139803 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-llvm-ir
Author: Luigi Sartor Piucco (LuigiPiucco)
Changes
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 and the RFC for discussion and context.
Full diff: https://github.com/llvm/llvm-project/pull/139803.diff
2 Files Affected:
- (modified) llvm/docs/LangRef.rst (+6-2)
- (added) llvm/test/CodeGen/AVR/volatile-null.ll (+15)
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 5f14726c36672..3cde71d7a8520 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -3563,7 +3563,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
@@ -4272,7 +4273,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 0000000000000..fa49e07eb0680 --- /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
+}