Use capstone to validate precise-output tests (#5780)

Use the capstone library to disassemble precise-output tests, in addition to pretty-printing their vcode.
This commit is contained in:
Trevor Elliott
2023-02-15 16:35:10 -08:00
committed by GitHub
parent eabd43a178
commit f04decc4a1
277 changed files with 39340 additions and 98 deletions

View File

@@ -5,6 +5,9 @@
use crate::subtest::{run_filecheck, Context, SubTest};
use anyhow::{bail, Result};
use cranelift_codegen::ir;
use cranelift_codegen::ir::function::FunctionParameters;
use cranelift_codegen::isa;
use cranelift_codegen::CompiledCode;
use cranelift_reader::{TestCommand, TestOption};
use log::info;
use similar::TextDiff;
@@ -48,6 +51,7 @@ impl SubTest for TestCompile {
fn run(&self, func: Cow<ir::Function>, context: &Context) -> Result<()> {
let isa = context.isa.expect("compile needs an ISA");
let params = func.params.clone();
let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned());
// With `MachBackend`s, we need to explicitly request dissassembly results.
@@ -58,20 +62,35 @@ impl SubTest for TestCompile {
.map_err(|e| crate::pretty_anyhow_error(&e.func, e.inner))?;
let total_size = compiled_code.code_info().total_size;
let disasm = compiled_code.disasm.as_ref().unwrap();
let vcode = compiled_code.vcode.as_ref().unwrap();
info!("Generated {} bytes of code:\n{}", total_size, disasm);
info!("Generated {} bytes of code:\n{}", total_size, vcode);
if self.precise_output {
check_precise_output(&disasm, context)
check_precise_output(isa, &params, &compiled_code, context)
} else {
run_filecheck(&disasm, context)
run_filecheck(&vcode, context)
}
}
}
fn check_precise_output(text: &str, context: &Context) -> Result<()> {
let actual = text.lines().collect::<Vec<_>>();
fn check_precise_output(
isa: &dyn isa::TargetIsa,
params: &FunctionParameters,
compiled_code: &CompiledCode,
context: &Context,
) -> Result<()> {
let cs = isa
.to_capstone()
.map_err(|e| anyhow::format_err!("{}", e))?;
let dis = compiled_code.disassemble(Some(params), &cs)?;
let actual = Vec::from_iter(
std::iter::once("VCode:")
.chain(compiled_code.vcode.as_ref().unwrap().lines())
.chain(["", "Disassembled:"])
.chain(dis.lines()),
);
// Use the comments after the function to build the test expectation.
let expected = context