[llvm] [AMDGPU] Document "relaxed buffer OOB mode", update HSA default (PR #134734)
Krzysztof Drewniak via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 10:49:36 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/134734
>From a7b3bde00ec6eebc82f4f353cd8d2c35cf68ac82 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Fri, 12 Jun 2026 17:48:58 +0000
Subject: [PATCH] Document buffer OOB access modes
---
llvm/docs/AMDGPUUsage.rst | 47 +++++++++++++++++++++++++++++++++++++--
1 file changed, 45 insertions(+), 2 deletions(-)
diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst
index a82cfe9240403..1ecbbf85f38c4 100644
--- a/llvm/docs/AMDGPUUsage.rst
+++ b/llvm/docs/AMDGPUUsage.rst
@@ -859,11 +859,14 @@ consumed by the AMDGPU backend during code generation.
semantics. This is an alias of **strict** that is allowed to link
with any other module. Code generation is identical to **strict**.
- ``1``: **relaxed**. The backend may merge misaligned buffer
- accesses for performance, even if that changes OOB behaviour.
+ accesses for performance, even if that changes OOB behaviour, and will
+ not split vector accesses that may produce unexpected OOB accesses.
- ``2``: **strict**. The backend preserves per-byte OOB guarantees
by preventing merging of misaligned buffer accesses that could
straddle an OOB boundary (e.g. as required by Vulkan
- ``robustBufferAccess2``).
+ ``robustBufferAccess2``) and by splitting vector accesses to buffer
+ fat pointers that may produce incorrect results under a robust buffer
+ access scheme. See `__amdgpu_fat_buffer_oob_handling` for details.
* - ``amdgpu.tbuffer.oob.mode``
- ``i32``
@@ -1339,6 +1342,46 @@ instruction with ``one-as`` sync scope is specified via
other operations within the same address space.
======================= ===================================================
+.. __amdgpu_fat_buffer_oob_handling:
+
+Buffer Fat Pointer out of bounds (OOB) handling
+-----------------------------------------------
+
+Instructions that load from or store to buffer resources (and thus, by extension
+buffer fat pointers and buffer strided pointers) generally implement handling for
+out of bounds (OOB) memory accesses, including those that are partially OOB,
+if the buffer resource resource has the required flags set. How ordinary
+``load`` and ``store`` instructions are lowered to buffer operations is partly
+controlled by the ``amdgpu.buffer.oob.mode`` (see `__amdgpu_metadata`). If
+that flag is set to ``1`` (relaxed), no handling to improve the expected behavior
+of OOB accesses is performed, while if it is set to ``0`` (any) or ``2`` (strict),
+oerations may be spliit to ensure correctness under stronger models of how
+out-of-bounds accesses should behave.
+
+When operating on more than 32 bits of data, the ``voffset`` used for the access
+will be range-checked for each 32-bit word independently. This check uses saturating
+arithmetic and interprets the offset as an unsigned value.
+
+The behavior described above conflicts with the ABI requirements of certain graphics
+APIs that require out of bounds accesses to be handled strictly so that accessed
+that begin out of bounds but then access in-bounds elements (such as loading a
+``<4 x i32>`` beginning at offset ``-4``) still load the three in-bounds integers
+(producing ``<0, v0, v1, v2>`` and not ``<0, 0, 0, 0>``. So, under strict OOB
+handling, such an access will be split into four ``i32`` accesses.
+
+Similarly, buffer fat pointers permit operating types such as ``<8 x i8>`` which
+must be accessed (and bounds-checked) 4 bytes at a time. Non-word-aligned
+accesses to such types from near the end of a buffer resource (such as starting
+a load of an ``<8 x i8>`` from an offset of ``6`` on an 8-byte buffer) will treat
+the initial two bytes to be loaded/stored as out of bounds, even though, under
+a strict interpretation of the bounds-checking semantics, they would be in bounds.
+Under strict OOB handling, such a load will be split into a sequence of ``<2 x i16>``
+loads.
+
+.. note::
+These transformations do not impact intrinsic calls (calling
+``llvm.amdgcn.raw.buffer.*.t`` directly.
+
Target Types
------------
More information about the llvm-commits
mailing list