Cranelift: ensure ISA level needed for SIMD is present when SIMD is enabled. (#3816)

Addresses #3809: when we are asked to create a Cranelift backend with
shared flags that indicate support for SIMD, we should check that the
ISA level needed for our SIMD lowerings is present.
This commit is contained in:
Chris Fallin
2022-02-16 17:29:30 -08:00
committed by GitHub
parent ef17a36852
commit 1c014d129a
55 changed files with 172 additions and 84 deletions

View File

@@ -17,19 +17,22 @@ fn define_settings(shared: &SettingGroup) -> SettingGroup {
"has_sse3",
"Has support for SSE3.",
"SSE3: CPUID.01H:ECX.SSE3[bit 0]",
false,
// Needed for default `enable_simd` setting.
true,
);
let has_ssse3 = settings.add_bool(
"has_ssse3",
"Has support for SSSE3.",
"SSSE3: CPUID.01H:ECX.SSSE3[bit 9]",
false,
// Needed for default `enable_simd` setting.
true,
);
let has_sse41 = settings.add_bool(
"has_sse41",
"Has support for SSE4.1.",
"SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]",
false,
// Needed for default `enable_simd` setting.
true,
);
let has_sse42 = settings.add_bool(
"has_sse42",

View File

@@ -85,7 +85,8 @@ mod tests {
fn test_simple_func() {
let isa = lookup(triple!("aarch64"))
.expect("expect aarch64 ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("Creating compiler backend");
let mut context = Context::for_function(create_function(
CallConv::SystemV,
@@ -127,7 +128,8 @@ mod tests {
fn test_multi_return_func() {
let isa = lookup(triple!("aarch64"))
.expect("expect aarch64 ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("Creating compiler backend");
let mut context = Context::for_function(create_multi_return_function(CallConv::SystemV));

View File

@@ -172,7 +172,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
constructor: |triple, shared_flags, builder| {
let isa_flags = aarch64_settings::Flags::new(&shared_flags, builder);
let backend = AArch64Backend::new_with_flags(triple, shared_flags, isa_flags);
Box::new(backend)
Ok(Box::new(backend))
},
}
}

View File

@@ -139,7 +139,8 @@ impl fmt::Display for LookupError {
pub struct Builder {
triple: Triple,
setup: settings::Builder,
constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<dyn TargetIsa>,
constructor:
fn(Triple, settings::Flags, settings::Builder) -> CodegenResult<Box<dyn TargetIsa>>,
}
impl Builder {
@@ -153,9 +154,13 @@ impl Builder {
self.setup.iter()
}
/// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
/// fully configured `TargetIsa` trait object.
pub fn finish(self, shared_flags: settings::Flags) -> Box<dyn TargetIsa> {
/// Combine the ISA-specific settings with the provided
/// ISA-independent settings and allocate a fully configured
/// `TargetIsa` trait object. May return an error if some of the
/// flags are inconsistent or incompatible: for example, some
/// platform-independent features, like general SIMD support, may
/// need certain ISA extensions to be enabled.
pub fn finish(self, shared_flags: settings::Flags) -> CodegenResult<Box<dyn TargetIsa>> {
(self.constructor)(self.triple, shared_flags, self.setup)
}
}

View File

@@ -100,7 +100,8 @@ mod tests {
fn test_simple_func() {
let isa = lookup(triple!("s390x"))
.expect("expect s390x ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("Creating compiler backend");
let mut context = Context::for_function(create_function(
CallConv::SystemV,
@@ -142,7 +143,8 @@ mod tests {
fn test_multi_return_func() {
let isa = lookup(triple!("s390x"))
.expect("expect s390x ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("Creating compiler backend");
let mut context = Context::for_function(create_multi_return_function(
CallConv::SystemV,

View File

@@ -179,7 +179,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
constructor: |triple, shared_flags, builder| {
let isa_flags = s390x_settings::Flags::new(&shared_flags, builder);
let backend = S390xBackend::new_with_flags(triple, shared_flags, isa_flags);
Box::new(backend)
Ok(Box::new(backend))
},
}
}

View File

@@ -112,7 +112,8 @@ mod tests {
fn test_simple_func() {
let isa = lookup(triple!("x86_64"))
.expect("expect x86 ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("expect backend creation to succeed");
let mut context = Context::for_function(create_function(
CallConv::SystemV,
@@ -154,7 +155,8 @@ mod tests {
fn test_multi_return_func() {
let isa = lookup(triple!("x86_64"))
.expect("expect x86 ISA")
.finish(Flags::new(builder()));
.finish(Flags::new(builder()))
.expect("expect backend creation to succeed");
let mut context = Context::for_function(create_multi_return_function(CallConv::SystemV));

View File

@@ -11,7 +11,7 @@ use crate::isa::Builder as IsaBuilder;
use crate::machinst::{
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
};
use crate::result::CodegenResult;
use crate::result::{CodegenError, CodegenResult};
use crate::settings::{self as shared_settings, Flags};
use alloc::{boxed::Box, vec::Vec};
use core::fmt;
@@ -174,10 +174,21 @@ fn isa_constructor(
triple: Triple,
shared_flags: Flags,
builder: shared_settings::Builder,
) -> Box<dyn TargetIsa> {
) -> CodegenResult<Box<dyn TargetIsa>> {
let isa_flags = x64_settings::Flags::new(&shared_flags, builder);
// Check for compatibility between flags and ISA level
// requested. In particular, SIMD support requires SSE4.1.
if shared_flags.enable_simd() {
if !isa_flags.has_sse3() || !isa_flags.has_ssse3() || !isa_flags.has_sse41() {
return Err(CodegenError::Unsupported(
"SIMD support requires SSE3, SSSE3, and SSE4.1 on x86_64.".into(),
));
}
}
let backend = X64Backend::new_with_flags(triple, shared_flags, isa_flags);
Box::new(backend)
Ok(Box::new(backend))
}
#[cfg(test)]
@@ -332,4 +343,20 @@ mod test {
assert_eq!(code, &golden[..]);
}
// Check that feature tests for SIMD work correctly.
#[test]
fn simd_required_features() {
let mut shared_flags_builder = settings::builder();
shared_flags_builder.set("enable_simd", "true").unwrap();
let shared_flags = settings::Flags::new(shared_flags_builder);
let mut isa_builder = crate::isa::lookup_by_name("x86_64").unwrap();
isa_builder.set("has_sse3", "false").unwrap();
isa_builder.set("has_ssse3", "false").unwrap();
isa_builder.set("has_sse41", "false").unwrap();
assert!(matches!(
isa_builder.finish(shared_flags),
Err(CodegenError::Unsupported(_)),
));
}
}

View File

@@ -1,6 +1,6 @@
test compile precise-output
set enable_simd
target x86_64 has_ssse3 has_sse41
target x86_64 has_sse3 has_ssse3 has_sse41
;; shuffle

View File

@@ -1,7 +1,7 @@
test run
set enable_simd
target aarch64
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %bitselect_i32x4(i32x4, i32x4, i32x4) -> i32x4 {
block0(v0: i32x4, v1: i32x4, v2: i32x4):

View File

@@ -2,7 +2,7 @@ test run
target aarch64
; target s390x TODO: Not yet implemented on s390x
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %icmp_eq_i8x16() -> b8 {
block0:

View File

@@ -2,7 +2,7 @@ test run
target aarch64
; target s390x TODO: Not yet implemented on s390x
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %fcvt_from_sint(i32x4) -> f32x4 {
block0(v0: i32x4):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %extractlane_4(i8x16) -> i8 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %iabs_i8x16(i8x16) -> i8x16 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %insertlane_15(i8x16, i8) -> i8x16 {
block0(v0: i8x16, v1: i8):

View File

@@ -2,7 +2,7 @@ test run
target aarch64
; target s390x TODO: Not yet implemented on s390x
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
;; shuffle

View File

@@ -2,7 +2,7 @@ test run
target aarch64
; target s390x TODO: Not yet implemented on s390x
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %bnot() -> b32 {
block0:

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %saddsat_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %shuffle_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %snarrow_i16x8(i16x8, i16x8) -> i8x16 {
block0(v0: i16x8, v1: i16x8):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %splat_i8x16(i8) -> i8x16 {
block0(v0: i8):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %sqmulrs_i16x8(i16x8, i16x8) -> i16x8 {
block0(v0: i16x8, v1: i16x8):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %ssubsat_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %swidenhigh_i8x16(i8x16) -> i16x8 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %swidenlow_i8x16(i8x16) -> i16x8 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %swizzle_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %uaddsat_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %unarrow_i16x8(i16x8, i16x8) -> i8x16 {
block0(v0: i16x8, v1: i16x8):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %usubsat_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %uwidenhigh_i8x16(i8x16) -> i16x8 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %uwidenlow_i8x16(i8x16) -> i16x8 {
block0(v0: i8x16):

View File

@@ -2,7 +2,7 @@ test run
; target s390x TODO: Not yet implemented on s390x
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %vconst_zeroes() -> b1 {

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %vhighbits_i8x16(i8x16) -> i16 {
block0(v0: i8x16):

View File

@@ -3,7 +3,7 @@ test run
; target s390x TODO: Not yet implemented on s390x
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %vselect_i8x16() -> i8x16 {
block0:

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %wpdps(i16x8, i16x8) -> i32x4 {
block0(v0: i16x8, v1: i16x8):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %smulhi_i16(i16, i16) -> i16 {
block0(v0: i16, v1: i16):

View File

@@ -2,7 +2,7 @@ test interpret
test run
target aarch64
set enable_simd
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
target s390x
function %umulhi_i16(i16, i16) -> i16 {

View File

@@ -1,7 +1,7 @@
test verifier
set enable_simd=true
target aarch64
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %scalar_to_vector() {
block0:

View File

@@ -1,7 +1,7 @@
test verifier
set enable_simd
target aarch64
target x86_64
target x86_64 has_sse3 has_ssse3 has_sse41
function %insertlane_i32x4() {
block0:

View File

@@ -1,4 +1,5 @@
//! Provides functionality for compiling and running CLIF IR for `run` tests.
use anyhow::Result;
use core::mem;
use cranelift_codegen::data_value::DataValue;
use cranelift_codegen::ir::{condcodes::IntCC, Function, InstBuilder, Signature};
@@ -27,7 +28,7 @@ use thiserror::Error;
///
/// let code = "test run \n function %add(i32, i32) -> i32 { block0(v0:i32, v1:i32): v2 = iadd v0, v1 return v2 }".into();
/// let func = parse_functions(code).unwrap().into_iter().nth(0).unwrap();
/// let mut compiler = SingleFunctionCompiler::with_default_host_isa();
/// let mut compiler = SingleFunctionCompiler::with_default_host_isa().unwrap();
/// let compiled_func = compiler.compile(func).unwrap();
/// println!("Address of compiled function: {:p}", compiled_func.as_ptr());
/// ```
@@ -46,16 +47,16 @@ impl SingleFunctionCompiler {
}
/// Build a [SingleFunctionCompiler] using the host machine's ISA and the passed flags.
pub fn with_host_isa(flags: settings::Flags) -> Self {
pub fn with_host_isa(flags: settings::Flags) -> Result<Self> {
let builder =
builder_with_options(true).expect("Unable to build a TargetIsa for the current host");
let isa = builder.finish(flags);
Self::new(isa)
let isa = builder.finish(flags)?;
Ok(Self::new(isa))
}
/// Build a [SingleFunctionCompiler] using the host machine's ISA and the default flags for this
/// ISA.
pub fn with_default_host_isa() -> Self {
pub fn with_default_host_isa() -> Result<Self> {
let flags = settings::Flags::new(settings::builder());
Self::with_host_isa(flags)
}
@@ -135,7 +136,7 @@ impl Trampoline {
///
/// let code = "test run \n function %add(i32, i32) -> i32 { block0(v0:i32, v1:i32): v2 = iadd v0, v1 return v2 }".into();
/// let func = parse_functions(code).unwrap().into_iter().nth(0).unwrap();
/// let mut compiler = SingleFunctionCompiler::with_default_host_isa();
/// let mut compiler = SingleFunctionCompiler::with_default_host_isa().unwrap();
/// let compiled_func = compiler.compile(func).unwrap();
///
/// let returned = compiled_func.call(&vec![DataValue::I32(2), DataValue::I32(40)]);
@@ -377,7 +378,7 @@ mod test {
let function = test_file.functions[0].0.clone();
// execute function
let mut compiler = SingleFunctionCompiler::with_default_host_isa();
let mut compiler = SingleFunctionCompiler::with_default_host_isa().unwrap();
let compiled_function = compiler.compile(function).unwrap();
let returned = compiled_function.call(&[]);
assert_eq!(returned, vec![DataValue::B(true)])
@@ -395,7 +396,7 @@ mod test {
}",
);
let compiler = SingleFunctionCompiler::with_default_host_isa();
let compiler = SingleFunctionCompiler::with_default_host_isa().unwrap();
let trampoline = make_trampoline(&function.signature, compiler.isa.as_ref());
assert!(format!("{}", trampoline).ends_with(
"sig0 = (f32, i8, i64x2, b1) -> f32x4, b64 fast

View File

@@ -51,7 +51,7 @@ impl SubTest for TestRun {
let test_env = RuntestEnvironment::parse(&context.details.comments[..])?;
let mut compiler = SingleFunctionCompiler::with_host_isa(context.flags.clone());
let mut compiler = SingleFunctionCompiler::with_host_isa(context.flags.clone())?;
for comment in context.details.comments.iter() {
if let Some(command) = parse_run_command(comment.text, &func.signature)? {
trace!("Parsed run command: {}", command);

View File

@@ -1355,7 +1355,8 @@ block0:
let target = isa::lookup(triple)
.ok()
.map(|b| b.finish(shared_flags))
.expect("This test requires x86_64 support.");
.expect("This test requires x86_64 support.")
.expect("Should be able to create backend with default flags");
let mut sig = Signature::new(target.default_call_conv());
sig.returns.push(AbiParam::new(I32));
@@ -1567,7 +1568,8 @@ block0:
let target = isa::lookup(triple)
.ok()
.map(|b| b.finish(shared_flags))
.expect("This test requires x86_64 support.");
.expect("This test requires x86_64 support.")
.expect("Should be able to create backend with default flags");
let mut sig = Signature::new(target.default_call_conv());
sig.returns.push(AbiParam::new(B1));

View File

@@ -12,7 +12,9 @@ fn main() {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
let mut ctx = module.make_context();

View File

@@ -42,7 +42,9 @@ impl JITBuilder {
/// enum to symbols. LibCalls are inserted in the IR as part of the legalization for certain
/// floating point instructions, and for stack probes. If you don't know what to use for this
/// argument, use `cranelift_module::default_libcall_names()`.
pub fn new(libcall_names: Box<dyn Fn(ir::LibCall) -> String + Send + Sync>) -> Self {
pub fn new(
libcall_names: Box<dyn Fn(ir::LibCall) -> String + Send + Sync>,
) -> ModuleResult<Self> {
let mut flag_builder = settings::builder();
// On at least AArch64, "colocated" calls use shorter-range relocations,
// which might not reach all definitions; we can't handle that here, so
@@ -52,8 +54,8 @@ impl JITBuilder {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
Self::with_isa(isa, libcall_names)
let isa = isa_builder.finish(settings::Flags::new(flag_builder))?;
Ok(Self::with_isa(isa, libcall_names))
}
/// Create a new `JITBuilder` with an arbitrary target. This is mainly

View File

@@ -16,7 +16,9 @@ fn error_on_incompatible_sig_in_declare_function() {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
let mut sig = Signature {
@@ -70,7 +72,9 @@ fn panic_on_define_after_finalize() {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
define_simple_function(&mut module);
@@ -159,7 +163,9 @@ fn libcall_function() {
let isa_builder = cranelift_native::builder().unwrap_or_else(|msg| {
panic!("host machine is not supported: {}", msg);
});
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
let sig = Signature {

View File

@@ -156,7 +156,9 @@ mod tests {
fn test() {
if let Ok(isa_builder) = builder() {
let flag_builder = settings::builder();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
if cfg!(all(target_os = "macos", target_arch = "aarch64")) {
assert_eq!(isa.default_call_conv(), CallConv::AppleAarch64);

View File

@@ -11,7 +11,9 @@ use cranelift_object::*;
fn error_on_incompatible_sig_in_declare_function() {
let flag_builder = settings::builder();
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module =
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
let mut sig = Signature {
@@ -60,7 +62,9 @@ fn define_simple_function(module: &mut ObjectModule) -> FuncId {
fn panic_on_define_after_finalize() {
let flag_builder = settings::builder();
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module =
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
@@ -145,7 +149,9 @@ fn switch_error() {
fn libcall_function() {
let flag_builder = settings::builder();
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module =
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
@@ -199,7 +205,9 @@ fn libcall_function() {
fn reject_nul_byte_symbol_for_func() {
let flag_builder = settings::builder();
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module =
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());
@@ -221,7 +229,9 @@ fn reject_nul_byte_symbol_for_func() {
fn reject_nul_byte_symbol_for_data() {
let flag_builder = settings::builder();
let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();
let isa = isa_builder.finish(settings::Flags::new(flag_builder));
let isa = isa_builder
.finish(settings::Flags::new(flag_builder))
.unwrap();
let mut module =
ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());

View File

@@ -1053,7 +1053,15 @@ impl<'a> Parser<'a> {
specified_target = true;
// Construct a trait object with the aggregate settings.
targets.push(isa_builder.finish(settings::Flags::new(flag_builder.clone())));
targets.push(
isa_builder
.finish(settings::Flags::new(flag_builder.clone()))
.map_err(|e| ParseError {
location: loc,
message: format!("invalid ISA flags for '{}': {:?}", targ, e),
is_warning: false,
})?,
);
}
if !specified_target {
@@ -1122,7 +1130,18 @@ impl<'a> Parser<'a> {
isaspec::parse_options(words, &mut isa_builder, self.loc)?;
// Construct a trait object with the aggregate settings.
targets.push(isa_builder.finish(settings::Flags::new(flag_builder.clone())));
targets.push(
isa_builder
.finish(settings::Flags::new(flag_builder.clone()))
.map_err(|e| ParseError {
location: loc,
message: format!(
"invalid ISA flags for '{}': {:?}",
target_name, e
),
is_warning: false,
})?,
);
}
_ => break,
}

View File

@@ -110,7 +110,7 @@ fn create_target_isa(isa_spec: &IsaSpec) -> Result<Box<dyn TargetIsa>> {
if let IsaSpec::None(flags) = isa_spec {
// build an ISA for the current machine
let builder = host_isa_builder().map_err(|s| anyhow::anyhow!("{}", s))?;
Ok(builder.finish(flags.clone()))
Ok(builder.finish(flags.clone())?)
} else {
anyhow::bail!(
"A target ISA was specified in the file but should not have been--only \

View File

@@ -99,7 +99,7 @@ pub fn parse_sets_and_triple(
.map_err(ParseError::from)?;
Ok(OwnedFlagsOrIsa::Isa(
isa_builder.finish(settings::Flags::new(flag_builder)),
isa_builder.finish(settings::Flags::new(flag_builder))?,
))
} else {
if !unknown_settings.is_empty() {

View File

@@ -101,12 +101,15 @@ impl CompilerBuilder for Builder {
Ok(())
}
fn build(&self) -> Box<dyn wasmtime_environ::Compiler> {
fn build(&self) -> Result<Box<dyn wasmtime_environ::Compiler>> {
let isa = self
.isa_flags
.clone()
.finish(settings::Flags::new(self.flags.clone()));
Box::new(crate::compiler::Compiler::new(isa, self.linkopts.clone()))
.finish(settings::Flags::new(self.flags.clone()))?;
Ok(Box::new(crate::compiler::Compiler::new(
isa,
self.linkopts.clone(),
)))
}
fn settings(&self) -> Vec<Setting> {

View File

@@ -104,7 +104,7 @@ pub trait CompilerBuilder: Send + Sync + fmt::Debug {
fn settings(&self) -> Vec<Setting>;
/// Builds a new [`Compiler`] object from this configuration.
fn build(&self) -> Box<dyn Compiler>;
fn build(&self) -> Result<Box<dyn Compiler>>;
}
/// Description of compiler settings returned by [`CompilerBuilder::settings`].

View File

@@ -64,7 +64,7 @@ impl Engine {
Ok(Engine {
inner: Arc::new(EngineInner {
#[cfg(compiler)]
compiler: config.compiler.build(),
compiler: config.compiler.build()?,
config,
allocator,
signatures: registry,

View File

@@ -60,7 +60,7 @@ fuzz_target!(|testcase: TestCase| {
};
// Native fn
let mut host_compiler = SingleFunctionCompiler::with_default_host_isa();
let mut host_compiler = SingleFunctionCompiler::with_default_host_isa().unwrap();
let compiled_fn = host_compiler.compile(testcase.func.clone()).unwrap();
for args in &testcase.inputs {

View File

@@ -62,7 +62,7 @@ impl SettingsCommand {
}
if self.target.is_none() {
let compiler = builder.build();
let compiler = builder.build()?;
println!();
println!("Settings inferred for the current host:");