[llvm] 04ea62b - [AMDGPU] Fix miscompile trimming sparse DMask on image stores (#213586)

via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 22:25:04 PDT 2026


Author: Arseniy Obolenskiy
Date: 2026-08-03T07:25:00+02:00
New Revision: 04ea62bc5e2c5596866de7ee6a9c3a8b6aa54d35

URL: https://github.com/llvm/llvm-project/commit/04ea62bc5e2c5596866de7ee6a9c3a8b6aa54d35
DIFF: https://github.com/llvm/llvm-project/commit/04ea62bc5e2c5596866de7ee6a9c3a8b6aa54d35.diff

LOG: [AMDGPU] Fix miscompile trimming sparse DMask on image stores (#213586)

Dropping a channel from a sparse DMask removes that write entirely

It does not zero-fill like a contiguous trim does

Only simplify stores when DMask is a contiguous prefix

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
    llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-buffer-stores.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
index cbda99ae7d33c..7e88334f70993 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstCombineIntrinsic.cpp
@@ -2395,6 +2395,9 @@ static Value *simplifyAMDGCNMemoryIntrinsicDemanded(InstCombiner &IC,
     if (DMaskVal == 0)
       return nullptr;
 
+    if (!IsLoad && !isMask_32(DMaskVal))
+      return nullptr;
+
     // Mask off values that are undefined because the dmask doesn't cover them
     DemandedElts &= (1 << llvm::popcount(DMaskVal)) - 1;
 

diff  --git a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-buffer-stores.ll b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-buffer-stores.ll
index ce36325731b81..1745e55294941 100644
--- a/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-buffer-stores.ll
+++ b/llvm/test/Transforms/InstCombine/AMDGPU/amdgcn-simplify-image-buffer-stores.ll
@@ -37,7 +37,7 @@ define amdgpu_ps void @image_store_1d_store_insert_zeros_at_end(<8 x i32> inreg
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.image.store.1d.v4f32.i32.v8i32(<4 x float> [[NEWVDATA4]], i32 15, i32 [[S:%.*]], <8 x i32> [[RSRC:%.*]], i32 0, i32 0)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float %vdata1, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float %vdata1, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float 0.0, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float 0.0, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float 0.0, i32 3
@@ -64,7 +64,7 @@ define amdgpu_ps void @image_store_mip_1d_store_insert_zeros_at_end(<8 x i32> in
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.image.store.1d.v4f32.i32.v8i32(<4 x float> [[NEWVDATA4]], i32 7, i32 [[S:%.*]], <8 x i32> [[RSRC:%.*]], i32 0, i32 0)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float 0.0, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float 0.0, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float %vdata1, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float %vdata2, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float 0.0, i32 3
@@ -72,6 +72,28 @@ define amdgpu_ps void @image_store_mip_1d_store_insert_zeros_at_end(<8 x i32> in
   ret void
 }
 
+define amdgpu_ps void @image_store_1d_store_sparse_dmask_zero_at_end(<8 x i32> inreg %rsrc, float %vdata1, i32 %s) #0 {
+; GCN-LABEL: @image_store_1d_store_sparse_dmask_zero_at_end(
+; GCN-NEXT:    [[NEWVDATA2:%.*]] = insertelement <2 x float> <float poison, float 0.000000e+00>, float [[VDATA1:%.*]], i64 0
+; GCN-NEXT:    call void @llvm.amdgcn.image.store.1d.v2f32.i32.v8i32(<2 x float> [[NEWVDATA2]], i32 10, i32 [[S:%.*]], <8 x i32> [[RSRC:%.*]], i32 0, i32 0)
+; GCN-NEXT:    ret void
+;
+; GFX12-LABEL: @image_store_1d_store_sparse_dmask_zero_at_end(
+; GFX12-NEXT:    [[NEWVDATA2:%.*]] = insertelement <2 x float> <float poison, float 0.000000e+00>, float [[VDATA1:%.*]], i64 0
+; GFX12-NEXT:    call void @llvm.amdgcn.image.store.1d.v2f32.i32.v8i32(<2 x float> [[NEWVDATA2]], i32 10, i32 [[S:%.*]], <8 x i32> [[RSRC:%.*]], i32 0, i32 0)
+; GFX12-NEXT:    ret void
+;
+; GFXUNKNOWN-LABEL: @image_store_1d_store_sparse_dmask_zero_at_end(
+; GFXUNKNOWN-NEXT:    [[NEWVDATA2:%.*]] = insertelement <2 x float> <float poison, float 0.000000e+00>, float [[VDATA1:%.*]], i64 0
+; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.image.store.1d.v2f32.i32.v8i32(<2 x float> [[NEWVDATA2]], i32 10, i32 [[S:%.*]], <8 x i32> [[RSRC:%.*]], i32 0, i32 0)
+; GFXUNKNOWN-NEXT:    ret void
+;
+  %newvdata1 = insertelement <2 x float> poison, float %vdata1, i32 0
+  %newvdata2 = insertelement <2 x float> %newvdata1, float 0.0, i32 1
+  call void @llvm.amdgcn.image.store.1d.v2f32.i32.v8i32(<2 x float> %newvdata2, i32 10, i32 %s, <8 x i32> %rsrc, i32 0, i32 0)
+  ret void
+}
+
 define amdgpu_ps void @struct_buffer_store_format_insert_zeros(<4 x i32> inreg %a, float %vdata1, i32 %b) {
 ; GCN-LABEL: @struct_buffer_store_format_insert_zeros(
 ; GCN-NEXT:    [[TMP1:%.*]] = insertelement <3 x float> <float poison, float 0.000000e+00, float poison>, float [[VDATA1:%.*]], i64 0
@@ -91,7 +113,7 @@ define amdgpu_ps void @struct_buffer_store_format_insert_zeros(<4 x i32> inreg %
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float> [[NEWVDATA4]], <4 x i32> [[A:%.*]], i32 [[B:%.*]], i32 0, i32 42, i32 0)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float %vdata1, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float %vdata1, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float 0.0, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float %vdata1, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float 0.0, i32 3
@@ -115,7 +137,7 @@ define amdgpu_ps void @struct_tbuffer_store_insert_zeros_at_beginning(<4 x i32>
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.struct.tbuffer.store.v4f32(<4 x float> [[NEWVDATA4]], <4 x i32> [[A:%.*]], i32 [[B:%.*]], i32 0, i32 42, i32 0, i32 15)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float 0.0, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float 0.0, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float 0.0, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float 0.0, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float %vdata1, i32 3
@@ -204,7 +226,7 @@ define amdgpu_ps void @struct_buffer_store_format_insert_first_at_end(<4 x i32>
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float> [[NEWVDATA4]], <4 x i32> [[A:%.*]], i32 [[B:%.*]], i32 0, i32 42, i32 0)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float %vdata1, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float %vdata1, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float 0.0, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float %vdata1, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float %vdata1, i32 3
@@ -230,7 +252,7 @@ define amdgpu_ps void @struct_tbuffer_store_insert(<4 x i32> inreg %a, float %vd
 ; GFXUNKNOWN-NEXT:    call void @llvm.amdgcn.struct.tbuffer.store.v4f32(<4 x float> [[NEWVDATA4]], <4 x i32> [[A:%.*]], i32 [[B:%.*]], i32 0, i32 42, i32 0, i32 15)
 ; GFXUNKNOWN-NEXT:    ret void
 ;
-  %newvdata1 = insertelement <4 x float> undef, float %vdata1, i32 0
+  %newvdata1 = insertelement <4 x float> poison, float %vdata1, i32 0
   %newvdata2 = insertelement <4 x float> %newvdata1, float 1.0, i32 1
   %newvdata3 = insertelement <4 x float> %newvdata2, float 2.0, i32 2
   %newvdata4 = insertelement <4 x float> %newvdata3, float %vdata1, i32 3
@@ -280,6 +302,7 @@ declare void @llvm.amdgcn.raw.buffer.store.format.v4f32(<4 x float>, <4 x i32>,
 declare void @llvm.amdgcn.struct.buffer.store.format.v4f32(<4 x float>, <4 x i32>, i32, i32, i32, i32) #2
 declare void @llvm.amdgcn.struct.tbuffer.store.v4f32(<4 x float>, <4 x i32>, i32, i32, i32, i32, i32) #0
 declare void @llvm.amdgcn.raw.tbuffer.store.v4f32(<4 x float>, <4 x i32>, i32, i32, i32, i32) #0
+declare void @llvm.amdgcn.image.store.1d.v2f32.i32.v8i32(<2 x float>, i32, i32, <8 x i32>, i32, i32) #0
 declare void @llvm.amdgcn.image.store.1d.v4f32.i32.v8i32(<4 x float>, i32, i32, <8 x i32>, i32, i32) #0
 declare void @llvm.amdgcn.image.store.2d.v4f32.i32.v8i32(<4 x float>, 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


        


More information about the llvm-commits mailing list