When executing a shader with WARP, with validation layer enabled (GBV), and compiling the shader with DXC, with the 6_6 target, there is a runtime hang.
This is the minimal offload test repro in HLSL:
RWStructuredBuffer<uint> Out : register(u0);
RWStructuredBuffer<uint> OutMono : register(u1);
RWByteAddressBuffer BABuf : register(u2);
RWStructuredBuffer<uint> OutMono2 : register(u3);
[numthreads(256, 1, 1)]
void main(uint3 GTID : SV_GroupThreadID) {
if (GTID.x == 0) {
Out[0] = 0u;
BABuf.Store(0, 0u);
}
DeviceMemoryBarrierWithGroupSync();
uint Acc = 0u;
for (uint I = 0; I < 2; ++I) {
InterlockedAdd(Out[0], 1u);
DeviceMemoryBarrierWithGroupSync();
Acc += Out[0];
}
OutMono[GTID.x] = Acc;
OutMono2[GTID.x] = 1u;
}
When WARP is the target and validation layer is enabled, and when DXC is the compiler, targeting 6_6 and executing the above shader hangs indefinitely.
Targeting SM 6.5 does not produce a hang, but 6.6 does.
Below are the IRs for 6.5 and 6.6 respectively.
6.5:
;
; Input signature:
;
; Name Index Mask Register SysValue Format Used
; -------------------- ----- ------ -------- -------- ------- ------
; no parameters
;
; Output signature:
;
; Name Index Mask Register SysValue Format Used
; -------------------- ----- ------ -------- -------- ------- ------
; no parameters
; shader hash: deea97080d919b7f52c81772339fee82
;
; Pipeline Runtime Information:
;
;PSVRuntimeInfo:
; Compute Shader
; NumThreads=(256,1,1)
; NumBytesGroupSharedMemory: 0
; MinimumExpectedWaveLaneCount: 0
; MaximumExpectedWaveLaneCount: 4294967295
; UsesViewID: false
; SigInputElements: 0
; SigOutputElements: 0
; SigPatchConstOrPrimElements: 0
; SigInputVectors: 0
; SigOutputVectors[0]: 0
; SigOutputVectors[1]: 0
; SigOutputVectors[2]: 0
; SigOutputVectors[3]: 0
; EntryFunctionName: main
;
;
; Buffer Definitions:
;
; Resource bind info for Out
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
; Resource bind info for OutMono
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
; Resource bind info for OutMono2
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
;
; Resource Bindings:
;
; Name Type Format Dim ID HLSL Bind Count
; ------------------------------ ---------- ------- ----------- ------- -------------- ------
; Out UAV struct r/w U0 u0 1
; OutMono UAV struct r/w U1 u1 1
; BABuf UAV byte r/w U2 u2 1
; OutMono2 UAV struct r/w U3 u3 1
;
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 }
%"class.RWStructuredBuffer<unsigned int>" = type { i32 }
%struct.RWByteAddressBuffer = type { i32 }
define void @main() {
%1 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 3, i32 3, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
%2 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 2, i32 2, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
%3 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 1, i32 1, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
%4 = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 1, i32 0, i32 0, i1 false) ; CreateHandle(resourceClass,rangeId,index,nonUniformIndex)
%5 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0) ; ThreadIdInGroup(component)
%6 = icmp eq i32 %5, 0
br i1 %6, label %7, label %8
; <label>:7 ; preds = %0
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %4, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %2, i32 0, i32 undef, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
br label %8
; <label>:8 ; preds = %7, %0
call void @dx.op.barrier(i32 80, i32 3) ; Barrier(barrierMode)
br label %9
; <label>:9 ; preds = %9, %8
%10 = phi i32 [ 0, %8 ], [ %15, %9 ]
%11 = phi i32 [ 0, %8 ], [ %16, %9 ]
%12 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %4, i32 0, i32 0, i32 0, i32 undef, i32 1) ; AtomicBinOp(handle,atomicOp,offset0,offset1,offset2,newValue)
call void @dx.op.barrier(i32 80, i32 3) ; Barrier(barrierMode)
%13 = call %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32 139, %dx.types.Handle %4, i32 0, i32 0, i8 1, i32 4) ; RawBufferLoad(srv,index,elementOffset,mask,alignment)
%14 = extractvalue %dx.types.ResRet.i32 %13, 0
%15 = add i32 %14, %10
%16 = add nuw nsw i32 %11, 1
%17 = icmp eq i32 %16, 2
br i1 %17, label %18, label %9
; <label>:18 ; preds = %9
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %3, i32 %5, i32 0, i32 %15, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %1, i32 %5, i32 0, i32 1, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadIdInGroup.i32(i32, i32) #0
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare i32 @dx.op.atomicBinOp.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32) #1
; Function Attrs: nounwind readonly
declare %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32, %dx.types.Handle, i32, i32, i8, i32) #2
; Function Attrs: noduplicate nounwind
declare void @dx.op.barrier(i32, i32) #3
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #2
attributes #0 = { nounwind readnone }
attributes #1 = { nounwind }
attributes #2 = { nounwind readonly }
attributes #3 = { noduplicate nounwind }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!2}
!dx.shaderModel = !{!3}
!dx.resources = !{!4}
!dx.entryPoints = !{!11}
!0 = !{!"dxc(private) 1.9.0.5364 (update_containertest_headers, 3aaa95da5)"}
!1 = !{i32 1, i32 5}
!2 = !{i32 1, i32 10}
!3 = !{!"cs", i32 6, i32 5}
!4 = !{null, !5, null, null}
!5 = !{!6, !8, !9, !10}
!6 = !{i32 0, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!7 = !{i32 1, i32 4}
!8 = !{i32 1, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!9 = !{i32 2, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 2, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!10 = !{i32 3, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 3, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!11 = !{void ()* @main, !"main", null, !4, !12}
!12 = !{i32 0, i64 16, i32 4, !13}
!13 = !{i32 256, i32 1, i32 1}
6.6:
;
; Input signature:
;
; Name Index Mask Register SysValue Format Used
; -------------------- ----- ------ -------- -------- ------- ------
; no parameters
;
; Output signature:
;
; Name Index Mask Register SysValue Format Used
; -------------------- ----- ------ -------- -------- ------- ------
; no parameters
; shader hash: 7dc7c169d0b5d2d8a75f41fcc3c286f2
;
; Pipeline Runtime Information:
;
;PSVRuntimeInfo:
; Compute Shader
; NumThreads=(256,1,1)
; NumBytesGroupSharedMemory: 0
; MinimumExpectedWaveLaneCount: 0
; MaximumExpectedWaveLaneCount: 4294967295
; UsesViewID: false
; SigInputElements: 0
; SigOutputElements: 0
; SigPatchConstOrPrimElements: 0
; SigInputVectors: 0
; SigOutputVectors[0]: 0
; SigOutputVectors[1]: 0
; SigOutputVectors[2]: 0
; SigOutputVectors[3]: 0
; EntryFunctionName: main
;
;
; Buffer Definitions:
;
; Resource bind info for Out
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
; Resource bind info for OutMono
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
; Resource bind info for OutMono2
; {
;
; uint $Element; ; Offset: 0 Size: 4
;
; }
;
;
; Resource Bindings:
;
; Name Type Format Dim ID HLSL Bind Count
; ------------------------------ ---------- ------- ----------- ------- -------------- ------
; Out UAV struct r/w U0 u0 1
; OutMono UAV struct r/w U1 u1 1
; BABuf UAV byte r/w U2 u2 1
; OutMono2 UAV struct r/w U3 u3 1
;
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResBind = type { i32, i32, i32, i8 }
%dx.types.ResourceProperties = type { i32, i32 }
%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 }
%"class.RWStructuredBuffer<unsigned int>" = type { i32 }
%struct.RWByteAddressBuffer = type { i32 }
define void @main() {
%1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 3, i32 3, i32 0, i8 1 }, i32 3, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex)
%2 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 2, i32 2, i32 0, i8 1 }, i32 2, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex)
%3 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 1, i32 1, i32 0, i8 1 }, i32 1, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex)
%4 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind { i32 0, i32 0, i32 0, i8 1 }, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex)
%5 = call i32 @dx.op.threadIdInGroup.i32(i32 95, i32 0) ; ThreadIdInGroup(component)
%6 = icmp eq i32 %5, 0
br i1 %6, label %7, label %10
; <label>:7 ; preds = %0
%8 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %4, %dx.types.ResourceProperties { i32 4108, i32 4 }) ; AnnotateHandle(res,props) resource: RWStructuredBuffer<stride=4>
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %8, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
%9 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %2, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %9, i32 0, i32 undef, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
br label %10
; <label>:10 ; preds = %7, %0
call void @dx.op.barrier(i32 80, i32 3) ; Barrier(barrierMode)
br label %14
; <label>:11 ; preds = %14
%12 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %3, %dx.types.ResourceProperties { i32 4108, i32 4 }) ; AnnotateHandle(res,props) resource: RWStructuredBuffer<stride=4>
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %12, i32 %5, i32 0, i32 %22, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
%13 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 4108, i32 4 }) ; AnnotateHandle(res,props) resource: RWStructuredBuffer<stride=4>
call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %13, i32 %5, i32 0, i32 1, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
; <label>:14 ; preds = %14, %10
%15 = phi i32 [ 0, %10 ], [ %22, %14 ]
%16 = phi i32 [ 0, %10 ], [ %23, %14 ]
%17 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %4, %dx.types.ResourceProperties { i32 4108, i32 4 }) ; AnnotateHandle(res,props) resource: RWStructuredBuffer<stride=4>
%18 = call i32 @dx.op.atomicBinOp.i32(i32 78, %dx.types.Handle %17, i32 0, i32 0, i32 0, i32 undef, i32 1) ; AtomicBinOp(handle,atomicOp,offset0,offset1,offset2,newValue)
call void @dx.op.barrier(i32 80, i32 3) ; Barrier(barrierMode)
%19 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %4, %dx.types.ResourceProperties { i32 4108, i32 4 }) ; AnnotateHandle(res,props) resource: RWStructuredBuffer<stride=4>
%20 = call %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32 139, %dx.types.Handle %19, i32 0, i32 0, i8 1, i32 4) ; RawBufferLoad(srv,index,elementOffset,mask,alignment)
%21 = extractvalue %dx.types.ResRet.i32 %20, 0
%22 = add i32 %21, %15
%23 = add nuw nsw i32 %16, 1
%24 = icmp eq i32 %23, 2
br i1 %24, label %11, label %14
}
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadIdInGroup.i32(i32, i32) #0
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare i32 @dx.op.atomicBinOp.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32) #1
; Function Attrs: nounwind readonly
declare %dx.types.ResRet.i32 @dx.op.rawBufferLoad.i32(i32, %dx.types.Handle, i32, i32, i8, i32) #2
; Function Attrs: noduplicate nounwind
declare void @dx.op.barrier(i32, i32) #3
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #0
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.createHandleFromBinding(i32, %dx.types.ResBind, i32, i1) #0
attributes #0 = { nounwind readnone }
attributes #1 = { nounwind }
attributes #2 = { nounwind readonly }
attributes #3 = { noduplicate nounwind }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!2}
!dx.shaderModel = !{!3}
!dx.resources = !{!4}
!dx.entryPoints = !{!11}
!0 = !{!"dxc(private) 1.9.0.5364 (update_containertest_headers, 3aaa95da5)"}
!1 = !{i32 1, i32 6}
!2 = !{i32 1, i32 10}
!3 = !{!"cs", i32 6, i32 6}
!4 = !{null, !5, null, null}
!5 = !{!6, !8, !9, !10}
!6 = !{i32 0, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!7 = !{i32 1, i32 4}
!8 = !{i32 1, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 1, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!9 = !{i32 2, %struct.RWByteAddressBuffer* undef, !"", i32 0, i32 2, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!10 = !{i32 3, %"class.RWStructuredBuffer<unsigned int>"* undef, !"", i32 0, i32 3, i32 1, i32 12, i1 false, i1 false, i1 false, !7}
!11 = !{void ()* @main, !"main", null, !4, !12}
!12 = !{i32 0, i64 16, i32 4, !13}
!13 = !{i32 256, i32 1, i32 1}
When executing a shader with WARP, with validation layer enabled (GBV), and compiling the shader with DXC, with the 6_6 target, there is a runtime hang.
This is the minimal offload test repro in HLSL:
When WARP is the target and validation layer is enabled, and when DXC is the compiler, targeting 6_6 and executing the above shader hangs indefinitely.
Targeting SM 6.5 does not produce a hang, but 6.6 does.
Below are the IRs for 6.5 and 6.6 respectively.
6.5:
6.6: