Skip to content

Commit 59495c1

Browse files
authored
[SPIR-V] Fix missing DerivativeGroup executionMode (#7981)
GroupNonUniformQuadSwap and QuadBroadcast operate on quad scope instances, hence we must emit the DerivativeGroup*KHR execution mode when those instructions are present. Fixes #7943
1 parent 8d87631 commit 59495c1

12 files changed

+80
-14
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10707,6 +10707,7 @@ SpirvEmitter::processWaveQuadWideShuffle(const CallExpr *callExpr,
1070710707
llvm_unreachable("case should not appear here");
1070810708
}
1070910709

10710+
addDerivativeGroupExecutionMode();
1071010711
return spvBuilder.createGroupNonUniformOp(
1071110712
opcode, retType, spv::Scope::Subgroup, {value, target}, srcLoc);
1071210713
}
@@ -10725,6 +10726,8 @@ SpirvInstruction *SpirvEmitter::processWaveQuadAnyAll(const CallExpr *callExpr,
1072510726
auto *predicate = doExpr(callExpr->getArg(0));
1072610727
const auto srcLoc = callExpr->getExprLoc();
1072710728

10729+
addDerivativeGroupExecutionMode();
10730+
1072810731
if (!featureManager.isExtensionEnabled(Extension::KHR_quad_control)) {
1072910732
// We can't use QuadAny/QuadAll, so implement them using QuadSwap. We
1073010733
// will read the value at each quad invocation, then combine them.

tools/clang/test/CodeGenSPIRV/sm6.quad-any-all.hlsl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.1 -fcgl %s -spirv | FileCheck %s --check-prefixes=CHECK,QUAD
2-
// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.1 -fspv-extension=SPV_KHR_16bit_storage -fcgl %s -spirv | FileCheck %s --check-prefixes=CHECK,NOQUAD
2+
// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.1 -fspv-extension=SPV_KHR_16bit_storage -fspv-extension=SPV_KHR_compute_shader_derivatives -fcgl %s -spirv | FileCheck %s --check-prefixes=CHECK,NOQUAD
33
// RUN: not %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.0 -fcgl %s -spirv 2>&1 | FileCheck %s --check-prefixes=ERROR
44

55
// CHECK: ; Version: 1.3
66

7-
// QUAD: OpCapability QuadControlKHR
7+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
8+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
9+
// QUAD-DAG: OpCapability QuadControlKHR
10+
811
// QUAD: OpExtension "SPV_KHR_quad_control"
912

13+
// CHECK: OpExecutionMode %main DerivativeGroupLinearKHR
14+
1015
RWStructuredBuffer<float3> values;
1116

1217
[numthreads(32, 1, 1)]
@@ -23,7 +28,7 @@ void main(uint3 id: SV_DispatchThreadID) {
2328
// NOQUAD-NEXT: [[inv2:%[0-9]+]] = OpGroupNonUniformQuadSwap %bool %uint_3 [[val1]] %uint_2
2429
// NOQUAD-NEXT: [[or2:%[0-9]+]] = OpLogicalOr %bool [[or1]] [[inv2]]
2530

26-
// ERROR: 27:24: error: Vulkan 1.1 is required for Wave Operation but not permitted to use
31+
// ERROR: 32:24: error: Vulkan 1.1 is required for Wave Operation but not permitted to use
2732
values[outIdx].x = QuadAny(outIdx % 4 == 0) ? 1.0 : 2.0;
2833

2934
// CHECK: [[val2:%[0-9]+]] = OpIEqual %bool {{%[0-9]+}}
@@ -36,6 +41,6 @@ void main(uint3 id: SV_DispatchThreadID) {
3641
// NOQUAD-NEXT: [[inv2:%[0-9]+]] = OpGroupNonUniformQuadSwap %bool %uint_3 [[val2]] %uint_2
3742
// NOQUAD-NEXT: [[or2:%[0-9]+]] = OpLogicalAnd %bool [[or1]] [[inv2]]
3843

39-
// ERROR: 40:24: error: Vulkan 1.1 is required for Wave Operation but not permitted to use
44+
// ERROR: 45:24: error: Vulkan 1.1 is required for Wave Operation but not permitted to use
4045
values[outIdx].y = QuadAll(outIdx % 2 == 0) ? 3.0 : 4.0;
4146
}

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-diagonal.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-diagonal.vulkan1.2.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-x.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-x.vulkan1.2.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-y.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-across-y.vulkan1.2.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {

tools/clang/test/CodeGenSPIRV/sm6.quad-read-lane-at.hlsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ struct S {
1010

1111
RWStructuredBuffer<S> values;
1212

13-
// CHECK: OpCapability GroupNonUniformQuad
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupLinearKHR
1417

1518
[numthreads(32, 1, 1)]
1619
void main(uint3 id: SV_DispatchThreadID) {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s
2+
3+
// CHECK: ; Version: 1.5
4+
5+
struct S {
6+
float4 val1;
7+
uint3 val2;
8+
int val3;
9+
};
10+
11+
RWStructuredBuffer<S> values;
12+
13+
// CHECK-DAG: OpCapability GroupNonUniformQuad
14+
// CHECK-DAG: OpCapability ComputeDerivativeGroupQuadsKHR
15+
// CHECK-DAG: OpCapability ComputeDerivativeGroupLinearKHR
16+
// CHECK-DAG: OpExecutionMode %main DerivativeGroupQuadsKHR
17+
18+
[numthreads(2, 2, 1)]
19+
void main(uint3 id: SV_DispatchThreadID) {
20+
uint x = id.x;
21+
22+
float4 val1 = values[x].val1;
23+
uint3 val2 = values[x].val2;
24+
int val3 = values[x].val3;
25+
26+
// CHECK: [[val1:%[0-9]+]] = OpLoad %v4float %val1
27+
// CHECK-NEXT: {{%[0-9]+}} = OpGroupNonUniformQuadBroadcast %v4float %uint_3 [[val1]] %uint_0
28+
values[x].val1 = QuadReadLaneAt(val1, 0);
29+
// CHECK: [[val2:%[0-9]+]] = OpLoad %v3uint %val2
30+
// CHECK-NEXT: {{%[0-9]+}} = OpGroupNonUniformQuadBroadcast %v3uint %uint_3 [[val2]] %uint_1
31+
values[x].val2 = QuadReadLaneAt(val2, 1);
32+
// CHECK: [[val3:%[0-9]+]] = OpLoad %int %val3
33+
// CHECK-NEXT: {{%[0-9]+}} = OpGroupNonUniformQuadBroadcast %int %uint_3 [[val3]] %uint_2
34+
values[x].val3 = QuadReadLaneAt(val3, 2);
35+
}

0 commit comments

Comments
 (0)