cranelift: Use requested ISA Flags in run tests (#4450)
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
test run
|
||||
target s390x
|
||||
target s390x has_mie2
|
||||
target aarch64
|
||||
target aarch64 has_lse
|
||||
target x86_64
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
target arm
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
test run
|
||||
target aarch64
|
||||
target arm
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
test run
|
||||
target aarch64
|
||||
target arm
|
||||
target s390x
|
||||
set avoid_div_traps=false
|
||||
target x86_64
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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| {
|
||||
|
||||
Reference in New Issue
Block a user