Skip to content

Commit adf758c

Browse files
authored
Fix the issue of name mangling (shader-slang#4691)
* Fix the issue of name mangle During our name mangling, we should add the direction of the parameter in the name, otherwise it could have the name collision which will result in invalid code generation: e.g. // in slang-module.slang export func(float a) { ...} // in test.slang extern func(inout float a); when we compile test.slang, slang will pass a pointer type to the 'func', however, in the slang-module.slang, `func` expects a value instead of pointer. This will lead the wrong spirv code. So we should add the parameter direction into the mangle name such that above two symbols will have the different mangled names, and we will catch this during IR-link stage. * Change to use to get param direction * Address few comments
1 parent 7488b15 commit adf758c

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

source/slang/slang-mangle.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,33 @@ namespace Slang
547547

548548
for(auto paramDeclRef : parameters)
549549
{
550+
// parameter modifier makes big difference in the spirv code generation, for example
551+
// "out"/"inout" parameter will be passed by pointer. Therefore, we need to
552+
// distinguish them in the mangled name to avoid name collision.
553+
ParameterDirection paramDirection = getParameterDirection(paramDeclRef.getDecl());
554+
switch (paramDirection)
555+
{
556+
case kParameterDirection_Ref:
557+
emitRaw(context, "r_");
558+
break;
559+
case kParameterDirection_ConstRef:
560+
emitRaw(context, "c_");
561+
break;
562+
case kParameterDirection_Out:
563+
emitRaw(context, "o_");
564+
break;
565+
case kParameterDirection_InOut:
566+
emitRaw(context, "io_");
567+
break;
568+
case kParameterDirection_In:
569+
emitRaw(context, "i_");
570+
break;
571+
default:
572+
StringBuilder errMsg;
573+
errMsg << "Unknown parameter direction: " << paramDirection;
574+
SLANG_ABORT_COMPILATION(errMsg.toString().begin());
575+
break;
576+
}
550577
emitType(context, getType(context->astBuilder, paramDeclRef));
551578
}
552579

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//TEST_IGNORE_FILE:
2+
3+
export float libraryFunction(float a)
4+
{
5+
a = a + a;
6+
return a;
7+
}
8+
9+
export float libraryFunction1(inout float a)
10+
{
11+
a = a * a;
12+
return a;
13+
}
14+
15+
export float libraryFunction2(inout float a, in float b, out float c)
16+
{
17+
a = a * a;
18+
a = a + b;
19+
return a;
20+
}
21+
22+
export float libraryFunction3(in float a)
23+
{
24+
a = a + a;
25+
return a;
26+
}
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// illegal-func-decl.slang
2+
3+
// This test checks that the in/out/inout modifiers in function declarations must
4+
// be consistent with the function's definition, and slang can diagnose the inconsistency.
5+
6+
//TEST:COMPILE: tests/diagnostics/illegal-func-decl-module.slang -o tests/diagnostics/illegal-func-decl-module.slang-module
7+
8+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK1): -r tests/diagnostics/illegal-func-decl-module.slang-module -DTEST1 -target spirv -o illegal-func-decl.spv
9+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK2): -r tests/diagnostics/illegal-func-decl-module.slang-module -DTEST2 -target spirv -o illegal-func-decl.spv
10+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK3): -r tests/diagnostics/illegal-func-decl-module.slang-module -DTEST3 -target spirv -o illegal-func-decl.spv
11+
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK4): -r tests/diagnostics/illegal-func-decl-module.slang-module -DTEST4 -target spirv -o illegal-func-decl.spv
12+
13+
#ifdef TEST1
14+
// CHECK1: ([[# @LINE+1]]): error 45001: unresolved external symbol 'libraryFunction'.
15+
extern float libraryFunction(inout float a); // invalid: 'a' is 'in'
16+
#endif
17+
18+
#ifdef TEST2
19+
// CHECK2-NOT: ([[# @LINE+1]]): error 45001: unresolved external symbol 'libraryFunction1'.
20+
extern float libraryFunction1(inout float b); // valid
21+
#endif
22+
23+
#ifdef TEST3
24+
// CHECK3: ([[# @LINE+1]]): error 45001: unresolved external symbol 'libraryFunction2'.
25+
extern float libraryFunction2(inout float a, in float b, float c); // valid: 'c' is 'inout'
26+
#endif
27+
28+
#ifdef TEST4
29+
// CHECK4-NOT: ([[# @LINE+1]]): error 45001: unresolved external symbol 'libraryFunction3'.
30+
export float libraryFunction3(float a); // valid: 'in' is the default is not specified
31+
#endif
32+
33+
[shader("compute")]
34+
[numthreads(1, 1, 1)]
35+
void main(out float4 col : SV_Target0, bool isFrontHit)
36+
{
37+
float a = 5;
38+
float b = 7;
39+
float c = 7;
40+
41+
#ifdef TEST1
42+
col.x = libraryFunction(a);
43+
#endif
44+
45+
#ifdef TEST2
46+
col.y = libraryFunction1(b);
47+
#endif
48+
49+
#ifdef TEST3
50+
col.z = libraryFunction2(a, b, c);
51+
#endif
52+
53+
#ifdef TEST4
54+
col.w = libraryFunction3(a);
55+
#endif
56+
}
57+
58+

0 commit comments

Comments
 (0)