[llvm] [AMDGPU] Fold image load/store with known-zero slice index to non-arrayed form (PR #214744)
Barbara Mitic via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 10 01:54:20 PDT 2026
https://github.com/barbara-amd updated https://github.com/llvm/llvm-project/pull/214744
>From 859fd11516a0630586a606cf2d97f2ded3570c66 Mon Sep 17 00:00:00 2001
From: barbara-amd <Barbara.Mitic at amd.com>
Date: Thu, 6 Aug 2026 16:07:29 +0200
Subject: [PATCH] [AMDGPU] Fold image load/store with known-zero slice index to
non-arrayed form
Fold an arrayed image load or store whose array slice is a known-zero
constant into the equivalent non-arrayed op, dropping the slice
coordinate. Slice 0 is the base layer, which is the texel the
non-arrayed op addresses. Dropping the coordinate also removes the
materialization of the zero, freeing a VGPR.
Covers 1D_ARRAY -> 1D, 2D_ARRAY -> 2D and 2D_MSAA_ARRAY -> 2D_MSAA,
keeping fragid for the MSAA case. The mapping is a new NonArrayDim
field on MIMGDimInfo, defaulting to the dim itself so that CUBE,
whose extra component is a face rather than a layer, is left alone.
Sampled ops and atomics are not folded for now.
---
llvm/include/llvm/IR/IntrinsicsAMDGPU.td | 7 +
.../AMDGPU/AMDGPUInstCombineIntrinsic.cpp | 33 ++-
llvm/lib/Target/AMDGPU/MIMGInstructions.td | 4 +-
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h | 1 +
.../amdgcn-simplify-image-array-zero-slice.ll | 203 ++++++++++++++++++
5 files changed, 241 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-array-zero-slice.ll
diff --git a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
index 9c57b4d343fc6..be939f8e6531e 100644
--- a/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -989,6 +989,10 @@ class AMDGPUDimProps<bits<3> enc, string name, string asmsuffix,
bit DA = 0; // DA bit in MIMG encoding
bit MSAA = msaa;
+ // The corresponding non-arrayed dim, e.g. 2D_ARRAY -> 2D. Defaults to Dim.
+ // The arrayed dims override it below.
+ AMDGPUDimProps NonArrayDim = Dim;
+
list<AMDGPUArg> CoordSliceArgs =
makeArgList<!listconcat(coord_names, slice_names), llvm_anyfloat_ty>.ret;
list<AMDGPUArg> CoordSliceIntArgs =
@@ -1007,11 +1011,14 @@ def AMDGPUDim2D : AMDGPUDimProps<0x1, "2d", "2D", ["s", "t"], []>;
def AMDGPUDim3D : AMDGPUDimProps<0x2, "3d", "3D", ["s", "t", "r"], []>;
let DA = 1 in {
def AMDGPUDimCube : AMDGPUDimProps<0x3, "cube", "CUBE", ["s", "t"], ["face"]>;
+ let NonArrayDim = AMDGPUDim1D in
def AMDGPUDim1DArray : AMDGPUDimProps<0x4, "1darray", "1D_ARRAY", ["s"], ["slice"]>;
+ let NonArrayDim = AMDGPUDim2D in
def AMDGPUDim2DArray : AMDGPUDimProps<0x5, "2darray", "2D_ARRAY", ["s", "t"], ["slice"]>;
}
def AMDGPUDim2DMsaa : AMDGPUDimProps<0x6, "2dmsaa", "2D_MSAA", ["s", "t"], ["fragid"], 1>;
let DA = 1 in {
+ let NonArrayDim = AMDGPUDim2DMsaa in
def AMDGPUDim2DArrayMsaa : AMDGPUDimProps<0x7, "2darraymsaa", "2D_MSAA_ARRAY", ["s", "t"], ["slice", "fragid"], 1>;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index 7e88334f70993..95143f27aacf3 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -182,6 +182,9 @@ static std::optional<Instruction *>
simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST,
const AMDGPU::ImageDimIntrinsicInfo *ImageDimIntr,
IntrinsicInst &II, InstCombiner &IC) {
+ const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
+ AMDGPU::getMIMGBaseOpcodeInfo(ImageDimIntr->BaseOpcode);
+
// Optimize _L to _LZ when _L is zero
if (const auto *LZMappingInfo =
AMDGPU::getMIMGLZMappingInfo(ImageDimIntr->BaseOpcode)) {
@@ -251,12 +254,31 @@ simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST,
}
}
+ // Optimize the arrayed dim away when the array slice is zero, since slice 0
+ // is the base layer. Restricted to plain image loads and stores for now.
+ const AMDGPU::MIMGDimInfo *DimInfo =
+ AMDGPU::getMIMGDimInfo(ImageDimIntr->Dim);
+ if (!BaseOpcode->Atomic && !BaseOpcode->Sampler && BaseOpcode->Coordinates &&
+ DimInfo->NonArrayDim != ImageDimIntr->Dim) {
+ // Address is [coords..., slice, (fragid)] plus an optional lod/clamp/mip,
+ // so index from CoordStart.
+ unsigned SliceIndex = ImageDimIntr->CoordStart + DimInfo->NumCoords - 1 -
+ (DimInfo->MSAA ? 1 : 0);
+ auto *ConstantSlice = dyn_cast<ConstantInt>(II.getOperand(SliceIndex));
+ if (ConstantSlice && ConstantSlice->isZero()) {
+ if (const AMDGPU::ImageDimIntrinsicInfo *NewImageDimIntr =
+ AMDGPU::getImageDimIntrinsicByBaseOpcode(ImageDimIntr->BaseOpcode,
+ DimInfo->NonArrayDim)) {
+ return modifyIntrinsicCall(II, II, NewImageDimIntr->Intr, IC,
+ [&](auto &Args, auto &ArgTys) {
+ Args.erase(Args.begin() + SliceIndex);
+ });
+ }
+ }
+ }
+
// Try to use D16
if (ST->hasD16Images()) {
-
- const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
- AMDGPU::getMIMGBaseOpcodeInfo(ImageDimIntr->BaseOpcode);
-
if (BaseOpcode->HasD16) {
// If the only use of image intrinsic is a fptrunc (with conversion to
@@ -346,8 +368,7 @@ simplifyAMDGCNImageIntrinsic(const GCNSubtarget *ST,
// Address is interpreted as float if the instruction has a sampler or as
// unsigned int if there is no sampler.
- bool HasSampler =
- AMDGPU::getMIMGBaseOpcodeInfo(ImageDimIntr->BaseOpcode)->Sampler;
+ bool HasSampler = BaseOpcode->Sampler;
bool FloatCoord = false;
// true means derivatives can be converted to 16 bit, coordinates not
bool OnlyDerivatives = false;
diff --git a/llvm/lib/Target/AMDGPU/MIMGInstructions.td b/llvm/lib/Target/AMDGPU/MIMGInstructions.td
index cb554073f6398..1a4cd39cabfff 100644
--- a/llvm/lib/Target/AMDGPU/MIMGInstructions.td
+++ b/llvm/lib/Target/AMDGPU/MIMGInstructions.td
@@ -80,8 +80,10 @@ def MIMGDim : GenericEnum {
def MIMGDimInfoTable : GenericTable {
let FilterClass = "AMDGPUDimProps";
let CppTypeName = "MIMGDimInfo";
- let Fields = ["Dim", "NumCoords", "NumGradients", "MSAA", "DA", "Encoding", "AsmSuffix"];
+ let Fields = ["Dim", "NonArrayDim", "NumCoords", "NumGradients", "MSAA", "DA",
+ "Encoding", "AsmSuffix"];
string TypeOf_Dim = "MIMGDim";
+ string TypeOf_NonArrayDim = "MIMGDim";
let PrimaryKey = ["Dim"];
let PrimaryKeyName = "getMIMGDimInfo";
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 44476d4d555c0..dd76ae0c3af99 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -410,6 +410,7 @@ const MIMGBaseOpcodeInfo *getMIMGBaseOpcodeInfo(unsigned BaseOpcode);
struct MIMGDimInfo {
MIMGDim Dim;
+ MIMGDim NonArrayDim;
uint8_t NumCoords;
uint8_t NumGradients;
bool MSAA;
diff --git a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-array-zero-slice.ll b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-array-zero-slice.ll
new file mode 100644
index 0000000000000..b2cef5a2bf011
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-array-zero-slice.ll
@@ -0,0 +1,203 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine -mtriple=amdgpu12.01 %s | FileCheck %s
+
+define amdgpu_ps void @store_1darray_zero_slice(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_1darray_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.1d.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.1darray.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_2darray_zero_slice(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darray_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2d.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_2darray_zero_slice_f16(<8 x i32> inreg %rsrc, <4 x half> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darray_zero_slice_f16(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x half> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2d.v4f16.i32.v8i32(<4 x half> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darray.v4f16.i32.v8i32(<4 x half> %vdata, i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_2darraymsaa_zero_slice(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t, i32 %fragid) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darraymsaa_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]], i32 [[FRAGID:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2dmsaa.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 [[FRAGID]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darraymsaa.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 0, i32 %fragid, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_mip_2darray_zero_slice_nonzero_mip(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_mip_2darray_zero_slice_nonzero_mip(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.mip.2d.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 2, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.mip.2darray.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 0, i32 2, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_2darray_zero_slice_a16(<8 x i32> inreg %rsrc, <4 x float> %vdata, i16 %s, i16 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darray_zero_slice_a16(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i16 [[S:%.*]], i16 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2d.v4f32.i16.v8i32(<4 x float> [[VDATA]], i32 15, i16 [[S]], i16 [[T]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darray.v4f32.i16.v8i32(<4 x float> %vdata, i32 15, i16 %s, i16 %t, i16 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps <4 x float> @load_1darray_zero_slice(<8 x i32> inreg %rsrc, i32 %s) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @load_1darray_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[S:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.load.1d.v4f32.i32.v8i32(i32 15, i32 [[S]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.load.1darray.v4f32.i32.v8i32(i32 15, i32 %s, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps <4 x float> @load_2darray_zero_slice(<8 x i32> inreg %rsrc, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @load_2darray_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.load.2d.v4f32.i32.v8i32(i32 15, i32 [[S]], i32 [[T]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.load.2darray.v4f32.i32.v8i32(i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps <4 x half> @load_2darray_zero_slice_f16(<8 x i32> inreg %rsrc, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x half> @load_2darray_zero_slice_f16(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x half> @llvm.amdgcn.image.load.2d.v4f16.i32.v8i32(i32 15, i32 [[S]], i32 [[T]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x half> [[V]]
+;
+ %v = call <4 x half> @llvm.amdgcn.image.load.2darray.v4f16.i32.v8i32(i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x half> %v
+}
+
+define amdgpu_ps <4 x float> @load_2darraymsaa_zero_slice(<8 x i32> inreg %rsrc, i32 %s, i32 %t, i32 %fragid) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @load_2darraymsaa_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[S:%.*]], i32 [[T:%.*]], i32 [[FRAGID:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.load.2dmsaa.v4f32.i32.v8i32(i32 15, i32 [[S]], i32 [[T]], i32 [[FRAGID]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.load.2darraymsaa.v4f32.i32.v8i32(i32 15, i32 %s, i32 %t, i32 0, i32 %fragid, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps <4 x float> @msaa_load_x_2darraymsaa_zero_slice(<8 x i32> inreg %rsrc, i32 %s, i32 %t, i32 %fragid) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @msaa_load_x_2darraymsaa_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[S:%.*]], i32 [[T:%.*]], i32 [[FRAGID:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.msaa.load.x.2dmsaa.v4f32.i32.v8i32(i32 15, i32 [[S]], i32 [[T]], i32 [[FRAGID]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.msaa.load.x.2darraymsaa.v4f32.i32.v8i32(i32 15, i32 %s, i32 %t, i32 0, i32 %fragid, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps void @store_2darray_nonzero_slice(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darray_nonzero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 1, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 1, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_2darray_variable_slice(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t, i32 %slice) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_2darray_variable_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]], i32 [[SLICE:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 [[SLICE]], <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 %slice, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_cube_zero_face(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_cube_zero_face(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.cube.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 0, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.cube.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps void @store_3d_zero_r(<8 x i32> inreg %rsrc, <4 x float> %vdata, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps void @store_3d_zero_r(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x float> [[VDATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: call void @llvm.amdgcn.image.store.3d.v4f32.i32.v8i32(<4 x float> [[VDATA]], i32 15, i32 [[S]], i32 [[T]], i32 0, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret void
+;
+ call void @llvm.amdgcn.image.store.3d.v4f32.i32.v8i32(<4 x float> %vdata, i32 15, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret void
+}
+
+define amdgpu_ps <4 x float> @getresinfo_2darray_zero_mip(<8 x i32> inreg %rsrc) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @getresinfo_2darray_zero_mip(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.getresinfo.2darray.v4f32.i16.v8i32(i32 15, i16 0, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.getresinfo.2darray.v4f32.i32.v8i32(i32 15, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps <4 x float> @sample_cl_2darray_zero_slice_zero_clamp(<8 x i32> inreg %rsrc, <4 x i32> inreg %samp, float %s, float %t) #0 {
+; CHECK-LABEL: define amdgpu_ps <4 x float> @sample_cl_2darray_zero_slice_zero_clamp(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], <4 x i32> inreg [[SAMP:%.*]], float [[S:%.*]], float [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call <4 x float> @llvm.amdgcn.image.sample.cl.2darray.v4f32.f32.v8i32.v4i32(i32 15, float [[S]], float [[T]], float 0.000000e+00, float 0.000000e+00, <8 x i32> [[RSRC]], <4 x i32> [[SAMP]], i1 false, i32 0, i32 0)
+; CHECK-NEXT: ret <4 x float> [[V]]
+;
+ %v = call <4 x float> @llvm.amdgcn.image.sample.cl.2darray.v4f32.f32.v8i32.v4i32(i32 15, float %s, float %t, float 0.0, float 0.0, <8 x i32> %rsrc, <4 x i32> %samp, i1 false, i32 0, i32 0)
+ ret <4 x float> %v
+}
+
+define amdgpu_ps i32 @atomic_add_2darray_zero_slice(<8 x i32> inreg %rsrc, i32 %data, i32 %s, i32 %t) #0 {
+; CHECK-LABEL: define amdgpu_ps i32 @atomic_add_2darray_zero_slice(
+; CHECK-SAME: <8 x i32> inreg [[RSRC:%.*]], i32 [[DATA:%.*]], i32 [[S:%.*]], i32 [[T:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[V:%.*]] = call i32 @llvm.amdgcn.image.atomic.add.2darray.i32.i32.v8i32(i32 [[DATA]], i32 [[S]], i32 [[T]], i32 0, <8 x i32> [[RSRC]], i32 0, i32 0)
+; CHECK-NEXT: ret i32 [[V]]
+;
+ %v = call i32 @llvm.amdgcn.image.atomic.add.2darray.i32.i32.v8i32(i32 %data, i32 %s, i32 %t, i32 0, <8 x i32> %rsrc, i32 0, i32 0)
+ ret i32 %v
+}
+
+declare void @llvm.amdgcn.image.store.1darray.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.2darray.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.2darray.v4f16.i32.v8i32(<4 x half>, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.2darray.v4f32.i16.v8i32(<4 x float>, i32, i16, i16, i16, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.2darraymsaa.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.mip.2darray.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.cube.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare void @llvm.amdgcn.image.store.3d.v4f32.i32.v8i32(<4 x float>, i32, i32, i32, i32, <8 x i32>, i32, i32) #0
+declare <4 x float> @llvm.amdgcn.image.load.1darray.v4f32.i32.v8i32(i32, i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x float> @llvm.amdgcn.image.load.2darray.v4f32.i32.v8i32(i32, i32, i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x half> @llvm.amdgcn.image.load.2darray.v4f16.i32.v8i32(i32, i32, i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x float> @llvm.amdgcn.image.load.2darraymsaa.v4f32.i32.v8i32(i32, i32, i32, i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x float> @llvm.amdgcn.image.msaa.load.x.2darraymsaa.v4f32.i32.v8i32(i32, i32, i32, i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x float> @llvm.amdgcn.image.getresinfo.2darray.v4f32.i32.v8i32(i32, i32, <8 x i32>, i32, i32) #1
+declare <4 x float> @llvm.amdgcn.image.sample.cl.2darray.v4f32.f32.v8i32.v4i32(i32, float, float, float, float, <8 x i32>, <4 x i32>, i1, i32, i32) #1
+declare i32 @llvm.amdgcn.image.atomic.add.2darray.i32.i32.v8i32(i32, i32, i32, i32, <8 x i32>, i32, i32) #2
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readonly }
+attributes #2 = { nounwind }
More information about the llvm-commits
mailing list