Skip to content

Commit 147ceb1

Browse files
Fix issue with raw default constructors in SPIRV emit (shader-slang#5556)
1 parent e58ba6b commit 147ceb1

4 files changed

+77
-0
lines changed

source/slang/slang-emit.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
#include "slang-ir-ssa.h"
9090
#include "slang-ir-string-hash.h"
9191
#include "slang-ir-strip-cached-dict.h"
92+
#include "slang-ir-strip-default-construct.h"
9293
#include "slang-ir-strip-witness-tables.h"
9394
#include "slang-ir-strip.h"
9495
#include "slang-ir-synthesize-active-mask.h"
@@ -1419,6 +1420,19 @@ Result linkAndOptimizeIR(
14191420
// we will need to disable this pass.
14201421
stripWitnessTables(irModule);
14211422

1423+
switch (target)
1424+
{
1425+
// On targets that don't support default initialization, remove 'raw' default construct
1426+
// insts because our code-gen will not have any way to emit them.
1427+
//
1428+
case CodeGenTarget::SPIRV:
1429+
if (targetProgram->shouldEmitSPIRVDirectly())
1430+
removeRawDefaultConstructors(irModule);
1431+
break;
1432+
default:
1433+
break;
1434+
}
1435+
14221436
#if 0
14231437
dumpIRIfEnabled(codeGenContext, irModule, "AFTER STRIP WITNESS TABLES");
14241438
#endif

source/slang/slang-ir-insts.h

+7
Original file line numberDiff line numberDiff line change
@@ -2894,6 +2894,13 @@ struct IRUndefined : IRInst
28942894
{
28952895
};
28962896

2897+
// Special inst for targets that support default initialization,
2898+
// like the braces '= {}' in C/HLSL
2899+
struct IRDefaultConstruct : IRInst
2900+
{
2901+
IR_LEAF_ISA(DefaultConstruct)
2902+
};
2903+
28972904
// A global-scope generic parameter (a type parameter, a
28982905
// constraint parameter, etc.)
28992906
struct IRGlobalGenericParam : IRInst
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// slang-ir-strip-default-construct.cpp
2+
#include "slang-ir-strip-default-construct.h"
3+
4+
#include "slang-ir-inst-pass-base.h"
5+
#include "slang-ir-insts.h"
6+
#include "slang-ir.h"
7+
8+
namespace Slang
9+
{
10+
11+
struct RemoveDefaultConstructInsts : InstPassBase
12+
{
13+
RemoveDefaultConstructInsts(IRModule* module)
14+
: InstPassBase(module)
15+
{
16+
}
17+
void processModule()
18+
{
19+
processInstsOfType<IRDefaultConstruct>(
20+
kIROp_DefaultConstruct,
21+
[&](IRDefaultConstruct* defaultConstruct)
22+
{
23+
List<IRInst*> instsToRemove;
24+
for (auto use = defaultConstruct->firstUse; use; use = use->nextUse)
25+
{
26+
if (as<IRStore>(use->getUser()))
27+
instsToRemove.add(use->getUser());
28+
else
29+
return; // Ignore this inst if there are non-store uses.
30+
}
31+
32+
for (auto inst : instsToRemove)
33+
inst->removeAndDeallocate();
34+
35+
defaultConstruct->removeAndDeallocate();
36+
});
37+
}
38+
};
39+
40+
void removeRawDefaultConstructors(IRModule* module)
41+
{
42+
RemoveDefaultConstructInsts(module).processModule();
43+
}
44+
45+
} // namespace Slang
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// slang-ir-strip-default-construct.h
2+
#pragma once
3+
4+
namespace Slang
5+
{
6+
struct IRModule;
7+
8+
/// Strip the contents of all witness table instructions from the given IR `module`
9+
void removeRawDefaultConstructors(IRModule* module);
10+
11+
} // namespace Slang

0 commit comments

Comments
 (0)