Skip to content

Commit

Permalink
Add support for assembly tests
Browse files Browse the repository at this point in the history
This is a port of rust-lang/rust#58791
  • Loading branch information
alessandrod committed Nov 20, 2020
1 parent 3ca5f4c commit f34c4dd
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 7 deletions.
3 changes: 3 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub enum Mode {
RunMake,
Ui,
MirOpt,
Assembly,
}

impl Mode {
Expand Down Expand Up @@ -72,6 +73,7 @@ impl FromStr for Mode {
"run-make" => Ok(RunMake),
"ui" => Ok(Ui),
"mir-opt" => Ok(MirOpt),
"assembly" => Ok(Assembly),
_ => Err(()),
}
}
Expand All @@ -95,6 +97,7 @@ impl fmt::Display for Mode {
RunMake => "run-make",
Ui => "ui",
MirOpt => "mir-opt",
Assembly => "assembly",
},
f)
}
Expand Down
12 changes: 12 additions & 0 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ pub struct TestProps {
pub normalize_stderr: Vec<(String, String)>,
pub run_rustfix: bool,
pub rustfix_only_machine_applicable: bool,
pub assembly_output: Option<String>,
}

impl TestProps {
Expand Down Expand Up @@ -254,6 +255,7 @@ impl TestProps {
normalize_stderr: vec![],
run_rustfix: false,
rustfix_only_machine_applicable: false,
assembly_output: None,
}
}

Expand Down Expand Up @@ -388,6 +390,10 @@ impl TestProps {
self.rustfix_only_machine_applicable =
config.parse_rustfix_only_machine_applicable(ln);
}

if self.assembly_output.is_none() {
self.assembly_output = config.parse_assembly_output(ln);
}
});

for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
Expand Down Expand Up @@ -446,6 +452,7 @@ impl Config {

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

fn parse_compile_flags(&self, line: &str) -> Option<String> {
Expand Down Expand Up @@ -505,6 +512,11 @@ impl Config {
self.parse_name_directive(line, "run-pass")
}

fn parse_assembly_output(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "assembly-output")
.map(|r| r.trim().to_string())
}

fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> {
self.parse_name_value_directive(line, name).map(|nv| {
// nv is either FOO or FOO=BAR
Expand Down
58 changes: 51 additions & 7 deletions src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use common::{Config, TestPaths};
use common::{UI_FIXED, UI_STDERR, UI_STDOUT};
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
use common::{Incremental, RunMake, Ui, MirOpt};
use common::{Incremental, RunMake, Ui, MirOpt, Assembly};
use diff;
use errors::{self, ErrorKind, Error};
use filetime::FileTime;
Expand Down Expand Up @@ -142,6 +142,7 @@ impl<'test> TestCx<'test> {
RunMake => self.run_rmake_test(),
Ui => self.run_ui_test(),
MirOpt => self.run_mir_opt_test(),
Assembly => self.run_assembly_test(),
}
}

Expand Down Expand Up @@ -1441,7 +1442,8 @@ actual:\n\
Codegen |
Rustdoc |
RunMake |
CodegenUnits => {
CodegenUnits |
Assembly => {
// do not use JSON output
}
}
Expand Down Expand Up @@ -1712,10 +1714,35 @@ actual:\n\
self.compose_and_run_compiler(rustc, None)
}

fn check_ir_with_filecheck(&self) -> ProcRes {
let irfile = self.output_base_name().with_extension("ll");
fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
// This works with both `--emit asm` (as default output name for the assembly)
// and `ptx-linker` because the latter can write output at requested location.
let output_path = self.output_base_name().with_extension("s");

let output_file = TargetLocation::ThisFile(output_path.clone());
let mut rustc = self.make_compile_args(&self.testpaths.file, output_file, AllowUnused::No);

rustc.arg("-L").arg(self.aux_output_dir_name());

match self.props.assembly_output.as_ref().map(AsRef::as_ref) {
Some("emit-asm") => {
rustc.arg("--emit=asm");
}

Some("ptx-linker") => {
// No extra flags needed.
}

Some(_) => self.fatal("unknown 'assembly-output' header"),
None => self.fatal("missing 'assembly-output' header"),
}

(self.compose_and_run_compiler(rustc, None), output_path)
}

fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
filecheck.arg("--input-file").arg(irfile)
filecheck.arg("--input-file").arg(output)
.arg(&self.testpaths.file);
self.compose_and_run(filecheck, "", None, None)
}
Expand All @@ -1727,12 +1754,29 @@ actual:\n\
self.fatal("missing --llvm-filecheck");
}

let mut proc_res = self.compile_test_and_save_ir();
let proc_res = self.compile_test_and_save_ir();
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

let output_path = self.output_base_name().with_extension("ll");
let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
}
}

fn run_assembly_test(&self) {
if self.config.llvm_filecheck.is_none() {
self.fatal("missing --llvm-filecheck");
}

let (proc_res, output_path) = self.compile_test_and_save_assembly();
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}

proc_res = self.check_ir_with_filecheck();
let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
}
Expand Down
1 change: 1 addition & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
("i686", "x86"),
("mips", "mips"),
("msp430", "msp430"),
("nvptx64", "nvptx64"),
("powerpc", "powerpc"),
("powerpc64", "powerpc64"),
("s390x", "s390x"),
Expand Down

0 comments on commit f34c4dd

Please sign in to comment.