[llvm] [RFC] IR: Define noalias.addrspace metadata (PR #102461)

Yaxun Liu via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 19 10:21:53 PDT 2024


================
@@ -8020,6 +8020,42 @@ it will contain a list of ids, including the ids of the callsites in the
 full inline sequence, in order from the leaf-most call's id to the outermost
 inlined call.
 
+
+'``noalias.addrspace``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``noalias.addrspace`` metadata is used to identify memory
+operations which cannot access a range of address spaces. It is
+attached to memory instructions, including :ref:`atomicrmw
+<i_atomicrmw>`, :ref:`cmpxchg <i_cmpxchg>`, and :ref:`call <i_call>`
+instructions.
+
+This follows the same form as :ref:`range metadata <_range-metadata>`,
+except the field entries must be of type `i32`. The interpretation is
+the same numeric address spaces as applied to IR values.
+
+Example:
+
+.. code-block:: llvm
+    ; %ptr cannot point to an object allocated in addrspace(5)
+    %rmw.valid = atomicrmw and ptr %ptr, i64 %value seq_cst, !noalias.addrspace !0
+
+    ; Undefined behavior. The underlying object is allocated in one of the listed
+    ; address spaces.
+    %alloca = alloca i64, addrspace(5)
+    %alloca.cast = addrspacecast ptr addrspace(5) %alloca to ptr
+    %rmw.ub = atomicrmw and ptr %alloca.cast, i64 %value seq_cst, !noalias.addrspace !0
+
+    !0 = !{i32 5, i32 6}
+
+
+This is intended for use on targets with a notion of generic address
+spaces, which at runtime resolve to different physical memory
+spaces. The interpretation of the address space values is target
+specific. The behavior is undefined if the runtime memory address does
+resolve to an object defined in one of the indicated address spaces.
----------------
yxsamliu wrote:

> 
> To simplify your question with an example, I would interpret
> 
> ```
> @globalvar.in.0 = addrspace(0) constant i64
> 
> @globalvar.in.1 = addrspace(1) constant i64
> 
> ; instant undefined behavior, can fold to trap
> %rmw.ub = atomicrmw and ptr @globalvar.in.0, i64 %value seq_cst, !noalias.addrspace !0
> 
> ; OK, underlying object is in addrspace(1)
> %rmw.ok0 = atomicrmw and ptr addrspace(1) @globalvar.in.1, i64 %value seq_cst, !noalias.addrspace !0
> 
> ; OK, underlying object is in addrspace(1) even though access is through forbidden addrspace(0) the object ; definition address space is what matters 
> %cast.gv.in.1 = addrspacecast ptr addrspace(1) @globalvar.in.1 to ptr
> %rmw.ok0 = atomicrmw and ptr %cast.gv.in.1, i64 %value seq_cst, !noalias.addrspace !0
> 
> !0 = !{i32 0, i32 1} ; cannot alias 0
> ```

This example is confusing for me. Since addr space 0 is a union of all concrete addr spaces including 1, 2, 3, 5, etc, an actual global pointer with MD promising not alias to 0 is self-contradictory.

If in this example the MD is promising not alias to 5 then it has no confusion.

Then it comes the question: does it really meaningful to have a MD promising not alias to generic addr space 0? Should that be disallowed?


https://github.com/llvm/llvm-project/pull/102461


More information about the llvm-commits mailing list