Skip to content

Commit bedcb92

Browse files
author
Tim Foley
authored
Fix handling of enum tags that aren't literals (shader-slang#926)
An `enum` case currently lowers to the IR as the value of its tag expression, so if we have: ```hlsl enum E { X = 99, } ``` then `X` will lower as IR for the expression `99` which is just a literal. If instead we have: ```hlsl enum E { X = 99u, } ``` then after type checking the expression is `int(99u)`, which will get emitted to the global (module) scope as a cast/conversion instruction, that then gets referenced at the use sites of `E.X`. The emit logic wasn't set up to handle the case of referencing something directly from the global scope, so this change makes it so that side-effect-free global instructions are treated just like literal constants. This simple handling is fine for now since it will only apply to `enum` tag values (true global constants declared with `static const` have different handling).
1 parent 3ae31a6 commit bedcb92

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

source/slang/emit.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,7 @@ struct EmitVisitor
23932393
case kIROp_GlobalConstant:
23942394
case kIROp_GlobalParam:
23952395
case kIROp_Param:
2396+
case kIROp_Func:
23962397
return false;
23972398

23982399
// Always fold these in, because they are trivial
@@ -2513,6 +2514,15 @@ struct EmitVisitor
25132514
}
25142515
}
25152516

2517+
// If the instruction is at global scope, then it might represent
2518+
// a constant (e.g., the value of an enum case).
2519+
//
2520+
if(as<IRModuleInst>(inst->getParent()))
2521+
{
2522+
if(!inst->mightHaveSideEffects())
2523+
return true;
2524+
}
2525+
25162526
// Having dealt with all of the cases where we *must* fold things
25172527
// above, we can now deal with the more general cases where we
25182528
// *should not* fold things.
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// enum-tag-conversion.slang
2+
3+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute
4+
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute
5+
6+
// Confirm that a value of `enum` type can have an initializer
7+
// that includes basic operations like type conversion.
8+
9+
enum RoseColors
10+
{
11+
Red = 16u,
12+
}
13+
14+
int test(int val)
15+
{
16+
return val + RoseColors.Red;
17+
}
18+
19+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out
20+
RWStructuredBuffer<int> outputBuffer;
21+
22+
[numthreads(4, 1, 1)]
23+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
24+
{
25+
uint tid = dispatchThreadID.x;
26+
27+
int val = int(tid);
28+
val = test(val);
29+
30+
outputBuffer[tid] = val;
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
10
2+
11
3+
12
4+
13

0 commit comments

Comments
 (0)