Skip to content

Commit 3fca36e

Browse files
committed
tests: run both with and without --spirt.
1 parent 8535bb3 commit 3fca36e

File tree

76 files changed

+516
-253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+516
-253
lines changed

crates/rustc_codegen_spirv/src/linker/test.rs

Lines changed: 134 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{link, LinkResult, Options};
1+
use super::{link, LinkResult};
22
use pipe::pipe;
33
use rspirv::dr::{Loader, Module};
44
use rustc_errors::registry::Registry;
@@ -53,7 +53,55 @@ fn load(bytes: &[u8]) -> Module {
5353
loader.module()
5454
}
5555

56-
fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
56+
struct TestLinkOutputs {
57+
// Old output, equivalent to not passing `--spirt` in codegen args.
58+
without_spirt: Module,
59+
60+
// New output, equivalent to passing `--spirt` in codegen args.
61+
with_spirt: Module,
62+
}
63+
64+
// FIXME(eddyb) shouldn't this be named just `link`? (`assemble_spirv` is separate)
65+
fn assemble_and_link(binaries: &[&[u8]]) -> Result<TestLinkOutputs, PrettyString> {
66+
let link_with_spirt = |spirt: bool| {
67+
link_with_linker_opts(
68+
binaries,
69+
&crate::linker::Options {
70+
compact_ids: true,
71+
dce: true,
72+
keep_link_exports: true,
73+
spirt,
74+
..Default::default()
75+
},
76+
)
77+
};
78+
match [link_with_spirt(false), link_with_spirt(true)] {
79+
[Ok(without_spirt), Ok(with_spirt)] => Ok(TestLinkOutputs {
80+
without_spirt,
81+
with_spirt,
82+
}),
83+
84+
[Err(without_spirt), Err(with_spirt)] if without_spirt == with_spirt => Err(without_spirt),
85+
86+
// Different error, or only one side errored.
87+
[without_spirt, with_spirt] => {
88+
let pretty = |result: Result<Module, _>| {
89+
result.map(|m| {
90+
use rspirv::binary::Disassemble;
91+
PrettyString(m.disassemble())
92+
})
93+
};
94+
// HACK(eddyb) using `assert_eq!` to dump the different `Result`s.
95+
assert_eq!(pretty(without_spirt), pretty(with_spirt));
96+
unreachable!();
97+
}
98+
}
99+
}
100+
101+
fn link_with_linker_opts(
102+
binaries: &[&[u8]],
103+
opts: &crate::linker::Options,
104+
) -> Result<Module, PrettyString> {
57105
let modules = binaries.iter().cloned().map(load).collect::<Vec<_>>();
58106

59107
// FIXME(eddyb) this seems ridiculous, we should be able to write to
@@ -118,16 +166,7 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
118166
)
119167
};
120168

121-
let res = link(
122-
&sess,
123-
modules,
124-
&Options {
125-
compact_ids: true,
126-
dce: true,
127-
keep_link_exports: true,
128-
..Default::default()
129-
},
130-
);
169+
let res = link(&sess, modules, opts);
131170
assert_eq!(sess.has_errors(), res.as_ref().err().copied());
132171
res.map(|res| match res {
133172
LinkResult::SingleModule(m) => *m,
@@ -141,14 +180,33 @@ fn assemble_and_link(binaries: &[&[u8]]) -> Result<Module, PrettyString> {
141180
}
142181

143182
#[track_caller]
144-
fn without_header_eq(mut result: Module, expected: &str) {
145-
use rspirv::binary::Disassemble;
146-
//use rspirv::binary::Assemble;
147-
148-
// validate(&result.assemble());
149-
150-
result.header = None;
151-
let result = result.disassemble();
183+
fn without_header_eq(outputs: TestLinkOutputs, expected: &str) {
184+
let result = {
185+
let disasm = |mut result: Module| {
186+
use rspirv::binary::Disassemble;
187+
//use rspirv::binary::Assemble;
188+
189+
// validate(&result.assemble());
190+
191+
result.header = None;
192+
result.disassemble()
193+
};
194+
let [without_spirt, with_spirt] =
195+
[disasm(outputs.without_spirt), disasm(outputs.with_spirt)];
196+
197+
// HACK(eddyb) merge the two outputs into a single "dump".
198+
if without_spirt == with_spirt {
199+
without_spirt
200+
} else {
201+
format!(
202+
"=== without SPIR-T ===\n\
203+
{without_spirt}\n\
204+
\n\
205+
=== with SPIR-T ===\n\
206+
{with_spirt}"
207+
)
208+
}
209+
};
152210

153211
let expected = expected
154212
.split('\n')
@@ -471,7 +529,8 @@ fn use_exported_func_param_attr() {
471529

472530
let result = assemble_and_link(&[&a, &b]).unwrap();
473531

474-
let expect = r#"OpCapability Kernel
532+
let expect = r#"=== without SPIR-T ===
533+
OpCapability Kernel
475534
OpCapability Linkage
476535
OpMemoryModel Logical OpenCL
477536
OpDecorate %1 FuncParamAttr Zext
@@ -492,6 +551,30 @@ fn use_exported_func_param_attr() {
492551
%10 = OpLabel
493552
%11 = OpLoad %6 %4
494553
OpReturn
554+
OpFunctionEnd
555+
556+
=== with SPIR-T ===
557+
OpCapability Linkage
558+
OpCapability Kernel
559+
OpMemoryModel Logical OpenCL
560+
OpDecorate %1 FuncParamAttr Zext
561+
OpDecorate %2 FuncParamAttr Sext
562+
OpDecorate %3 LinkageAttributes "HACK(eddyb) keep function alive" Export
563+
OpDecorate %4 LinkageAttributes "foo" Export
564+
%5 = OpTypeVoid
565+
%6 = OpTypeInt 32 0
566+
%7 = OpTypeFunction %5 %6
567+
%3 = OpFunction %5 None %7
568+
%1 = OpFunctionParameter %6
569+
%8 = OpLabel
570+
%9 = OpLoad %6 %1
571+
OpReturn
572+
OpFunctionEnd
573+
%4 = OpFunction %5 None %7
574+
%2 = OpFunctionParameter %6
575+
%10 = OpLabel
576+
%11 = OpLoad %6 %2
577+
OpReturn
495578
OpFunctionEnd"#;
496579

497580
without_header_eq(result, expect);
@@ -550,7 +633,8 @@ fn names_and_decorations() {
550633

551634
let result = assemble_and_link(&[&a, &b]).unwrap();
552635

553-
let expect = r#"OpCapability Kernel
636+
let expect = r#"=== without SPIR-T ===
637+
OpCapability Kernel
554638
OpCapability Linkage
555639
OpMemoryModel Logical OpenCL
556640
OpName %1 "foo"
@@ -575,6 +659,34 @@ fn names_and_decorations() {
575659
%11 = OpLabel
576660
%12 = OpLoad %6 %2
577661
OpReturn
662+
OpFunctionEnd
663+
664+
=== with SPIR-T ===
665+
OpCapability Linkage
666+
OpCapability Kernel
667+
OpMemoryModel Logical OpenCL
668+
OpName %1 "foo"
669+
OpName %2 "param"
670+
OpDecorate %3 Restrict
671+
OpDecorate %3 NonWritable
672+
OpDecorate %2 Restrict
673+
OpDecorate %4 LinkageAttributes "HACK(eddyb) keep function alive" Export
674+
OpDecorate %1 LinkageAttributes "foo" Export
675+
%5 = OpTypeVoid
676+
%6 = OpTypeInt 32 0
677+
%7 = OpTypePointer Function %6
678+
%8 = OpTypeFunction %5 %7
679+
%4 = OpFunction %5 None %8
680+
%3 = OpFunctionParameter %7
681+
%9 = OpLabel
682+
%10 = OpLoad %6 %3
683+
OpReturn
684+
OpFunctionEnd
685+
%1 = OpFunction %5 None %8
686+
%2 = OpFunctionParameter %7
687+
%11 = OpLabel
688+
%12 = OpLoad %6 %2
689+
OpReturn
578690
OpFunctionEnd"#;
579691

580692
without_header_eq(result, expect);

tests/src/main.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ struct Opt {
2727
}
2828

2929
impl Opt {
30-
pub fn environments(&self) -> Vec<String> {
31-
self.target_env.split(',').map(String::from).collect()
30+
pub fn environments(&self) -> impl Iterator<Item = &str> {
31+
self.target_env.split(',')
3232
}
3333
}
3434

@@ -125,12 +125,20 @@ impl Runner {
125125
.join(" ")
126126
}
127127

128-
for env in self.opt.environments() {
128+
for (env, spirt) in self
129+
.opt
130+
.environments()
131+
.flat_map(|env| [(env, false), (env, true)])
132+
{
133+
// HACK(eddyb) in order to allow *some* tests to have separate output
134+
// with the SPIR-T support enabled (via `--spirt`), while keeping
135+
// *most* of the tests unchanged, we take advantage of "stage IDs",
136+
// which offer `// only-S` and `// ignore-S` for any stage ID `S`.
137+
let stage_id = if spirt { "spirt" } else { "not_spirt" };
138+
129139
let target = format!("{}{}", TARGET_PREFIX, env);
130-
let mut config = compiletest::Config::default();
131140
let libs = build_deps(&self.deps_target_dir, &self.codegen_backend_path, &target);
132-
133-
let flags = test_rustc_flags(
141+
let mut flags = test_rustc_flags(
134142
&self.codegen_backend_path,
135143
&libs,
136144
&[
@@ -142,14 +150,22 @@ impl Runner {
142150
.join(DepKind::ProcMacro.target_dir_suffix(&target)),
143151
],
144152
);
145-
146-
config.target_rustcflags = Some(flags);
147-
config.mode = mode.parse().expect("Invalid mode");
148-
config.target = target;
149-
config.src_base = self.tests_dir.join(mode);
150-
config.build_base = self.compiletest_build_dir.clone();
151-
config.bless = self.opt.bless;
152-
config.filters = self.opt.filters.clone();
153+
if spirt {
154+
flags += " -Cllvm-args=--spirt";
155+
}
156+
157+
let config = compiletest::Config {
158+
stage_id: stage_id.to_string(),
159+
target_rustcflags: Some(flags),
160+
mode: mode.parse().expect("Invalid mode"),
161+
target,
162+
src_base: self.tests_dir.join(mode),
163+
build_base: self.compiletest_build_dir.clone(),
164+
bless: self.opt.bless,
165+
filters: self.opt.filters.clone(),
166+
..compiletest::Config::default()
167+
};
168+
// FIXME(eddyb) do we need this? shouldn't `compiletest` be independent?
153169
config.clean_rmeta();
154170

155171
compiletest::run_tests(&config);

tests/ui/arch/all_memory_barrier.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// normalize-stderr-not_spirt "OpLine %8 11 1" -> "OpNoLine"
2+
13
// build-pass
24
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
35
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier::all_memory_barrier

tests/ui/arch/all_memory_barrier.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
%4 = OpLabel
33
OpLine %5 75 4
44
OpMemoryBarrier %6 %7
5-
OpLine %8 9 1
5+
OpNoLine
66
OpReturn
77
OpFunctionEnd

tests/ui/arch/all_memory_barrier_with_group_sync.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// normalize-stderr-not_spirt "OpLine %9 11 1" -> "OpNoLine"
2+
13
// build-pass
24
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
35
// compile-flags: -C llvm-args=--disassemble-fn=all_memory_barrier_with_group_sync::all_memory_barrier_with_group_sync

tests/ui/arch/all_memory_barrier_with_group_sync.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
%4 = OpLabel
33
OpLine %5 41 4
44
OpControlBarrier %6 %7 %8
5-
OpLine %9 9 1
5+
OpNoLine
66
OpReturn
77
OpFunctionEnd

tests/ui/arch/device_memory_barrier.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// normalize-stderr-not_spirt "OpLine %8 11 1" -> "OpNoLine"
2+
13
// build-pass
24
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
35
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier::device_memory_barrier

tests/ui/arch/device_memory_barrier.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
%4 = OpLabel
33
OpLine %5 75 4
44
OpMemoryBarrier %6 %7
5-
OpLine %8 9 1
5+
OpNoLine
66
OpReturn
77
OpFunctionEnd

tests/ui/arch/device_memory_barrier_with_group_sync.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// normalize-stderr-not_spirt "OpLine %9 11 1" -> "OpNoLine"
2+
13
// build-pass
24
// compile-flags: -C target-feature=+VulkanMemoryModelDeviceScopeKHR,+ext:SPV_KHR_vulkan_memory_model
35
// compile-flags: -C llvm-args=--disassemble-fn=device_memory_barrier_with_group_sync::device_memory_barrier_with_group_sync

tests/ui/arch/device_memory_barrier_with_group_sync.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
%4 = OpLabel
33
OpLine %5 41 4
44
OpControlBarrier %6 %7 %8
5-
OpLine %9 9 1
5+
OpNoLine
66
OpReturn
77
OpFunctionEnd

0 commit comments

Comments
 (0)