Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
2161: feat(llvm): Make NaN canonicalization configurable r=jubianchi a=jubianchi

compiler-llvm now uses the experimental.constrained intrinsics to ensure
correct behavior on FP operations when full-canonicalization is
disabled.
    
This patch requires TheDan64/inkwell#247

# Review

- [ ] Add a short description of the the change to the CHANGELOG.md file


Co-authored-by: jubianchi <[email protected]>
  • Loading branch information
bors[bot] and jubianchi authored May 31, 2021
2 parents 99f42b0 + ec1430c commit c0d3a8f
Show file tree
Hide file tree
Showing 15 changed files with 1,888 additions and 976 deletions.
32 changes: 16 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/c-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder {
.exclude_item("wasi_get_unordered_imports")
.exclude_item("wasi_get_wasi_version")
.exclude_item("wasi_version_t")
.exclude_item("wasm_config_canonicalize_nans")
.exclude_item("wasm_config_push_middleware")
.exclude_item("wasm_config_set_compiler")
.exclude_item("wasm_config_set_engine")
Expand Down
5 changes: 5 additions & 0 deletions lib/c-api/src/wasm_c_api/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ pub struct wasm_config_t {
compiler: wasmer_compiler_t,
#[cfg(feature = "middlewares")]
pub(super) middlewares: Vec<wasmer_middleware_t>,
pub(super) nan_canonicalization: bool,
pub(super) features: Option<Box<wasmer_features_t>>,
pub(super) target: Option<Box<wasmer_target_t>>,
}
Expand Down Expand Up @@ -482,6 +483,10 @@ pub extern "C" fn wasm_engine_new_with_config(
compiler_config.push_middleware(middleware.inner);
}

if config.nan_canonicalization {
compiler_config.canonicalize_nans(true);
}

let inner: Arc<dyn Engine + Send + Sync> = match config.engine {
wasmer_engine_t::UNIVERSAL => {
cfg_if! {
Expand Down
39 changes: 39 additions & 0 deletions lib/c-api/src/wasm_c_api/unstable/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,45 @@ pub extern "C" fn wasm_config_set_features(
config.features = Some(features);
}

/// Updates the configuration to enable NaN canonicalization.
///
/// This is a Wasmer-specific function.
///
/// # Example
///
/// ```rust
/// # use inline_c::assert_c;
/// # fn main() {
/// # (assert_c! {
/// # #include "tests/wasmer_wasm.h"
/// #
/// int main() {
/// // Create the configuration.
/// wasm_config_t* config = wasm_config_new();
///
/// // Enable NaN canonicalization.
/// wasm_config_canonicalize_nans(config, true);
///
/// // Create the engine.
/// wasm_engine_t* engine = wasm_engine_new_with_config(config);
///
/// // Check we have an engine!
/// assert(engine);
///
/// // Free everything.
/// wasm_engine_delete(engine);
///
/// return 0;
/// }
/// # })
/// # .success();
/// # }
/// ```
#[no_mangle]
pub extern "C" fn wasm_config_canonicalize_nans(config: &mut wasm_config_t, enable: bool) {
config.nan_canonicalization = enable;
}

/// Check whether the given compiler is available, i.e. part of this
/// compiled library.
#[no_mangle]
Expand Down
2 changes: 2 additions & 0 deletions lib/c-api/wasmer_wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,8 @@ bool wasi_get_unordered_imports(const wasm_store_t *store,
enum wasi_version_t wasi_get_wasi_version(const wasm_module_t *module);
#endif

void wasm_config_canonicalize_nans(wasm_config_t *config, bool enable);

void wasm_config_push_middleware(wasm_config_t *config, struct wasmer_middleware_t *middleware);

#if defined(WASMER_COMPILER_ENABLED)
Expand Down
8 changes: 8 additions & 0 deletions lib/compiler-cranelift/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ impl CompilerConfig for Cranelift {
self.enable_verifier = true;
}

fn enable_nan_canonicalization(&mut self) {
self.enable_nan_canonicalization = true;
}

fn canonicalize_nans(&mut self, enable: bool) {
self.enable_nan_canonicalization = enable;
}

/// Transform it into the compiler
fn compiler(self: Box<Self>) -> Box<dyn Compiler> {
Box::new(CraneliftCompiler::new(*self))
Expand Down
3 changes: 2 additions & 1 deletion lib/compiler-llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ rayon = "1.5"
loupe = "0.1"

[dependencies.inkwell]
version = "=0.1.0-beta.2"
package = "wasmer_inkwell"
version = "0.2.0-alpha.2"
default-features = false
features = ["llvm11-0", "target-x86", "target-aarch64"]

Expand Down
88 changes: 64 additions & 24 deletions lib/compiler-llvm/src/abi/aarch64_systemv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use inkwell::{
attributes::{Attribute, AttributeLoc},
builder::Builder,
context::Context,
types::{BasicType, FunctionType, StructType},
types::{BasicMetadataTypeEnum, BasicType, FunctionType, StructType},
values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, IntValue, PointerValue},
AddressSpace,
};
Expand Down Expand Up @@ -83,34 +83,51 @@ impl Abi for Aarch64SystemV {

Ok(match sig.results() {
[] => (
intrinsics
.void_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
intrinsics.void_ty.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
),
[_] => {
let single_value = sig.results()[0];
(
type_to_llvm(intrinsics, single_value)?
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
type_to_llvm(intrinsics, single_value)?.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
)
}
[Type::F32, Type::F32] => {
let f32_ty = intrinsics.f32_ty.as_basic_type_enum();
(
context
.struct_type(&[f32_ty, f32_ty], false)
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
context.struct_type(&[f32_ty, f32_ty], false).fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
)
}
[Type::F64, Type::F64] => {
let f64_ty = intrinsics.f64_ty.as_basic_type_enum();
(
context
.struct_type(&[f64_ty, f64_ty], false)
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
context.struct_type(&[f64_ty, f64_ty], false).fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
)
}
Expand All @@ -119,7 +136,13 @@ impl Abi for Aarch64SystemV {
(
context
.struct_type(&[f32_ty, f32_ty, f32_ty], false)
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
)
}
Expand All @@ -128,7 +151,13 @@ impl Abi for Aarch64SystemV {
(
context
.struct_type(&[f32_ty, f32_ty, f32_ty, f32_ty], false)
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
)
}
Expand All @@ -145,9 +174,13 @@ impl Abi for Aarch64SystemV {
.collect::<Vec<i32>>();
match sig_returns_bitwidths.as_slice() {
[32, 32] => (
intrinsics
.i64_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
intrinsics.i64_ty.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
),
[32, 64]
Expand All @@ -157,10 +190,13 @@ impl Abi for Aarch64SystemV {
| [64, 32, 32]
| [32, 32, 64]
| [32, 32, 32, 32] => (
intrinsics
.i64_ty
.array_type(2)
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
intrinsics.i64_ty.array_type(2).fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
vmctx_attributes(0),
),
_ => {
Expand All @@ -187,9 +223,13 @@ impl Abi for Aarch64SystemV {
attributes.append(&mut vmctx_attributes(1));

(
intrinsics
.void_ty
.fn_type(&param_types.collect::<Result<Vec<_>, _>>()?, false),
intrinsics.void_ty.fn_type(
param_types
.map(|v| v.map(Into::into))
.collect::<Result<Vec<BasicMetadataTypeEnum>, _>>()?
.as_slice(),
false,
),
attributes,
)
}
Expand Down
Loading

0 comments on commit c0d3a8f

Please sign in to comment.