Skip to content

Commit 6387c82

Browse files
committed
[llvm] Comment on validity of volatile ops on null
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>`.
1 parent e4d21ae commit 6387c82

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

llvm/docs/LangRef.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3563,7 +3563,8 @@ can read and/or modify state which is not accessible via a regular load
35633563
or store in this module. Volatile operations may use addresses which do
35643564
not point to memory (like MMIO registers). This means the compiler may
35653565
not use a volatile operation to prove a non-volatile access to that
3566-
address has defined behavior.
3566+
address has defined behavior. This includes addresses typically forbidden,
3567+
such as the pointer with bit-value 0.
35673568

35683569
The allowed side-effects for volatile accesses are limited. If a
35693570
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
42724273
access through a non-dereferenceable pointer is undefined behavior in
42734274
any address space. Pointers with the bit-value 0 are only assumed to
42744275
be non-dereferenceable in address space 0, unless the function is
4275-
marked with the ``null_pointer_is_valid`` attribute.
4276+
marked with the ``null_pointer_is_valid`` attribute. However, *volatile*
4277+
access to any non-dereferenceable address may have defined behavior
4278+
(according to the target), and in this case the attribute is not needed
4279+
even for address 0.
42764280

42774281
If an object can be proven accessible through a pointer with a
42784282
different address space, the access may be modified to use that
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
; RUN: llc < %s -mtriple=avr | FileCheck %s
2+
3+
define i8 @load_volatile_null() {
4+
; CHECK-LABEL: load_volatile_null:
5+
; CHECK: lds r24, 0
6+
%result = load volatile i8, ptr null
7+
ret i8 %result
8+
}
9+
10+
define void @store_volatile_null(i8 %a) {
11+
; CHECK-LABEL: store_volatile_null:
12+
; CHECK: sts 0, r24
13+
store volatile i8 %a, ptr null
14+
ret void
15+
}

0 commit comments

Comments
 (0)