[llvm-branch-commits] [llvm] [AMDGPU] Pre-commit num_records of arbitrary width tests for LowerBufferFatPointers (PR #217137)
Krzysztof Drewniak via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 18 14:47:40 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/217137
>From ef6955d474a2794ce170fa6ccc535cdd347580d2 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Tue, 18 Aug 2026 19:32:28 +0000
Subject: [PATCH 1/2] [AMDGPU] Pre-commit num_records of arbitrary width tests
for LowerBufferFatPointers
Add tests to ensure that the reasoning for whether an access can be
partially out of bounds and needs to be scalarized work correctly when
num_records has a width different from the hardware width.
AI disclosure: Claude generated these and I've looked at them
---
...r-buffer-fat-pointers-num-records-width.ll | 236 ++++++++++++++++++
1 file changed, 236 insertions(+)
create mode 100644 llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
new file mode 100644
index 0000000000000..851cb7fd87336
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
@@ -0,0 +1,236 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgpu9.00-- -mattr=+unaligned-access-mode < %s | FileCheck %s --check-prefixes=CHECK,RECORDS32
+; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgpu12.50-- -mattr=+unaligned-access-mode < %s | FileCheck %s --check-prefixes=CHECK,RECORDS45
+;; alignment reasons instead.
+; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgcn-- -mattr=+unaligned-access-mode,+unaligned-buffer-access < %s | FileCheck %s --check-prefixes=CHECK,UNKNOWN
+
+; Ensure that "this isn't out of bounds" tests work correctly even when
+; when size manipulation is needed.
+
+define <8 x half> @bound_i64_2p44(ptr addrspace(1) inreg %ptr, i32 %off) {
+; CHECK-LABEL: define <8 x half> @bound_i64_2p44(
+; CHECK-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i64(ptr addrspace(1) [[PTR]], i16 0, i64 17592186044416, i32 0)
+; CHECK-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; CHECK-NEXT: [[RET:%.*]] = call <8 x half> @llvm.amdgcn.raw.ptr.buffer.load.v8f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; CHECK-NEXT: ret <8 x half> [[RET]]
+;
+ %buf = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i64(ptr addrspace(1) %ptr, i16 0, i64 17592186044416, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 1024)
+ %q = getelementptr i8, ptr addrspace(7) %p, i32 %off.clamped
+ %ret = load <8 x half>, ptr addrspace(7) %q, align 2
+ ret <8 x half> %ret
+}
+
+define <8 x half> @bound_i45_2p44(ptr addrspace(1) inreg %ptr, i32 %off) {
+; RECORDS32-LABEL: define <8 x half> @bound_i45_2p44(
+; RECORDS32-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS32-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 -17592186044416, i32 0)
+; RECORDS32-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; RECORDS32-NEXT: [[RET:%.*]] = call <8 x half> @llvm.amdgcn.raw.ptr.buffer.load.v8f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; RECORDS32-NEXT: ret <8 x half> [[RET]]
+;
+; RECORDS45-LABEL: define <8 x half> @bound_i45_2p44(
+; RECORDS45-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS45-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 -17592186044416, i32 0)
+; RECORDS45-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; RECORDS45-NEXT: [[RET_OFF_0:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_0:%.*]] = insertelement <8 x half> poison, half [[RET_OFF_0]], i64 0
+; RECORDS45-NEXT: [[Q_OFF_PTR_2:%.*]] = add i32 [[Q]], 2
+; RECORDS45-NEXT: [[RET_OFF_2:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_2]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_1:%.*]] = insertelement <8 x half> [[RET_SLICE_0]], half [[RET_OFF_2]], i64 1
+; RECORDS45-NEXT: [[Q_OFF_PTR_4:%.*]] = add i32 [[Q]], 4
+; RECORDS45-NEXT: [[RET_OFF_4:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_4]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_2:%.*]] = insertelement <8 x half> [[RET_SLICE_1]], half [[RET_OFF_4]], i64 2
+; RECORDS45-NEXT: [[Q_OFF_PTR_6:%.*]] = add i32 [[Q]], 6
+; RECORDS45-NEXT: [[RET_OFF_6:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_6]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_3:%.*]] = insertelement <8 x half> [[RET_SLICE_2]], half [[RET_OFF_6]], i64 3
+; RECORDS45-NEXT: [[Q_OFF_PTR_8:%.*]] = add i32 [[Q]], 8
+; RECORDS45-NEXT: [[RET_OFF_8:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_8]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_4:%.*]] = insertelement <8 x half> [[RET_SLICE_3]], half [[RET_OFF_8]], i64 4
+; RECORDS45-NEXT: [[Q_OFF_PTR_10:%.*]] = add i32 [[Q]], 10
+; RECORDS45-NEXT: [[RET_OFF_10:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_10]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_5:%.*]] = insertelement <8 x half> [[RET_SLICE_4]], half [[RET_OFF_10]], i64 5
+; RECORDS45-NEXT: [[Q_OFF_PTR_12:%.*]] = add i32 [[Q]], 12
+; RECORDS45-NEXT: [[RET_OFF_12:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_12]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET_SLICE_6:%.*]] = insertelement <8 x half> [[RET_SLICE_5]], half [[RET_OFF_12]], i64 6
+; RECORDS45-NEXT: [[Q_OFF_PTR_14:%.*]] = add i32 [[Q]], 14
+; RECORDS45-NEXT: [[RET_OFF_14:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_14]], i32 0, i32 0)
+; RECORDS45-NEXT: [[RET:%.*]] = insertelement <8 x half> [[RET_SLICE_6]], half [[RET_OFF_14]], i64 7
+; RECORDS45-NEXT: ret <8 x half> [[RET]]
+;
+; UNKNOWN-LABEL: define <8 x half> @bound_i45_2p44(
+; UNKNOWN-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; UNKNOWN-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 -17592186044416, i32 0)
+; UNKNOWN-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; UNKNOWN-NEXT: [[RET:%.*]] = call <8 x half> @llvm.amdgcn.raw.ptr.buffer.load.v8f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; UNKNOWN-NEXT: ret <8 x half> [[RET]]
+;
+ %buf = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) %ptr, i16 0, i45 17592186044416, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 1024)
+ %q = getelementptr i8, ptr addrspace(7) %p, i32 %off.clamped
+ %ret = load <8 x half>, ptr addrspace(7) %q, align 2
+ ret <8 x half> %ret
+}
+
+define <8 x half> @bound_i32_2p31(ptr addrspace(1) inreg %ptr, i32 %off) {
+; CHECK-LABEL: define <8 x half> @bound_i32_2p31(
+; CHECK-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) [[PTR]], i16 0, i32 -2147483648, i32 0)
+; CHECK-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; CHECK-NEXT: [[RET_OFF_0:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_0:%.*]] = insertelement <8 x half> poison, half [[RET_OFF_0]], i64 0
+; CHECK-NEXT: [[Q_OFF_PTR_2:%.*]] = add i32 [[Q]], 2
+; CHECK-NEXT: [[RET_OFF_2:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_2]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_1:%.*]] = insertelement <8 x half> [[RET_SLICE_0]], half [[RET_OFF_2]], i64 1
+; CHECK-NEXT: [[Q_OFF_PTR_4:%.*]] = add i32 [[Q]], 4
+; CHECK-NEXT: [[RET_OFF_4:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_4]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_2:%.*]] = insertelement <8 x half> [[RET_SLICE_1]], half [[RET_OFF_4]], i64 2
+; CHECK-NEXT: [[Q_OFF_PTR_6:%.*]] = add i32 [[Q]], 6
+; CHECK-NEXT: [[RET_OFF_6:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_6]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_3:%.*]] = insertelement <8 x half> [[RET_SLICE_2]], half [[RET_OFF_6]], i64 3
+; CHECK-NEXT: [[Q_OFF_PTR_8:%.*]] = add i32 [[Q]], 8
+; CHECK-NEXT: [[RET_OFF_8:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_8]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_4:%.*]] = insertelement <8 x half> [[RET_SLICE_3]], half [[RET_OFF_8]], i64 4
+; CHECK-NEXT: [[Q_OFF_PTR_10:%.*]] = add i32 [[Q]], 10
+; CHECK-NEXT: [[RET_OFF_10:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_10]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_5:%.*]] = insertelement <8 x half> [[RET_SLICE_4]], half [[RET_OFF_10]], i64 5
+; CHECK-NEXT: [[Q_OFF_PTR_12:%.*]] = add i32 [[Q]], 12
+; CHECK-NEXT: [[RET_OFF_12:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_12]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_6:%.*]] = insertelement <8 x half> [[RET_SLICE_5]], half [[RET_OFF_12]], i64 6
+; CHECK-NEXT: [[Q_OFF_PTR_14:%.*]] = add i32 [[Q]], 14
+; CHECK-NEXT: [[RET_OFF_14:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_14]], i32 0, i32 0)
+; CHECK-NEXT: [[RET:%.*]] = insertelement <8 x half> [[RET_SLICE_6]], half [[RET_OFF_14]], i64 7
+; CHECK-NEXT: ret <8 x half> [[RET]]
+;
+ %buf = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) %ptr, i16 0, i32 2147483648, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 1024)
+ %q = getelementptr i8, ptr addrspace(7) %p, i32 %off.clamped
+ %ret = load <8 x half>, ptr addrspace(7) %q, align 2
+ ret <8 x half> %ret
+}
+
+;; The two tests below use num_records values that are equal modulo 2^32 but
+;; that differ as 45-bit quantities, with a maximum offset that falls between
+;; those two bounds. Therefore, on targets with a 32-bit num_records, both
+;; loads can be partially out of bounds and must be scalarized, while on
+;; targets with a 45-bit num_records, only the i32 one can be.
+
+define <8 x half> @bound_i32_2p11(ptr addrspace(1) inreg %ptr, i32 %off) {
+; CHECK-LABEL: define <8 x half> @bound_i32_2p11(
+; CHECK-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) [[PTR]], i16 0, i32 2048, i32 0)
+; CHECK-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 4096)
+; CHECK-NEXT: [[RET_OFF_0:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_0:%.*]] = insertelement <8 x half> poison, half [[RET_OFF_0]], i64 0
+; CHECK-NEXT: [[Q_OFF_PTR_2:%.*]] = add i32 [[Q]], 2
+; CHECK-NEXT: [[RET_OFF_2:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_2]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_1:%.*]] = insertelement <8 x half> [[RET_SLICE_0]], half [[RET_OFF_2]], i64 1
+; CHECK-NEXT: [[Q_OFF_PTR_4:%.*]] = add i32 [[Q]], 4
+; CHECK-NEXT: [[RET_OFF_4:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_4]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_2:%.*]] = insertelement <8 x half> [[RET_SLICE_1]], half [[RET_OFF_4]], i64 2
+; CHECK-NEXT: [[Q_OFF_PTR_6:%.*]] = add i32 [[Q]], 6
+; CHECK-NEXT: [[RET_OFF_6:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_6]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_3:%.*]] = insertelement <8 x half> [[RET_SLICE_2]], half [[RET_OFF_6]], i64 3
+; CHECK-NEXT: [[Q_OFF_PTR_8:%.*]] = add i32 [[Q]], 8
+; CHECK-NEXT: [[RET_OFF_8:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_8]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_4:%.*]] = insertelement <8 x half> [[RET_SLICE_3]], half [[RET_OFF_8]], i64 4
+; CHECK-NEXT: [[Q_OFF_PTR_10:%.*]] = add i32 [[Q]], 10
+; CHECK-NEXT: [[RET_OFF_10:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_10]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_5:%.*]] = insertelement <8 x half> [[RET_SLICE_4]], half [[RET_OFF_10]], i64 5
+; CHECK-NEXT: [[Q_OFF_PTR_12:%.*]] = add i32 [[Q]], 12
+; CHECK-NEXT: [[RET_OFF_12:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_12]], i32 0, i32 0)
+; CHECK-NEXT: [[RET_SLICE_6:%.*]] = insertelement <8 x half> [[RET_SLICE_5]], half [[RET_OFF_12]], i64 6
+; CHECK-NEXT: [[Q_OFF_PTR_14:%.*]] = add i32 [[Q]], 14
+; CHECK-NEXT: [[RET_OFF_14:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_14]], i32 0, i32 0)
+; CHECK-NEXT: [[RET:%.*]] = insertelement <8 x half> [[RET_SLICE_6]], half [[RET_OFF_14]], i64 7
+; CHECK-NEXT: ret <8 x half> [[RET]]
+;
+ %buf = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) %ptr, i16 0, i32 2048, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 4096)
+ %q = getelementptr i8, ptr addrspace(7) %p, i32 %off.clamped
+ %ret = load <8 x half>, ptr addrspace(7) %q, align 2
+ ret <8 x half> %ret
+}
+
+define <8 x half> @bound_i45_2p32_plus_2p11(ptr addrspace(1) inreg %ptr, i32 %off) {
+; RECORDS32-LABEL: define <8 x half> @bound_i45_2p32_plus_2p11(
+; RECORDS32-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS32-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 4294969344, i32 0)
+; RECORDS32-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 4096)
+; RECORDS32-NEXT: [[RET_OFF_0:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_0:%.*]] = insertelement <8 x half> poison, half [[RET_OFF_0]], i64 0
+; RECORDS32-NEXT: [[Q_OFF_PTR_2:%.*]] = add i32 [[Q]], 2
+; RECORDS32-NEXT: [[RET_OFF_2:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_2]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_1:%.*]] = insertelement <8 x half> [[RET_SLICE_0]], half [[RET_OFF_2]], i64 1
+; RECORDS32-NEXT: [[Q_OFF_PTR_4:%.*]] = add i32 [[Q]], 4
+; RECORDS32-NEXT: [[RET_OFF_4:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_4]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_2:%.*]] = insertelement <8 x half> [[RET_SLICE_1]], half [[RET_OFF_4]], i64 2
+; RECORDS32-NEXT: [[Q_OFF_PTR_6:%.*]] = add i32 [[Q]], 6
+; RECORDS32-NEXT: [[RET_OFF_6:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_6]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_3:%.*]] = insertelement <8 x half> [[RET_SLICE_2]], half [[RET_OFF_6]], i64 3
+; RECORDS32-NEXT: [[Q_OFF_PTR_8:%.*]] = add i32 [[Q]], 8
+; RECORDS32-NEXT: [[RET_OFF_8:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_8]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_4:%.*]] = insertelement <8 x half> [[RET_SLICE_3]], half [[RET_OFF_8]], i64 4
+; RECORDS32-NEXT: [[Q_OFF_PTR_10:%.*]] = add i32 [[Q]], 10
+; RECORDS32-NEXT: [[RET_OFF_10:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_10]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_5:%.*]] = insertelement <8 x half> [[RET_SLICE_4]], half [[RET_OFF_10]], i64 5
+; RECORDS32-NEXT: [[Q_OFF_PTR_12:%.*]] = add i32 [[Q]], 12
+; RECORDS32-NEXT: [[RET_OFF_12:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_12]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET_SLICE_6:%.*]] = insertelement <8 x half> [[RET_SLICE_5]], half [[RET_OFF_12]], i64 6
+; RECORDS32-NEXT: [[Q_OFF_PTR_14:%.*]] = add i32 [[Q]], 14
+; RECORDS32-NEXT: [[RET_OFF_14:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_14]], i32 0, i32 0)
+; RECORDS32-NEXT: [[RET:%.*]] = insertelement <8 x half> [[RET_SLICE_6]], half [[RET_OFF_14]], i64 7
+; RECORDS32-NEXT: ret <8 x half> [[RET]]
+;
+; RECORDS45-LABEL: define <8 x half> @bound_i45_2p32_plus_2p11(
+; RECORDS45-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS45-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 4294969344, i32 0)
+; RECORDS45-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 4096)
+; RECORDS45-NEXT: [[RET:%.*]] = call <8 x half> @llvm.amdgcn.raw.ptr.buffer.load.v8f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; RECORDS45-NEXT: ret <8 x half> [[RET]]
+;
+; UNKNOWN-LABEL: define <8 x half> @bound_i45_2p32_plus_2p11(
+; UNKNOWN-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; UNKNOWN-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) [[PTR]], i16 0, i45 4294969344, i32 0)
+; UNKNOWN-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 4096)
+; UNKNOWN-NEXT: [[RET_OFF_0:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_0:%.*]] = insertelement <8 x half> poison, half [[RET_OFF_0]], i64 0
+; UNKNOWN-NEXT: [[Q_OFF_PTR_2:%.*]] = add i32 [[Q]], 2
+; UNKNOWN-NEXT: [[RET_OFF_2:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_2]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_1:%.*]] = insertelement <8 x half> [[RET_SLICE_0]], half [[RET_OFF_2]], i64 1
+; UNKNOWN-NEXT: [[Q_OFF_PTR_4:%.*]] = add i32 [[Q]], 4
+; UNKNOWN-NEXT: [[RET_OFF_4:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_4]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_2:%.*]] = insertelement <8 x half> [[RET_SLICE_1]], half [[RET_OFF_4]], i64 2
+; UNKNOWN-NEXT: [[Q_OFF_PTR_6:%.*]] = add i32 [[Q]], 6
+; UNKNOWN-NEXT: [[RET_OFF_6:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_6]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_3:%.*]] = insertelement <8 x half> [[RET_SLICE_2]], half [[RET_OFF_6]], i64 3
+; UNKNOWN-NEXT: [[Q_OFF_PTR_8:%.*]] = add i32 [[Q]], 8
+; UNKNOWN-NEXT: [[RET_OFF_8:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_8]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_4:%.*]] = insertelement <8 x half> [[RET_SLICE_3]], half [[RET_OFF_8]], i64 4
+; UNKNOWN-NEXT: [[Q_OFF_PTR_10:%.*]] = add i32 [[Q]], 10
+; UNKNOWN-NEXT: [[RET_OFF_10:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_10]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_5:%.*]] = insertelement <8 x half> [[RET_SLICE_4]], half [[RET_OFF_10]], i64 5
+; UNKNOWN-NEXT: [[Q_OFF_PTR_12:%.*]] = add i32 [[Q]], 12
+; UNKNOWN-NEXT: [[RET_OFF_12:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_12]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET_SLICE_6:%.*]] = insertelement <8 x half> [[RET_SLICE_5]], half [[RET_OFF_12]], i64 6
+; UNKNOWN-NEXT: [[Q_OFF_PTR_14:%.*]] = add i32 [[Q]], 14
+; UNKNOWN-NEXT: [[RET_OFF_14:%.*]] = call half @llvm.amdgcn.raw.ptr.buffer.load.f16(ptr addrspace(8) align 2 [[BUF]], i32 [[Q_OFF_PTR_14]], i32 0, i32 0)
+; UNKNOWN-NEXT: [[RET:%.*]] = insertelement <8 x half> [[RET_SLICE_6]], half [[RET_OFF_14]], i64 7
+; UNKNOWN-NEXT: ret <8 x half> [[RET]]
+;
+ %buf = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i45(ptr addrspace(1) %ptr, i16 0, i45 4294969344, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 4096)
+ %q = getelementptr i8, ptr addrspace(7) %p, i32 %off.clamped
+ %ret = load <8 x half>, ptr addrspace(7) %q, align 2
+ ret <8 x half> %ret
+}
+
+!llvm.module.flags = !{!0}
+;; Strict buffer OOB mode
+!0 = !{i32 7, !"amdgpu.buffer.oob.mode", i32 2}
>From b09a1d80a9ef85efca67e080d0e13322d6498ec0 Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Tue, 18 Aug 2026 21:45:56 +0000
Subject: [PATCH 2/2] Update generic target to something better
---
.../AMDGPU/lower-buffer-fat-pointers-num-records-width.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
index 851cb7fd87336..cb51c48b01a42 100644
--- a/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
+++ b/llvm/test/CodeGen/AMDGPU/lower-buffer-fat-pointers-num-records-width.ll
@@ -2,7 +2,7 @@
; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgpu9.00-- -mattr=+unaligned-access-mode < %s | FileCheck %s --check-prefixes=CHECK,RECORDS32
; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgpu12.50-- -mattr=+unaligned-access-mode < %s | FileCheck %s --check-prefixes=CHECK,RECORDS45
;; alignment reasons instead.
-; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgcn-- -mattr=+unaligned-access-mode,+unaligned-buffer-access < %s | FileCheck %s --check-prefixes=CHECK,UNKNOWN
+; RUN: opt -S -passes=amdgpu-lower-buffer-fat-pointers -mtriple=amdgpu-- -mattr=+unaligned-access-mode,+unaligned-buffer-access < %s | FileCheck %s --check-prefixes=CHECK,UNKNOWN
; Ensure that "this isn't out of bounds" tests work correctly even when
; when size manipulation is needed.
More information about the llvm-branch-commits
mailing list