[llvm-branch-commits] [llvm] [AMDGPU] Use real num_records width in LowerBufferFatPointers (PR #217138)
Krzysztof Drewniak via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 25 08:05:56 PDT 2026
https://github.com/krzysz00 updated https://github.com/llvm/llvm-project/pull/217138
>From d996ce7ef78e81bf86b5fdc7c90f497b76a056ef Mon Sep 17 00:00:00 2001
From: Krzysztof Drewniak <Krzysztof.Drewniak at amd.com>
Date: Tue, 18 Aug 2026 19:36:59 +0000
Subject: [PATCH] [AMDGPU] Use real num_records width in LowerBufferFatPointers
Fix the following edge cases in reasoning about whether a value can be
The out-of-bounds analysis in LowerBufferFatPointers took the
num_records operand of llvm.amdgcn.make.buffer.rsrc at face value, which
went wrong in three ways.
1. The pass would crash if num_records was narrower than the
underlying hardware width.
2. A 45-bit num_records with its high bit set made all offsets look
negative, which, among other things, broke the `(1 << 45) - 1` "no
bounds checking" value.
3. The test for all-1 num_records wasn't accounting for hardware
width, leading to false positives if the num_records field was
narrower tan the underlying field.
4. Don't try to do reasoning about num_records when its width isn't
known.
AI disclosure: Claude found and took a try at fixing these, I've
reviewed
---
.../AMDGPU/AMDGPULowerBufferFatPointers.cpp | 32 ++-
...r-buffer-fat-pointers-num-records-width.ll | 258 ++++++++++++++----
2 files changed, 218 insertions(+), 72 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index 236d8e619a5ec..39653fc985e5c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -886,21 +886,27 @@ LegalizeBufferContentTypesVisitor::analyzeOobProperties(Value *Ptr, Type *Ty,
if (!NumRecordsIfKnown->second)
return Result;
const SCEV *NumRecords = SE->getSCEV(NumRecordsIfKnown->second);
- // All-1s is (per ISA or as a consequence of the bonud)check rules, depending
- // on arcihtecture) no bounds check.
- if (NumRecords->isAllOnesValue())
+
+ // We'll normalize all bounds to the num_records width on the hardware.
+ std::optional<unsigned> MaybeNumRecordsWidth =
+ ST->getBufferResourceNumRecordsWidth();
+ if (!MaybeNumRecordsWidth)
+ return Result;
+ unsigned NumRecordsWidth = *MaybeNumRecordsWidth;
+ Type *NumRecordsTy = IRB.getIntNTy(NumRecordsWidth);
+ // Compare in i64 so wraparound is visible as a negative.
+ Type *CompareTy = IRB.getInt64Ty();
+ const SCEV *Bound = SE->getNoopOrZeroExtend(
+ SE->getTruncateOrZeroExtend(NumRecords, NumRecordsTy), CompareTy);
+
+ // All-1s is (per ISA or as a consequence of the bounds check rules, depending
+ // on architecture) no bounds check.
+ if (Bound == SE->getConstant(APInt::getMaxValue(NumRecordsWidth)
+ .zext(CompareTy->getIntegerBitWidth())))
Result.NoPartialOOB = true;
- const SCEV *BoundsDiff;
- if (ST->getBufferResourceNumRecordsWidth() == 45) {
- const SCEV *PtrDiffExt =
- SE->getNoopOrZeroExtend(PtrDiff, NumRecords->getType());
- BoundsDiff = SE->getMinusSCEV(NumRecords, PtrDiffExt);
- } else {
- const SCEV *NumRecordsI32 =
- SE->getTruncateOrNoop(NumRecords, IRB.getInt32Ty());
- BoundsDiff = SE->getMinusSCEV(NumRecordsI32, PtrDiff);
- }
+ const SCEV *BoundsDiff =
+ SE->getMinusSCEV(Bound, SE->getNoopOrZeroExtend(PtrDiff, CompareTy));
if (SE->getSignedRangeMin(BoundsDiff).sge(TypeSize) ||
SE->isKnownNonPositive(BoundsDiff))
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 e6aace5be6d36..029d80afbaf68 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
@@ -8,12 +8,48 @@
;; Make sure this always works with 2^44, even on 32-bit num_records.
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]]
+; RECORDS32-LABEL: define <8 x half> @bound_i64_2p44(
+; RECORDS32-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0:[0-9]+]] {
+; RECORDS32-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i64(ptr addrspace(1) [[PTR]], i16 0, i64 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_i64_2p44(
+; RECORDS45-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0:[0-9]+]] {
+; RECORDS45-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i64(ptr addrspace(1) [[PTR]], i16 0, i64 17592186044416, i32 0)
+; RECORDS45-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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_i64_2p44(
+; UNKNOWN-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0:[0-9]+]] {
+; UNKNOWN-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i64(ptr addrspace(1) [[PTR]], i16 0, i64 17592186044416, i32 0)
+; UNKNOWN-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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.i64(ptr addrspace(1) %ptr, i16 0, i64 17592186044416, i32 0)
%p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
@@ -36,36 +72,36 @@ define <8 x half> @bound_i45_2p44(ptr addrspace(1) inreg %ptr, i32 %off) {
; 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:%.*]] = 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_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_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 17592186044416, i32 0)
@@ -78,34 +114,48 @@ define <8 x half> @bound_i45_2p44(ptr addrspace(1) inreg %ptr, i32 %off) {
;; Bound is int32_max.
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]]
+; RECORDS32-LABEL: define <8 x half> @bound_i32_2p31(
+; RECORDS32-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS32-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) [[PTR]], i16 0, i32 -2147483648, 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_i32_2p31(
+; RECORDS45-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS45-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) [[PTR]], i16 0, i32 -2147483648, i32 0)
+; RECORDS45-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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_i32_2p31(
+; UNKNOWN-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; UNKNOWN-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i32(ptr addrspace(1) [[PTR]], i16 0, i32 -2147483648, i32 0)
+; UNKNOWN-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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.i32(ptr addrspace(1) %ptr, i16 0, i32 2147483648, i32 0)
%p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
@@ -119,7 +169,7 @@ define <8 x half> @bound_i32_2p31(ptr addrspace(1) inreg %ptr, i32 %off) {
;; scalarization, but not if we read num_records as a 45-bit value.
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-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.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)
@@ -229,6 +279,96 @@ define <8 x half> @bound_i45_2p32_plus_2p11(ptr addrspace(1) inreg %ptr, i32 %of
ret <8 x half> %ret
}
+define <8 x half> @bound_i16_all_ones_in_bounds(ptr addrspace(1) inreg %ptr, i32 %off) {
+; RECORDS32-LABEL: define <8 x half> @bound_i16_all_ones_in_bounds(
+; RECORDS32-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS32-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i16(ptr addrspace(1) [[PTR]], i16 0, i16 -1, 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_i16_all_ones_in_bounds(
+; RECORDS45-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; RECORDS45-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i16(ptr addrspace(1) [[PTR]], i16 0, i16 -1, i32 0)
+; RECORDS45-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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_i16_all_ones_in_bounds(
+; UNKNOWN-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; UNKNOWN-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i16(ptr addrspace(1) [[PTR]], i16 0, i16 -1, i32 0)
+; UNKNOWN-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 1024)
+; 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.i16(ptr addrspace(1) %ptr, i16 0, i16 -1, 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_i16_all_ones_partially_oob(ptr addrspace(1) inreg %ptr, i32 %off) {
+; CHECK-LABEL: define <8 x half> @bound_i16_all_ones_partially_oob(
+; CHECK-SAME: ptr addrspace(1) inreg [[PTR:%.*]], i32 [[OFF:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[BUF:%.*]] = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p1.i16(ptr addrspace(1) [[PTR]], i16 0, i16 -1, i32 0)
+; CHECK-NEXT: [[Q:%.*]] = call i32 @llvm.umin.i32(i32 [[OFF]], i32 65540)
+; 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.i16(ptr addrspace(1) %ptr, i16 0, i16 -1, i32 0)
+ %p = addrspacecast ptr addrspace(8) %buf to ptr addrspace(7)
+ %off.clamped = call i32 @llvm.umin.i32(i32 %off, i32 65540)
+ %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}
More information about the llvm-branch-commits
mailing list