Skip to content

Commit 5f5592c

Browse files
committed
Auto merge of #58791 - denzp:asm-compile-tests, r=alexcrichton
Introduce assembly tests suite The change introduces a new test suite - **Assembly** tests. The motivation behind this is an ability to perform end-to-end codegen testing with LLVM backend. Turned out, NVPTX backend sometimes missing common Rust features (`i128` and libcalls in the past, and still full atomics support) due to different reasons. Prior to this change, basic NVPTX assembly tests were implemented within `run-make` suite. Now, it's easier to write additional and maintain existing tests for the target. cc @gnzlbg @peterhj cc @eddyb I adjusted mangling scheme expectation, so there is no need to change the tests for #57967
2 parents 4ec9ffd + acc43c7 commit 5f5592c

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

src/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub enum Mode {
2626
Ui,
2727
JsDocTest,
2828
MirOpt,
29+
Assembly,
2930
}
3031

3132
impl Mode {
@@ -62,6 +63,7 @@ impl FromStr for Mode {
6263
"ui" => Ok(Ui),
6364
"js-doc-test" => Ok(JsDocTest),
6465
"mir-opt" => Ok(MirOpt),
66+
"assembly" => Ok(Assembly),
6567
_ => Err(()),
6668
}
6769
}
@@ -86,6 +88,7 @@ impl fmt::Display for Mode {
8688
Ui => "ui",
8789
JsDocTest => "js-doc-test",
8890
MirOpt => "mir-opt",
91+
Assembly => "assembly",
8992
};
9093
fmt::Display::fmt(s, f)
9194
}

src/header.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ pub struct TestProps {
335335
pub failure_status: i32,
336336
pub run_rustfix: bool,
337337
pub rustfix_only_machine_applicable: bool,
338+
pub assembly_output: Option<String>,
338339
}
339340

340341
impl TestProps {
@@ -370,6 +371,7 @@ impl TestProps {
370371
failure_status: -1,
371372
run_rustfix: false,
372373
rustfix_only_machine_applicable: false,
374+
assembly_output: None,
373375
}
374376
}
375377

@@ -517,6 +519,10 @@ impl TestProps {
517519
self.rustfix_only_machine_applicable =
518520
config.parse_rustfix_only_machine_applicable(ln);
519521
}
522+
523+
if self.assembly_output.is_none() {
524+
self.assembly_output = config.parse_assembly_output(ln);
525+
}
520526
});
521527

522528
if self.failure_status == -1 {
@@ -594,6 +600,7 @@ impl Config {
594600

595601
fn parse_aux_build(&self, line: &str) -> Option<String> {
596602
self.parse_name_value_directive(line, "aux-build")
603+
.map(|r| r.trim().to_string())
597604
}
598605

599606
fn parse_compile_flags(&self, line: &str) -> Option<String> {
@@ -676,6 +683,11 @@ impl Config {
676683
self.parse_name_directive(line, "skip-codegen")
677684
}
678685

686+
fn parse_assembly_output(&self, line: &str) -> Option<String> {
687+
self.parse_name_value_directive(line, "assembly-output")
688+
.map(|r| r.trim().to_string())
689+
}
690+
679691
fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> {
680692
self.parse_name_value_directive(line, name).map(|nv| {
681693
// nv is either FOO or FOO=BAR

src/runtest.rs

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::common::{output_base_dir, output_base_name, output_testname_unique};
44
use crate::common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
55
use crate::common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind};
66
use crate::common::{Config, TestPaths};
7-
use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest};
7+
use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
88
use diff;
99
use crate::errors::{self, Error, ErrorKind};
1010
use filetime::FileTime;
@@ -275,6 +275,7 @@ impl<'test> TestCx<'test> {
275275
RunMake => self.run_rmake_test(),
276276
RunPass | Ui => self.run_ui_test(),
277277
MirOpt => self.run_mir_opt_test(),
278+
Assembly => self.run_assembly_test(),
278279
JsDocTest => self.run_js_doc_test(),
279280
}
280281
}
@@ -1606,6 +1607,7 @@ impl<'test> TestCx<'test> {
16061607
|| self.config.target.contains("emscripten")
16071608
|| (self.config.target.contains("musl") && !aux_props.force_host)
16081609
|| self.config.target.contains("wasm32")
1610+
|| self.config.target.contains("nvptx")
16091611
{
16101612
// We primarily compile all auxiliary libraries as dynamic libraries
16111613
// to avoid code size bloat and large binaries as much as possible
@@ -1805,7 +1807,7 @@ impl<'test> TestCx<'test> {
18051807
rustc.arg(dir_opt);
18061808
}
18071809
RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb
1808-
| Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest => {
1810+
| Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest | Assembly => {
18091811
// do not use JSON output
18101812
}
18111813
}
@@ -2100,12 +2102,37 @@ impl<'test> TestCx<'test> {
21002102
self.compose_and_run_compiler(rustc, None)
21012103
}
21022104

2103-
fn check_ir_with_filecheck(&self) -> ProcRes {
2104-
let irfile = self.output_base_name().with_extension("ll");
2105+
fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
2106+
// This works with both `--emit asm` (as default output name for the assembly)
2107+
// and `ptx-linker` because the latter can write output at requested location.
2108+
let output_path = self.output_base_name().with_extension("s");
2109+
2110+
let output_file = TargetLocation::ThisFile(output_path.clone());
2111+
let mut rustc = self.make_compile_args(&self.testpaths.file, output_file);
2112+
2113+
rustc.arg("-L").arg(self.aux_output_dir_name());
2114+
2115+
match self.props.assembly_output.as_ref().map(AsRef::as_ref) {
2116+
Some("emit-asm") => {
2117+
rustc.arg("--emit=asm");
2118+
}
2119+
2120+
Some("ptx-linker") => {
2121+
// No extra flags needed.
2122+
}
2123+
2124+
Some(_) => self.fatal("unknown 'assembly-output' header"),
2125+
None => self.fatal("missing 'assembly-output' header"),
2126+
}
2127+
2128+
(self.compose_and_run_compiler(rustc, None), output_path)
2129+
}
2130+
2131+
fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
21052132
let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
21062133
filecheck
21072134
.arg("--input-file")
2108-
.arg(irfile)
2135+
.arg(output)
21092136
.arg(&self.testpaths.file);
21102137
// It would be more appropriate to make most of the arguments configurable through
21112138
// a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very
@@ -2124,12 +2151,29 @@ impl<'test> TestCx<'test> {
21242151
self.fatal("missing --llvm-filecheck");
21252152
}
21262153

2127-
let mut proc_res = self.compile_test_and_save_ir();
2154+
let proc_res = self.compile_test_and_save_ir();
2155+
if !proc_res.status.success() {
2156+
self.fatal_proc_rec("compilation failed!", &proc_res);
2157+
}
2158+
2159+
let output_path = self.output_base_name().with_extension("ll");
2160+
let proc_res = self.verify_with_filecheck(&output_path);
2161+
if !proc_res.status.success() {
2162+
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
2163+
}
2164+
}
2165+
2166+
fn run_assembly_test(&self) {
2167+
if self.config.llvm_filecheck.is_none() {
2168+
self.fatal("missing --llvm-filecheck");
2169+
}
2170+
2171+
let (proc_res, output_path) = self.compile_test_and_save_assembly();
21282172
if !proc_res.status.success() {
21292173
self.fatal_proc_rec("compilation failed!", &proc_res);
21302174
}
21312175

2132-
proc_res = self.check_ir_with_filecheck();
2176+
let proc_res = self.verify_with_filecheck(&output_path);
21332177
if !proc_res.status.success() {
21342178
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
21352179
}

src/util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
4141
("armv7", "arm"),
4242
("armv7s", "arm"),
4343
("asmjs", "asmjs"),
44-
("cuda", "cuda"),
4544
("hexagon", "hexagon"),
4645
("i386", "x86"),
4746
("i586", "x86"),
@@ -59,6 +58,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
5958
("mipsisa64r6", "mips64"),
6059
("mipsisa64r6el", "mips64"),
6160
("msp430", "msp430"),
61+
("nvptx64", "nvptx64"),
6262
("powerpc", "powerpc"),
6363
("powerpc64", "powerpc64"),
6464
("powerpc64le", "powerpc64"),
@@ -166,7 +166,7 @@ fn test_get_arch_failure() {
166166
fn test_get_arch() {
167167
assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu"));
168168
assert_eq!("x86_64", get_arch("amd64"));
169-
assert_eq!("cuda", get_arch("nvptx64-nvidia-cuda"));
169+
assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda"));
170170
}
171171

172172
#[test]

0 commit comments

Comments
 (0)