cranelift: Use requested ISA Flags in run tests (#4450)

This commit is contained in:
Afonso Bordado
2022-07-15 20:09:07 +01:00
committed by GitHub
parent 80976b6fc7
commit eca0a73453
12 changed files with 97 additions and 26 deletions

View File

@@ -113,6 +113,17 @@ impl Value {
_ => None,
}
}
/// Builds a string from the current value
pub fn value_string(&self) -> String {
match self.kind() {
SettingKind::Enum => self.as_enum().map(|b| b.to_string()),
SettingKind::Num => self.as_num().map(|b| b.to_string()),
SettingKind::Bool => self.as_bool().map(|b| b.to_string()),
SettingKind::Preset => unreachable!(),
}
.unwrap()
}
}
impl fmt::Display for Value {

View File

@@ -1,5 +1,6 @@
test run
target s390x
target s390x has_mie2
target aarch64
target aarch64 has_lse
target x86_64

View File

@@ -1,5 +1,6 @@
test run
target s390x
target s390x has_mie2
; We can't test that these instructions are right regarding atomicity, but we can
; test if they perform their operation correctly
@@ -457,4 +458,3 @@ block0(v0: i32, v1: i64, v2: i8):
; run: %atomic_rmw_xchg_big_i8(0x12345678, 2, 0xff) == 0x1234ff78
; run: %atomic_rmw_xchg_big_i8(0x12345678, 3, 0x11) == 0x12345611
; run: %atomic_rmw_xchg_big_i8(0x12345678, 3, 0xff) == 0x123456ff

View File

@@ -1,5 +1,6 @@
test run
target s390x
target s390x has_mie2
target aarch64
target aarch64 has_lse
target x86_64
@@ -456,4 +457,3 @@ block0(v0: i32, v1: i64, v2: i8):
; run: %atomic_rmw_xchg_little_i8(0x12345678, 1, 0xff) == 0x1234ff78
; run: %atomic_rmw_xchg_little_i8(0x12345678, 0, 0x11) == 0x12345611
; run: %atomic_rmw_xchg_little_i8(0x12345678, 0, 0xff) == 0x123456ff

View File

@@ -1,6 +1,7 @@
test run
target aarch64
target s390x
target s390x has_mie2
; target x86_64 TODO: Not yet implemented on x86_64
function %bnot_band() -> b1 {

View File

@@ -1,7 +1,6 @@
test interpret
test run
target aarch64
target arm
target s390x
target x86_64

View File

@@ -2,6 +2,7 @@ test interpret
test run
target aarch64
target x86_64
target x86_64 has_lzcnt
function %clz_i8(i8) -> i8 {
block0(v0: i8):

View File

@@ -1,6 +1,5 @@
test run
target aarch64
target arm
target s390x
target x86_64

View File

@@ -2,6 +2,7 @@ test interpret
test run
target aarch64
target x86_64
target x86_64 has_bmi1
function %ctz_i8(i8) -> i8 {
block0(v0: i8):

View File

@@ -1,6 +1,5 @@
test run
target aarch64
target arm
target s390x
set avoid_div_traps=false
target x86_64

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
target x86_64
target x86_64 has_popcnt=1
target x86_64 has_popcnt
function %popcnt_i8(i8) -> i8 {
block0(v0: i8):

View File

@@ -6,13 +6,14 @@ use crate::function_runner::SingleFunctionCompiler;
use crate::runtest_environment::{HeapMemory, RuntestEnvironment};
use crate::subtest::{Context, SubTest};
use cranelift_codegen::data_value::DataValue;
use cranelift_codegen::ir;
use cranelift_codegen::ir::Type;
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::settings::Configurable;
use cranelift_codegen::{ir, settings};
use cranelift_reader::parse_run_command;
use cranelift_reader::TestCommand;
use log::trace;
use std::borrow::Cow;
use target_lexicon::Architecture;
struct TestRun;
@@ -24,6 +25,68 @@ pub fn subtest(parsed: &TestCommand) -> anyhow::Result<Box<dyn SubTest>> {
Ok(Box::new(TestRun))
}
/// Builds a [TargetIsa] for the current host.
///
/// ISA Flags can be overridden by passing [Value]'s via `isa_flags`.
fn build_host_isa(
infer_native_flags: bool,
flags: settings::Flags,
isa_flags: Vec<settings::Value>,
) -> Box<dyn TargetIsa> {
let mut builder = cranelift_native::builder_with_options(infer_native_flags)
.expect("Unable to build a TargetIsa for the current host");
for value in isa_flags {
builder.set(value.name, &value.value_string()).unwrap();
}
builder.finish(flags).unwrap()
}
/// Checks if the host's ISA is compatible with the one requested by the test.
fn is_isa_compatible(
context: &Context,
host: &dyn TargetIsa,
requested: &dyn TargetIsa,
) -> Result<(), String> {
// If this test requests to run on a completely different
// architecture than the host platform then we skip it entirely,
// since we won't be able to natively execute machine code.
let host_arch = host.triple().architecture;
let requested_arch = requested.triple().architecture;
if host_arch != requested_arch {
return Err(format!(
"skipped {}: host can't run {:?} programs",
context.file_path, requested_arch
));
}
// We need to check that the requested ISA does not have any flags that
// we can't natively support on the host.
let requested_flags = requested.isa_flags();
for req_value in requested_flags {
if let Some(requested) = req_value.as_bool() {
let available_in_host = host
.isa_flags()
.iter()
.find(|val| val.name == req_value.name)
.and_then(|val| val.as_bool())
.unwrap_or(false);
if requested && !available_in_host {
return Err(format!(
"skipped {}: host does not support ISA flag {}",
context.file_path, req_value.name
));
}
} else {
unimplemented!("ISA flag {} of kind {:?}", req_value.name, req_value.kind());
}
}
Ok(())
}
impl SubTest for TestRun {
fn name(&self) -> &'static str {
"run"
@@ -38,18 +101,6 @@ impl SubTest for TestRun {
}
fn run(&self, func: Cow<ir::Function>, context: &Context) -> anyhow::Result<()> {
// If this test requests to run on a completely different
// architecture than the host platform then we skip it entirely,
// since we won't be able to natively execute machine code.
let requested_arch = context.isa.unwrap().triple().architecture;
if requested_arch != Architecture::host() {
println!(
"skipped {}: host can't run {:?} programs",
context.file_path, requested_arch
);
return Ok(());
}
// Disable runtests with pinned reg enabled.
// We've had some abi issues that the trampoline isn't quite ready for.
if context.flags.enable_pinned_reg() {
@@ -60,18 +111,26 @@ impl SubTest for TestRun {
.join("\n")));
}
let host_isa = build_host_isa(true, context.flags.clone(), vec![]);
let requested_isa = context.isa.unwrap();
if let Err(e) = is_isa_compatible(context, host_isa.as_ref(), requested_isa) {
println!("{}", e);
return Ok(());
}
// We can't use the requested ISA directly since it does not contain info
// about the operating system / calling convention / etc..
//
// Copy the requested ISA flags into the host ISA and use that.
let isa = build_host_isa(false, context.flags.clone(), requested_isa.isa_flags());
let test_env = RuntestEnvironment::parse(&context.details.comments[..])?;
let mut compiler = SingleFunctionCompiler::with_host_isa(context.flags.clone())?;
let mut compiler = SingleFunctionCompiler::new(isa);
for comment in context.details.comments.iter() {
if let Some(command) = parse_run_command(comment.text, &func.signature)? {
trace!("Parsed run command: {}", command);
// Note that here we're also explicitly ignoring `context.isa`,
// regardless of what's requested. We want to use the native
// host ISA no matter what here, so the ISA listed in the file
// is only used as a filter to not run into situations like
// running x86_64 code on aarch64 platforms.
let compiled_fn = compiler.compile(func.clone().into_owned())?;
command
.run(|_, run_args| {