[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 02:00:07 PDT 2026
================
@@ -0,0 +1,181 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mcpu=gfx1201 -S -passes=instcombine -mtriple=amdgcn-amd-amdhsa %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_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 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
+}
+
----------------
barbara-amd wrote:
Added f16-typed coverage in store_2darray_zero_slice_f16 and load_2darray_zero_slice_f16 (using <4 x half> / .v4f16).
https://github.com/llvm/llvm-project/pull/214744
More information about the llvm-commits
mailing list