Skip to content

Commit 66e975a

Browse files
committed
Signal when SPIR-V legalization needs targeted cleanup
1 parent 54afd2c commit 66e975a

12 files changed

+68
-47
lines changed

external/SPIRV-Tools

Submodule SPIRV-Tools updated 117 files

tools/clang/lib/Frontend/Rewrite/RewriteObjC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ namespace {
483483
result = Context->getObjCIdType();
484484
FunctionProtoType::ExtProtoInfo fpi;
485485
fpi.Variadic = variadic;
486-
return Context->getFunctionType(result, args, fpi);
486+
return Context->getFunctionType(result, args, fpi, {});
487487
}
488488

489489
// Helper function: create a CStyleCastExpr with trivial type source info.

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci)
593593
constEvaluator(astContext, spvBuilder), entryFunction(nullptr),
594594
curFunction(nullptr), curThis(nullptr), seenPushConstantAt(),
595595
isSpecConstantMode(false), needsLegalization(false),
596+
needsLegalizationLoopUnroll(false),
597+
needsLegalizationSsaRewrite(false),
596598
beforeHlslLegalization(false), mainSourceFile(nullptr) {
597599

598600
// Get ShaderModel from command line hlsl profile option.
@@ -954,6 +956,9 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) {
954956
declIdMapper.requiresFlatteningCompositeResources() ||
955957
!dsetbindingsToCombineImageSampler.empty() ||
956958
spirvOptions.signaturePacking;
959+
needsLegalizationSsaRewrite =
960+
needsLegalizationSsaRewrite ||
961+
!dsetbindingsToCombineImageSampler.empty();
957962

958963
// Run legalization passes
959964
if (spirvOptions.codeGenHighLevel) {
@@ -5823,8 +5828,11 @@ SpirvInstruction *SpirvEmitter::createImageSample(
58235828
SpirvInstruction *minLod, SpirvInstruction *residencyCodeId,
58245829
SourceLocation loc, SourceRange range) {
58255830

5826-
if (varOffset)
5831+
if (varOffset) {
58275832
needsLegalization = true;
5833+
needsLegalizationLoopUnroll = true;
5834+
needsLegalizationSsaRewrite = true;
5835+
}
58285836

58295837
// SampleDref* instructions in SPIR-V always return a scalar.
58305838
// They also have the correct type in HLSL.
@@ -8045,7 +8053,7 @@ SpirvInstruction *SpirvEmitter::createVectorSplat(const Expr *scalarExpr,
80458053
// Should find a more meaningful one.
80468054
if (auto *constVal = dyn_cast<SpirvConstant>(scalarVal)) {
80478055
llvm::SmallVector<SpirvConstant *, 4> elements(size_t(size), constVal);
8048-
const bool isSpecConst = constVal->getopcode() == spv::Op::OpSpecConstant;
8056+
const bool isSpecConst = constVal->isSpecConstant();
80498057
auto *value =
80508058
spvBuilder.getConstantComposite(vecType, elements, isSpecConst);
80518059
if (!value)
@@ -16665,7 +16673,15 @@ bool SpirvEmitter::spirvToolsLegalize(std::vector<uint32_t> *mod,
1666516673
optimizer.RegisterPass(
1666616674
spvtools::CreateInterfaceVariableScalarReplacementPass());
1666716675
}
16668-
optimizer.RegisterLegalizationPasses(spirvOptions.preserveInterface);
16676+
auto legalizationSsaRewriteMode = spvtools::SSARewriteMode::None;
16677+
if (needsLegalizationLoopUnroll) {
16678+
legalizationSsaRewriteMode = spvtools::SSARewriteMode::All;
16679+
} else if (needsLegalizationSsaRewrite) {
16680+
legalizationSsaRewriteMode = spvtools::SSARewriteMode::OpaqueOnly;
16681+
}
16682+
optimizer.RegisterLegalizationPasses(
16683+
spirvOptions.preserveInterface, needsLegalizationLoopUnroll,
16684+
legalizationSsaRewriteMode);
1666916685
// Add flattening of resources if needed.
1667016686
if (spirvOptions.flattenResourceArrays) {
1667116687
optimizer.RegisterPass(

tools/clang/lib/SPIRV/SpirvEmitter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,8 @@ class SpirvEmitter : public ASTConsumer {
15781578
///
15791579
/// Note: legalization specific code
15801580
bool needsLegalization;
1581+
bool needsLegalizationLoopUnroll;
1582+
bool needsLegalizationSsaRewrite;
15811583

15821584
/// Whether the translated SPIR-V binary passes --before-hlsl-legalization
15831585
/// option to spirv-val because of illegal function parameter scope.

tools/clang/test/CodeGenSPIRV/cast.flat-conversion.matrix.hlsl

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,18 @@ RWStructuredBuffer<T> t_output;
1616
// COL: OpMemberDecorate %S 0 RowMajor
1717
// ROW: OpMemberDecorate %S 0 ColMajor
1818

19-
// The DXIL generated for the two cases seem to produce the same results,
20-
// and this matches that behaviour.
21-
// CHECK: [[array_const:%[0-9]+]] = OpConstantComposite %_arr_float_uint_6 %float_0 %float_1 %float_2 %float_3 %float_4 %float_5
22-
// CHECK: [[t:%[0-9]+]] = OpConstantComposite %T [[array_const]]
23-
2419
// The DXIL that is generates different order for the values depending on
2520
// whether the matrix is column or row major. However, for SPIR-V, the value
2621
// stored in both cases is the same because the decoration, which is checked
2722
// above, is what determines the layout in memory for the value.
2823

29-
// CHECK: [[row0:%[0-9]+]] = OpConstantComposite %v3float %float_0 %float_1 %float_2
30-
// CHECK: [[row1:%[0-9]+]] = OpConstantComposite %v3float %float_3 %float_4 %float_5
31-
// CHECK: [[mat:%[0-9]+]] = OpConstantComposite %mat2v3float %33 %34
32-
// CHECK: [[s:%[0-9]+]] = OpConstantComposite %S %35
24+
// CHECK: [[mat:%[0-9]+]] = OpLoad %mat2v3float
25+
// CHECK: [[e00:%[0-9]+]] = OpCompositeExtract %float [[mat]] 0 0
26+
// CHECK: [[e01:%[0-9]+]] = OpCompositeExtract %float [[mat]] 0 1
27+
// CHECK: [[e02:%[0-9]+]] = OpCompositeExtract %float [[mat]] 0 2
28+
// CHECK: [[e10:%[0-9]+]] = OpCompositeExtract %float [[mat]] 1 0
29+
// CHECK: [[e11:%[0-9]+]] = OpCompositeExtract %float [[mat]] 1 1
30+
// CHECK: [[e12:%[0-9]+]] = OpCompositeExtract %float [[mat]] 1 2
3331

3432
void main() {
3533
S s;
@@ -40,13 +38,16 @@ void main() {
4038
s.a[i][j] = i*3+j;
4139
}
4240
}
43-
// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_T %t_output %int_0 %uint_0
44-
// CHECK: OpStore [[ac]] [[t]]
41+
// CHECK: [[tptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_T %t_output %int_0 %uint_0
42+
// CHECK: [[tarr:%[0-9]+]] = OpCompositeConstruct %_arr_float_uint_6 [[e00]] [[e01]] [[e02]] [[e10]] [[e11]] [[e12]]
43+
// CHECK: [[tval:%[0-9]+]] = OpCompositeConstruct %T [[tarr]]
44+
// CHECK: OpStore [[tptr]] [[tval]]
4545
T t = (T)(s);
4646
t_output[0] = t;
4747

48-
// CHECK: [[ac:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %s_output %int_0 %uint_0
49-
// CHECK: OpStore [[ac]] [[s]]
48+
// CHECK: [[sptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %s_output %int_0 %uint_0
49+
// CHECK: [[sval:%[0-9]+]] = OpCompositeConstruct %S [[mat]]
50+
// CHECK: OpStore [[sptr]] [[sval]]
5051
s = (S)t;
5152
s_output[0] = s;
5253
}

tools/clang/test/CodeGenSPIRV/legal-examples/15-loop-var-unroll-ok.hlsl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
// RUN: %dxc -T cs_6_0 -E main -O3 -Vd %s -spirv | FileCheck %s
22

3-
// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %gSBuffer2
4-
// CHECK-NEXT: [[val:%[0-9]+]] = OpLoad %S [[ptr]]
5-
// CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %gRWSBuffer
6-
// CHECK-NEXT: OpStore [[ptr]] [[val]]
7-
8-
// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %gSBuffer2
9-
// CHECK-NEXT: [[val:%[0-9]+]] = OpLoad %S [[ptr]]
10-
// CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %gRWSBuffer
11-
// CHECK-NEXT: OpStore [[ptr]] [[val]]
3+
// CHECK: OpLoopMerge {{%[0-9]+}} {{%[0-9]+}} Unroll
4+
// CHECK: [[which:%[0-9]+]] = OpSelect %_ptr_Uniform_type_StructuredBuffer_S {{%[0-9]+}} %gSBuffer1 %gSBuffer2
5+
// CHECK: [[idx:%[0-9]+]] = OpBitcast %uint {{%[0-9]+}}
6+
// CHECK: [[src:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S [[which]] %int_0 [[idx]]
7+
// CHECK: [[val:%[0-9]+]] = OpLoad %S [[src]]
8+
// CHECK: [[dst:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %gRWSBuffer %int_0 [[idx]]
9+
// CHECK: OpStore [[dst]] [[val]]
1210

1311
struct S {
1412
float4 f;

tools/clang/test/CodeGenSPIRV/max_id.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// CHECK-30: fatal error: failed to optimize SPIR-V: ID overflow. Try running compact-ids.
99

1010
// With a larger limit, the test case can compile successfully.
11-
// CHECK-400: Bound: 204
11+
// CHECK-400: Bound:
1212

1313

1414
RWStructuredBuffer<int> data;
@@ -20,4 +20,4 @@ void main(uint3 id : SV_DispatchThreadID)
2020
for( int i = 0; i < 64; i++ ) {
2121
data[i] = i;
2222
}
23-
}
23+
}

tools/clang/test/CodeGenSPIRV/type.rwstructured-buffer.array.counter.indirect.hlsl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ void func(RWStructuredBuffer<uint> local) {
2020

2121
float4 main(PSInput input) : SV_TARGET
2222
{
23-
// CHECK: [[ac2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %counter_var_g_rwbuffer {{%[0-9]+}} %uint_0
23+
// CHECK: [[counter_struct:%[0-9]+]] = OpAccessChain %_ptr_Uniform_type_ACSBuffer_counter %counter_var_g_rwbuffer {{%[0-9]+}}
24+
// CHECK: [[ac2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int [[counter_struct]] %uint_0
2425
// CHECK: OpAtomicIAdd %int [[ac2]] %uint_1 %uint_0 %int_1
2526
func(g_rwbuffer[input.idx]);
2627

27-
// CHECK: [[ac2_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint %g_rwbuffer {{%[0-9]+}} %int_0 %uint_0
28+
// CHECK: [[rwbuffer_struct:%[0-9]+]] = OpAccessChain %_ptr_Uniform_type_RWStructuredBuffer_uint %g_rwbuffer {{%[0-9]+}}
29+
// CHECK: [[ac2_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[rwbuffer_struct]] %int_0 %uint_0
2830
// CHECK: OpLoad %uint [[ac2_0]]
2931
return g_rwbuffer[input.idx][0];
3032
}

tools/clang/test/CodeGenSPIRV/type.rwstructured-buffer.array.counter.indirect2.hlsl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ float4 main(PSInput input) : SV_TARGET
1818
{
1919
RWStructuredBuffer<uint> l_rwbuffer[5] = g_rwbuffer;
2020

21-
// CHECK: [[ac2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int %counter_var_g_rwbuffer %int_0 %uint_0
21+
// CHECK: [[counter_struct:%[0-9]+]] = OpAccessChain %_ptr_Uniform_type_ACSBuffer_counter %counter_var_g_rwbuffer %int_0
22+
// CHECK: [[ac2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_int [[counter_struct]] %uint_0
2223
// CHECK: OpAtomicIAdd %int [[ac2]] %uint_1 %uint_0 %int_1
2324
l_rwbuffer[0].IncrementCounter();
2425

25-
// CHECK: [[ac2_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint %g_rwbuffer {{%[0-9]+}} %int_0 %uint_0
26+
// CHECK: [[rwbuffer_struct:%[0-9]+]] = OpAccessChain %_ptr_Uniform_type_RWStructuredBuffer_uint %g_rwbuffer {{%[0-9]+}}
27+
// CHECK: [[ac2_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[rwbuffer_struct]] %int_0 %uint_0
2628
// CHECK: OpLoad %uint [[ac2_0]]
2729
return l_rwbuffer[input.idx][0];
2830
}

0 commit comments

Comments
 (0)