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:
@@ -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",
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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(_)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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`].
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user