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 <[email protected]> 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} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
