Skip to content

Commit 13609db

Browse files
authored
[SM68] Add test for node objects as function parameter. (microsoft#6231)
More testing of node shader objects passed as arguments. noinline and export still not work, added as XFail. For microsoft#6124
1 parent 661d444 commit 13609db

File tree

7 files changed

+980
-0
lines changed

7 files changed

+980
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// RUN: %dxc -T lib_6_x -fcgl %s | FileCheck %s --check-prefixes=FCGL,CHECK
2+
// RUN: %dxc -T lib_6_x -Zi %s | FileCheck %s --check-prefix=DBG
3+
// RUN: %dxc -T lib_6_x %s | FileCheck %s --check-prefixes=CHECK,DXIL
4+
// RUN: %dxc -T lib_6_x -Od %s | FileCheck %s --check-prefixes=CHECK,DXIL
5+
6+
// Confirm that linking a shader calling external functions that take node objects as parameters
7+
// correctly includes the external and internal functions
8+
9+
struct RECORD {
10+
int X;
11+
};
12+
13+
// CHECK: define void @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* noalias {{(nocapture )?}}sret %agg.result, %"struct.DispatchNodeInputRecord<RECORD>"* {{(nocapture readonly )?}}%input)
14+
[noinline]
15+
DispatchNodeInputRecord<RECORD> foo(DispatchNodeInputRecord<RECORD> input) {
16+
// CHECK: %[[FooLd:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %input
17+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[FooLd]], %"struct.DispatchNodeInputRecord<RECORD>"* %agg.result
18+
19+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %input, metadata ![[FOOINPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"input" !DIExpression() func:"foo"
20+
return input;
21+
}
22+
23+
// CHECK: define void @"\01?bar@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* {{(nocapture readonly )?}}%input, %"struct.DispatchNodeInputRecord<RECORD>"* noalias {{(nocapture )?}}%output)
24+
export
25+
void bar(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output) {
26+
27+
// CHECK: %[[TMP:.+]] = alloca %"struct.DispatchNodeInputRecord<RECORD>"{{(, align 8)?}}
28+
// CHECK: call void @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* {{(nonnull |noalias )?}}sret %[[TMP]], %"struct.DispatchNodeInputRecord<RECORD>"* %input)
29+
// CHECK: %[[BarLd:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %[[TMP]]{{(, align 8)?}}
30+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[BarLd]], %"struct.DispatchNodeInputRecord<RECORD>"* %output{{(, align 4)?}}
31+
32+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %output, metadata ![[BAROUTPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"output" !DIExpression() func:"bar"
33+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %input, metadata ![[BARINPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"input" !DIExpression() func:"bar"
34+
35+
output = foo(input);
36+
}
37+
38+
// CHECK: define void @"\01?foo2@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* noalias {{(nocapture )?}}sret %agg.result, %"struct.DispatchNodeInputRecord<RECORD>"* {{(nocapture readonly )?}}%input)
39+
DispatchNodeInputRecord<RECORD> foo2(DispatchNodeInputRecord<RECORD> input) {
40+
// CHECK: %[[Foo2Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %input{{(, align 4)?}}
41+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Foo2Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %agg.result{{(, align 4)?}}
42+
43+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %input, metadata ![[FOO2INPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"input" !DIExpression() func:"foo2"
44+
45+
return input;
46+
}
47+
48+
// CHECK: define void @"\01?bar2@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* {{(nocapture readonly )?}}%input, %"struct.DispatchNodeInputRecord<RECORD>"* noalias {{(nocapture )?}}%output)
49+
[noinline]
50+
export
51+
void bar2(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output) {
52+
// FCGL: %[[TMP:.+]] = alloca %"struct.DispatchNodeInputRecord<RECORD>", align 4
53+
// FCGL: call void @"\01?foo2@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* sret %[[TMP]], %"struct.DispatchNodeInputRecord<RECORD>"* %input)
54+
// FCGL: %[[Bar2Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %[[TMP]]
55+
// FCGL: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Bar2Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %output
56+
57+
// DXIL: %[[Bar2Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %input, {{(align 4, )?}}!noalias
58+
// DXIL: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Bar2Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %output{{(, align 4, )?}}
59+
60+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %output, metadata ![[BAR2OUTPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"output" !DIExpression() func:"bar2"
61+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %input, metadata ![[BAR2INPUT:[0-9]+]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"input" !DIExpression() func:"bar2"
62+
// DBG: call void @llvm.dbg.declare(metadata %"struct.DispatchNodeInputRecord<RECORD>"* %input, metadata ![[FOO2INPUT]], metadata !{{[0-9]+}}), !dbg !{{[0-9]+}} ; var:"input" !DIExpression() func:"foo2"
63+
64+
output = foo2(input);
65+
}
66+
67+
68+
// DBG checks debug info to make sure node object types are correctly saved for function parameters and local variable.
69+
// DBG: ![[Foo:[0-9]+]] = !DISubprogram(name: "foo", linkageName: "\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z", scope: !1, file: !1, line: {{[0-9]+}}, type: ![[FooTy:[0-9]+]], isLocal: false, isDefinition: true, scopeLine: {{[0-9]+}}, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"*)* @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z")
70+
// DBG: ![[FooTy]] = !DISubroutineType(types: ![[FooTys:[0-9]+]])
71+
// DBG: ![[FooTys]] = !{![[ObjTy:[0-9]+]], ![[ObjTy]]}
72+
// DBG: ![[ObjTy]] = !DICompositeType(tag: DW_TAG_structure_type, name: "DispatchNodeInputRecord<RECORD>", file: !1, size: 32, align: 32, elements: !2, templateParams: ![[TemplateParams:[0-9]+]])
73+
// DBG: ![[TemplateParams]] = !{![[TemplateParam:[0-9]+]]}
74+
// DBG: ![[TemplateParam]] = !DITemplateTypeParameter(name: "recordtype", type: ![[RECORD:[0-9]+]])
75+
// DBG: ![[RECORD]] = !DICompositeType(tag: DW_TAG_structure_type, name: "RECORD", file: !1, line: {{[0-9]+}}, size: 32, align: 32, elements: ![[RecordElts:[0-9]+]])
76+
// DBG: ![[RecordElts]] = !{![[RecordElt:[0-9]+]]}
77+
// DBG: ![[RecordElt]] = !DIDerivedType(tag: DW_TAG_member, name: "X", scope: ![[RECORD]], file: !1, line: {{[0-9]+}}, baseType: ![[INT:[0-9]+]], size: 32, align: 32)
78+
// DBG: ![[INT]] = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
79+
// DBG: ![[Bar:[0-9]+]] = !DISubprogram(name: "bar", linkageName: "\01?bar@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z", scope: !1, file: !1, line: {{[0-9]+}}, type: ![[BarTy:[0-9]+]], isLocal: false, isDefinition: true, scopeLine: {{[0-9]+}}, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"*)* @"\01?bar@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z")
80+
// DBG: ![[BarTy]] = !DISubroutineType(types: ![[BarTys:[0-9]+]])
81+
// DBG: ![[BarTys]] = !{null, ![[ObjTy]], ![[OutObjTy:[0-9]+]]}
82+
// DBG: ![[OutObjTy]] = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: ![[ObjTy]])
83+
// DBG: ![[Foo2:[0-9]+]] = !DISubprogram(name: "foo2", linkageName: "\01?foo2@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z", scope: !1, file: !1, line: {{[0-9]+}}, type: ![[FooTy]], isLocal: false, isDefinition: true, scopeLine: {{[0-9]+}}, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"*)* @"\01?foo2@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z")
84+
// DBG: ![[Bar2:[0-9]+]] = !DISubprogram(name: "bar2", linkageName: "\01?bar2@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z", scope: !1, file: !1, line: {{[0-9]+}}, type: ![[BarTy]], isLocal: false, isDefinition: true, scopeLine: {{[0-9]+}}, flags: DIFlagPrototyped, isOptimized: false, function: void (%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"*)* @"\01?bar2@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z")
85+
// DBG: ![[FOOINPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "input", arg: 1, scope: ![[Foo]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
86+
// DBG: ![[BAROUTPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "output", arg: 2, scope: ![[Bar]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
87+
// DBG: ![[BARINPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "input", arg: 1, scope: ![[Bar]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
88+
// DBG: ![[FOO2INPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "input", arg: 1, scope: ![[Foo2]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
89+
// DBG: ![[BAR2OUTPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "output", arg: 2, scope: ![[Bar2]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
90+
// DBG: ![[BAR2INPUT]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "input", arg: 1, scope: ![[Bar2]], file: !1, line: {{[0-9]+}}, type: ![[ObjTy]])
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %dxc -T lib_6_x %s | FileCheck %s
2+
3+
// Not supported yet.
4+
// https://github.com/microsoft/DirectXShaderCompiler/issues/6258
5+
// XFAIL: *
6+
7+
struct RECORD
8+
{
9+
half h;
10+
};
11+
12+
13+
DispatchNodeInputRecord<RECORD> wrapper(DispatchNodeInputRecord<RECORD> t);
14+
15+
16+
RWBuffer<uint> buf0;
17+
18+
19+
[Shader("node")]
20+
[NumThreads(1024,1,1)]
21+
[NodeDispatchGrid(64,1,1)]
22+
[NodeLaunch("broadcasting")]
23+
void node_DispatchNodeInputRecord(DispatchNodeInputRecord<RECORD> input)
24+
{
25+
buf0[0] = wrapper(input).Get().h;
26+
}
27+
28+
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// RUN: %dxc -T lib_6_x %S/node-object-export-1.hlsl -Fo %t.1
2+
// RUN: %dxc -T lib_6_x %s -Fo %t.2
3+
// RUN: %dxc -T lib_6_x -link "%t.1;%t.2" | FileCheck %s
4+
5+
// Confirm that linking a shader calling external functions that take node objects as parameters
6+
// correctly includes the external and internal functions
7+
8+
// Confirm that external function "foo2" is correctly included here even though it is called only by external functions
9+
// CHECK: define void @"\01?foo2@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* noalias nocapture sret, %"struct.DispatchNodeInputRecord<RECORD>"* nocapture readonly) #0 {
10+
// CHECK: %[[Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
11+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
12+
13+
// Confirm that external function "bar" is correctly included here since it is called by bar3
14+
// CHECK: define void @"\01?bar@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* nocapture readonly, %"struct.DispatchNodeInputRecord<RECORD>"* noalias nocapture) #0 {
15+
// CHECK: %[[Alloca:.+]] = alloca %"struct.DispatchNodeInputRecord<RECORD>", align 8
16+
// CHECK: call void @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* nonnull sret %[[Alloca]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}})
17+
// CHECK: %[[Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %[[Alloca]], align 8
18+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
19+
20+
// Confirm that external function "bar2" is correctly included here since it is called by bar4
21+
// CHECK: define void @"\01?bar2@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* nocapture readonly, %"struct.DispatchNodeInputRecord<RECORD>"* noalias nocapture) #1 {
22+
// CHECK: %[[Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
23+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
24+
25+
// Confirm that internal function "bar3" is correctly included here and calls external function "foo"
26+
// CHECK: define void @"\01?bar3@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"* noalias) #0 {
27+
// CHECK: %[[Alloca:.+]] = alloca %"struct.DispatchNodeInputRecord<RECORD>", align 8
28+
// CHECK: call void @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* nonnull sret %[[Alloca]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}) #2
29+
// CHECK: %[[Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %[[Alloca]], align 8
30+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
31+
32+
// Confirm that internal function "bar4" is correctly included here and calls outside function "bar2"
33+
// CHECK: define void @"\01?bar4@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"*, %"struct.DispatchNodeInputRecord<RECORD>"* noalias) #0 {
34+
// CHECK: call void @"\01?bar2@@YAXU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, %"struct.DispatchNodeInputRecord<RECORD>"* %1) #2
35+
36+
// Confirm that external function "foo" is correctly included here even though it is called only by external functions
37+
// CHECK: define void @"\01?foo@@YA?AU?$DispatchNodeInputRecord@URECORD@@@@U1@@Z"(%"struct.DispatchNodeInputRecord<RECORD>"* noalias nocapture sret, %"struct.DispatchNodeInputRecord<RECORD>"* nocapture readonly) #1 {
38+
// CHECK: %[[Ld:.+]] = load %"struct.DispatchNodeInputRecord<RECORD>", %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
39+
// CHECK: store %"struct.DispatchNodeInputRecord<RECORD>" %[[Ld]], %"struct.DispatchNodeInputRecord<RECORD>"* %{{.+}}, align 4
40+
41+
42+
struct RECORD {
43+
int X;
44+
};
45+
46+
47+
void bar(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output);
48+
49+
[noinline]
50+
void bar2(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output);
51+
52+
export
53+
void bar3(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output) {
54+
bar(input, output);
55+
}
56+
57+
export
58+
void bar4(DispatchNodeInputRecord<RECORD> input, out DispatchNodeInputRecord<RECORD> output) {
59+
bar2(input, output);
60+
}
61+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %dxc -T lib_6_8 %s | FileCheck %s
2+
3+
// Not supported yet.
4+
// https://github.com/microsoft/DirectXShaderCompiler/issues/6258
5+
// XFAIL: *
6+
7+
[noinline]
8+
void loadStressEmptyRecWorker(
9+
EmptyNodeOutput outputNode)
10+
{
11+
outputNode.GroupIncrementOutputCount(1);
12+
}
13+
14+
[Shader("node")]
15+
[NodeDispatchGrid(1, 1, 1)]
16+
[NumThreads(1, 1, 1)]
17+
void node_EmptyNodeOutput(
18+
[MaxOutputRecords(1)] EmptyNodeOutput loadStressChild
19+
)
20+
{
21+
loadStressEmptyRecWorker(wrapper(loadStressChild));
22+
}

0 commit comments

Comments
 (0)