Skip to content

Commit 3a2969a

Browse files
authored
Lower CopyLogical before SPIRV control flow legalization. (#8883)
The bug is that the `lowerCopyLogical` pass must run before SPIRV control flow legalization, because it may generate new loops that needs to be legalized. Closes #8838.
1 parent dcb47b7 commit 3a2969a

2 files changed

Lines changed: 52 additions & 11 deletions

File tree

source/slang/slang-ir-spirv-legalize.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,19 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
22892289
t->replaceUsesWith(lowered);
22902290
}
22912291

2292+
// If older than spirv 1.4, we need more legalization steps due to lack of opcodes.
2293+
if (!m_sharedContext->isSpirv14OrLater())
2294+
{
2295+
// Legalize OpSelect returning non-vector-composites.
2296+
if (m_codeGenContext->getRequiredLoweringPassSet().nonVectorCompositeSelect)
2297+
legalizeNonVectorCompositeSelect(m_module);
2298+
2299+
// Lower OpCopyLogical to element-wise stores.
2300+
// Note that it is important to run this pass before processing functions, since we may
2301+
// introduce new loops that needs to be legalized.
2302+
lowerCopyLogical(m_module);
2303+
}
2304+
22922305
for (auto globalInst : m_module->getGlobalInsts())
22932306
{
22942307
if (auto func = as<IRFunc>(globalInst))
@@ -2333,17 +2346,6 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
23332346
// invalid SPIR-V.
23342347
bool skipFuncParamValidation = false;
23352348
validateAtomicOperations(skipFuncParamValidation, m_sink, m_module->getModuleInst());
2336-
2337-
// If older than spirv 1.4, we need more legalization steps due to lack of opcodes.
2338-
if (!m_sharedContext->isSpirv14OrLater())
2339-
{
2340-
// Legalize OpSelect returning non-vector-composites.
2341-
if (m_codeGenContext->getRequiredLoweringPassSet().nonVectorCompositeSelect)
2342-
legalizeNonVectorCompositeSelect(m_module);
2343-
2344-
// Lower OpCopyLogical to element-wise stores.
2345-
lowerCopyLogical(m_module);
2346-
}
23472349
}
23482350

23492351
void updateFunctionTypes()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//TEST:SIMPLE(filecheck=CHECK): -target spirv -profile spirv_1_3 -g1
2+
3+
// CHECK: OpEntryPoint
4+
5+
public struct PortalView
6+
{
7+
public float3 viewOrigin;
8+
}
9+
10+
public struct PortalViews
11+
{
12+
public PortalView views[64];
13+
public uint viewBits;
14+
public Optional<PortalView> PortalForStencil(uint stencil)
15+
{
16+
// -g1 causes `this` to be preloaded into a local variable for
17+
// debugging.
18+
// when emitting code for spirv_1_3 where there is no OpCopyLogical,
19+
// we have to generate a loop to copy the `views` array from the constant buffer
20+
// into the local variable for debugging.
21+
// The loop must be generated before control flow legalization for SPIRV
22+
// otherwise we will generate invalid SPIRV.
23+
if ((viewBits & stencil) == 0)
24+
return none;
25+
return views[firstbithigh(stencil)];
26+
}
27+
};
28+
29+
ConstantBuffer<PortalViews> CPortals;
30+
RWStructuredBuffer<float4> outputBuffer;
31+
32+
[numthreads(1,1,1)]
33+
void main()
34+
{
35+
if (let portal = CPortals.PortalForStencil(0xff))
36+
{
37+
outputBuffer[0] = portal.viewOrigin.x;
38+
}
39+
}

0 commit comments

Comments
 (0)