Merge branch 'master' into deterministic

This commit is contained in:
Yaron Wittenstein 2019-10-10 15:55:35 +03:00 committed by GitHub
commit 420bfa570e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 399 additions and 633 deletions

View File

@ -6,6 +6,8 @@ Blocks of changes will separated by version increments.
## **[Unreleased]**
- [#863](https://github.com/wasmerio/wasmer/pull/863) Fix min and max for cases involving NaN and negative zero when using the LLVM backend.
## 0.8.0 - 2019-10-02
Special thanks to @jdanford for their contributions!

View File

@ -935,7 +935,8 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
let signal_mem = ctx.signal_mem();
let iv = builder
.build_store(signal_mem, context.i8_type().const_int(0 as u64, false));
iv.set_volatile(true);
// Any 'store' can be made volatile.
iv.set_volatile(true).unwrap();
finalize_opcode_stack_map(
intrinsics,
builder,
@ -2420,14 +2421,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
}
Operator::I32Clz => {
let input = state.pop1()?;
let ensure_defined_zero = intrinsics
.i1_ty
.const_int(1 as u64, false)
.as_basic_value_enum();
let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.ctlz_i32,
&[input, ensure_defined_zero],
&[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
@ -2437,14 +2435,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
}
Operator::I64Clz => {
let input = state.pop1()?;
let ensure_defined_zero = intrinsics
.i1_ty
.const_int(1 as u64, false)
.as_basic_value_enum();
let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.ctlz_i64,
&[input, ensure_defined_zero],
&[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
@ -2454,14 +2449,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
}
Operator::I32Ctz => {
let input = state.pop1()?;
let ensure_defined_zero = intrinsics
.i1_ty
.const_int(1 as u64, false)
.as_basic_value_enum();
let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.cttz_i32,
&[input, ensure_defined_zero],
&[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
@ -2471,14 +2463,11 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
}
Operator::I64Ctz => {
let input = state.pop1()?;
let ensure_defined_zero = intrinsics
.i1_ty
.const_int(1 as u64, false)
.as_basic_value_enum();
let is_zero_undef = intrinsics.i1_zero.as_basic_value_enum();
let res = builder
.build_call(
intrinsics.cttz_i64,
&[input, ensure_defined_zero],
&[input, is_zero_undef],
&state.var_name(),
)
.try_as_basic_value()
@ -2692,86 +2681,404 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
state.push1(bits);
}
Operator::F32Min => {
// This implements the same logic as LLVM's @llvm.minimum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let res = builder
.build_call(intrinsics.minimum_f32, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f32_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f32_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i32_ty, "")
.into_int_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i32_ty, "")
.into_int_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let negative_zero = intrinsics.f32_ty.const_float(-0.0);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
negative_zero,
v2,
"",
)
.into_float_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
state.push1(res);
}
Operator::F64Min => {
// This implements the same logic as LLVM's @llvm.minimum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let res = builder
.build_call(intrinsics.minimum_f64, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f64_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f64_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i64_ty, "")
.into_int_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i64_ty, "")
.into_int_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let negative_zero = intrinsics.f64_ty.const_float(-0.0);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
negative_zero,
v2,
"",
)
.into_float_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
state.push1(res);
}
Operator::F32x4Min => {
// This implements the same logic as LLVM's @llvm.minimum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
let res = builder
.build_call(intrinsics.minimum_f32x4, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f32x4_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f32x4_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i32x4_ty, "")
.into_vector_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i32x4_ty, "")
.into_vector_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let negative_zero = splat_vector(
builder,
intrinsics,
intrinsics.f32_ty.const_float(-0.0).as_basic_value_enum(),
intrinsics.f32x4_ty,
"",
);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
negative_zero,
v2,
"",
)
.into_vector_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Min => {
// This implements the same logic as LLVM's @llvm.minimum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
let res = builder
.build_call(intrinsics.minimum_f64x2, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f64x2_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f64x2_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i64x2_ty, "")
.into_vector_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i64x2_ty, "")
.into_vector_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OLT, v1, v2, "");
let negative_zero = splat_vector(
builder,
intrinsics,
intrinsics.f64_ty.const_float(-0.0).as_basic_value_enum(),
intrinsics.f64x2_ty,
"",
);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
negative_zero,
v2,
"",
)
.into_vector_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F32Max => {
// This implements the same logic as LLVM's @llvm.maximum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let res = builder
.build_call(intrinsics.maximum_f32, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f32_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f32_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i32_ty, "")
.into_int_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i32_ty, "")
.into_int_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
intrinsics.f32_zero,
v2,
"",
)
.into_float_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
state.push1(res);
}
Operator::F64Max => {
// This implements the same logic as LLVM's @llvm.maximum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let res = builder
.build_call(intrinsics.maximum_f64, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f64_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f64_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i64_ty, "")
.into_int_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i64_ty, "")
.into_int_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
intrinsics.f64_zero,
v2,
"",
)
.into_float_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
state.push1(res);
}
Operator::F32x4Max => {
// This implements the same logic as LLVM's @llvm.maximum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
let res = builder
.build_call(intrinsics.maximum_f32x4, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f32x4_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f32x4_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i32x4_ty, "")
.into_vector_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i32x4_ty, "")
.into_vector_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let zero = splat_vector(
builder,
intrinsics,
intrinsics.f32_zero.as_basic_value_enum(),
intrinsics.f32x4_ty,
"",
);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
zero,
v2,
"",
)
.into_vector_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}
Operator::F64x2Max => {
// This implements the same logic as LLVM's @llvm.maximum
// intrinsic would, but x86 lowering of that intrinsics
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
let res = builder
.build_call(intrinsics.maximum_f64x2, &[v1, v2], &state.var_name())
.try_as_basic_value()
.left()
.unwrap();
let v1 = canonicalize_nans(builder, intrinsics, v1);
let v2 = canonicalize_nans(builder, intrinsics, v2);
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
let v1_is_nan = builder.build_float_compare(
FloatPredicate::UNO,
v1,
intrinsics.f64x2_zero,
"nan",
);
let v2_is_not_nan = builder.build_float_compare(
FloatPredicate::ORD,
v2,
intrinsics.f64x2_zero,
"notnan",
);
let v1_repr = builder
.build_bitcast(v1, intrinsics.i64x2_ty, "")
.into_vector_value();
let v2_repr = builder
.build_bitcast(v2, intrinsics.i64x2_ty, "")
.into_vector_value();
let repr_ne = builder.build_int_compare(IntPredicate::NE, v1_repr, v2_repr, "");
let float_eq = builder.build_float_compare(FloatPredicate::OEQ, v1, v2, "");
let min_cmp = builder.build_float_compare(FloatPredicate::OGT, v1, v2, "");
let zero = splat_vector(
builder,
intrinsics,
intrinsics.f64_zero.as_basic_value_enum(),
intrinsics.f64x2_ty,
"",
);
let v2 = builder
.build_select(
builder.build_and(
builder.build_and(float_eq, repr_ne, ""),
v2_is_not_nan,
"",
),
zero,
v2,
"",
)
.into_vector_value();
let res =
builder.build_select(builder.build_or(v1_is_nan, min_cmp, ""), v1, v2, "");
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
state.push1(res);
}

View File

@ -6,7 +6,9 @@ use inkwell::{
types::{
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
},
values::{BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue},
values::{
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue, VectorValue,
},
AddressSpace,
};
use std::collections::HashMap;
@ -125,6 +127,8 @@ pub struct Intrinsics {
pub i128_zero: IntValue,
pub f32_zero: FloatValue,
pub f64_zero: FloatValue,
pub f32x4_zero: VectorValue,
pub f64x2_zero: VectorValue,
pub trap_unreachable: BasicValueEnum,
pub trap_call_indirect_sig: BasicValueEnum,
@ -191,6 +195,8 @@ impl Intrinsics {
let i128_zero = i128_ty.const_int(0, false);
let f32_zero = f32_ty.const_float(0.0);
let f64_zero = f64_ty.const_float(0.0);
let f32x4_zero = f32x4_ty.const_zero();
let f64x2_zero = f64x2_ty.const_zero();
let i1_ty_basic = i1_ty.as_basic_type_enum();
let i32_ty_basic = i32_ty.as_basic_type_enum();
@ -455,6 +461,8 @@ impl Intrinsics {
i128_zero,
f32_zero,
f64_zero,
f32x4_zero,
f64x2_zero,
trap_unreachable: i32_zero.as_basic_value_enum(),
trap_call_indirect_sig: i32_ty.const_int(1, false).as_basic_value_enum(),

View File

@ -148,7 +148,7 @@ impl LocalBacking {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
message: "a const initializer must be an i32".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => {
@ -209,7 +209,7 @@ impl LocalBacking {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
message: "a const initializer must be an i32".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => {
@ -282,7 +282,7 @@ impl LocalBacking {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
message: "a const initializer must be an i32".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => {
@ -340,7 +340,7 @@ impl LocalBacking {
Initializer::Const(Value::I32(offset)) => offset as u32,
Initializer::Const(_) => {
return Err(vec![LinkError::Generic {
message: "a const initializer must be the i32 type".to_string(),
message: "a const initializer be an i32".to_string(),
}]);
}
Initializer::GetGlobal(import_global_index) => {

View File

@ -24,7 +24,6 @@ clif:skip:simd_binaryen.wast:* # SIMD not implemented
# linking.wast:387,388 appear to be related to WABT issue: https://github.com/pepyakin/wabt-rs/issues/51
clif:fail:globals.wast:243 # AssertInvalid - Should be invalid
clif:fail:linking.wast:137 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883062 - illegal instruction"
clif:fail:linking.wast:139 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883062 - illegal instruction"
clif:fail:linking.wast:142 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883062 - illegal instruction"
@ -265,577 +264,13 @@ clif:fail:data.wast:266:windows # AssertUnlinkable - caught panic Any
clif:fail:data.wast:186:windows # AssertUnlinkable - caught panic Any
clif:fail:data.wast:194:windows # AssertUnlinkable - caught panic Any
# LLVM bug with min/max over NaNs
llvm:skip:f32.wast:1651
llvm:skip:f32.wast:1652
llvm:skip:f32.wast:1653
llvm:skip:f32.wast:1654
llvm:skip:f32.wast:1655
llvm:skip:f32.wast:1656
llvm:skip:f32.wast:1657
llvm:skip:f32.wast:1658
llvm:skip:f32.wast:1691
llvm:skip:f32.wast:1692
llvm:skip:f32.wast:1693
llvm:skip:f32.wast:1694
llvm:skip:f32.wast:1695
llvm:skip:f32.wast:1696
llvm:skip:f32.wast:1697
llvm:skip:f32.wast:1698
llvm:skip:f32.wast:1731
llvm:skip:f32.wast:1732
llvm:skip:f32.wast:1733
llvm:skip:f32.wast:1734
llvm:skip:f32.wast:1735
llvm:skip:f32.wast:1736
llvm:skip:f32.wast:1737
llvm:skip:f32.wast:1738
llvm:skip:f32.wast:1771
llvm:skip:f32.wast:1772
llvm:skip:f32.wast:1773
llvm:skip:f32.wast:1774
llvm:skip:f32.wast:1775
llvm:skip:f32.wast:1776
llvm:skip:f32.wast:1777
llvm:skip:f32.wast:1778
llvm:skip:f32.wast:1811
llvm:skip:f32.wast:1812
llvm:skip:f32.wast:1813
llvm:skip:f32.wast:1814
llvm:skip:f32.wast:1815
llvm:skip:f32.wast:1816
llvm:skip:f32.wast:1817
llvm:skip:f32.wast:1818
llvm:skip:f32.wast:1851
llvm:skip:f32.wast:1852
llvm:skip:f32.wast:1853
llvm:skip:f32.wast:1854
llvm:skip:f32.wast:1855
llvm:skip:f32.wast:1856
llvm:skip:f32.wast:1857
llvm:skip:f32.wast:1858
llvm:skip:f32.wast:1891
llvm:skip:f32.wast:1892
llvm:skip:f32.wast:1893
llvm:skip:f32.wast:1894
llvm:skip:f32.wast:1895
llvm:skip:f32.wast:1896
llvm:skip:f32.wast:1897
llvm:skip:f32.wast:1898
llvm:skip:f32.wast:1931
llvm:skip:f32.wast:1932
llvm:skip:f32.wast:1933
llvm:skip:f32.wast:1934
llvm:skip:f32.wast:1935
llvm:skip:f32.wast:1936
llvm:skip:f32.wast:1937
llvm:skip:f32.wast:1938
llvm:skip:f32.wast:1939
llvm:skip:f32.wast:1940
llvm:skip:f32.wast:1941
llvm:skip:f32.wast:1942
llvm:skip:f32.wast:1943
llvm:skip:f32.wast:1944
llvm:skip:f32.wast:1945
llvm:skip:f32.wast:1946
llvm:skip:f32.wast:1947
llvm:skip:f32.wast:1948
llvm:skip:f32.wast:1949
llvm:skip:f32.wast:1950
llvm:skip:f32.wast:1951
llvm:skip:f32.wast:1952
llvm:skip:f32.wast:1953
llvm:skip:f32.wast:1954
llvm:skip:f32.wast:1955
llvm:skip:f32.wast:1956
llvm:skip:f32.wast:1957
llvm:skip:f32.wast:1958
llvm:skip:f32.wast:1959
llvm:skip:f32.wast:1960
llvm:skip:f32.wast:1961
llvm:skip:f32.wast:1962
llvm:skip:f32.wast:1963
llvm:skip:f32.wast:1964
llvm:skip:f32.wast:1965
llvm:skip:f32.wast:1966
llvm:skip:f32.wast:1967
llvm:skip:f32.wast:1968
llvm:skip:f32.wast:1969
llvm:skip:f32.wast:1970
llvm:skip:f32.wast:1971
llvm:skip:f32.wast:1972
llvm:skip:f32.wast:1973
llvm:skip:f32.wast:1974
llvm:skip:f32.wast:1975
llvm:skip:f32.wast:1976
llvm:skip:f32.wast:1977
llvm:skip:f32.wast:1978
llvm:skip:f32.wast:1979
llvm:skip:f32.wast:1980
llvm:skip:f32.wast:1981
llvm:skip:f32.wast:1982
llvm:skip:f32.wast:1983
llvm:skip:f32.wast:1984
llvm:skip:f32.wast:1985
llvm:skip:f32.wast:1986
llvm:skip:f32.wast:1987
llvm:skip:f32.wast:1988
llvm:skip:f32.wast:1989
llvm:skip:f32.wast:1990
llvm:skip:f32.wast:1991
llvm:skip:f32.wast:1992
llvm:skip:f32.wast:1993
llvm:skip:f32.wast:1994
llvm:skip:f32.wast:1995
llvm:skip:f32.wast:1996
llvm:skip:f32.wast:1997
llvm:skip:f32.wast:1998
llvm:skip:f32.wast:1999
llvm:skip:f32.wast:2000
llvm:skip:f32.wast:2001
llvm:skip:f32.wast:2002
llvm:skip:f32.wast:2005
llvm:skip:f32.wast:2006
llvm:skip:f32.wast:2009
llvm:skip:f32.wast:2010
llvm:skip:f32.wast:2013
llvm:skip:f32.wast:2014
llvm:skip:f32.wast:2017
llvm:skip:f32.wast:2018
llvm:skip:f32.wast:2051
llvm:skip:f32.wast:2052
llvm:skip:f32.wast:2053
llvm:skip:f32.wast:2054
llvm:skip:f32.wast:2055
llvm:skip:f32.wast:2056
llvm:skip:f32.wast:2057
llvm:skip:f32.wast:2058
llvm:skip:f32.wast:2091
llvm:skip:f32.wast:2092
llvm:skip:f32.wast:2093
llvm:skip:f32.wast:2094
llvm:skip:f32.wast:2095
llvm:skip:f32.wast:2096
llvm:skip:f32.wast:2097
llvm:skip:f32.wast:2098
llvm:skip:f32.wast:2131
llvm:skip:f32.wast:2132
llvm:skip:f32.wast:2133
llvm:skip:f32.wast:2134
llvm:skip:f32.wast:2135
llvm:skip:f32.wast:2136
llvm:skip:f32.wast:2137
llvm:skip:f32.wast:2138
llvm:skip:f32.wast:2171
llvm:skip:f32.wast:2172
llvm:skip:f32.wast:2173
llvm:skip:f32.wast:2174
llvm:skip:f32.wast:2175
llvm:skip:f32.wast:2176
llvm:skip:f32.wast:2177
llvm:skip:f32.wast:2178
llvm:skip:f32.wast:2211
llvm:skip:f32.wast:2212
llvm:skip:f32.wast:2213
llvm:skip:f32.wast:2214
llvm:skip:f32.wast:2215
llvm:skip:f32.wast:2216
llvm:skip:f32.wast:2217
llvm:skip:f32.wast:2218
llvm:skip:f32.wast:2251
llvm:skip:f32.wast:2252
llvm:skip:f32.wast:2253
llvm:skip:f32.wast:2254
llvm:skip:f32.wast:2255
llvm:skip:f32.wast:2256
llvm:skip:f32.wast:2257
llvm:skip:f32.wast:2258
llvm:skip:f32.wast:2291
llvm:skip:f32.wast:2292
llvm:skip:f32.wast:2293
llvm:skip:f32.wast:2294
llvm:skip:f32.wast:2295
llvm:skip:f32.wast:2296
llvm:skip:f32.wast:2297
llvm:skip:f32.wast:2298
llvm:skip:f32.wast:2331
llvm:skip:f32.wast:2332
llvm:skip:f32.wast:2333
llvm:skip:f32.wast:2334
llvm:skip:f32.wast:2335
llvm:skip:f32.wast:2336
llvm:skip:f32.wast:2337
llvm:skip:f32.wast:2338
llvm:skip:f32.wast:2339
llvm:skip:f32.wast:2340
llvm:skip:f32.wast:2341
llvm:skip:f32.wast:2342
llvm:skip:f32.wast:2343
llvm:skip:f32.wast:2344
llvm:skip:f32.wast:2345
llvm:skip:f32.wast:2346
llvm:skip:f32.wast:2347
llvm:skip:f32.wast:2348
llvm:skip:f32.wast:2349
llvm:skip:f32.wast:2350
llvm:skip:f32.wast:2351
llvm:skip:f32.wast:2352
llvm:skip:f32.wast:2353
llvm:skip:f32.wast:2354
llvm:skip:f32.wast:2355
llvm:skip:f32.wast:2356
llvm:skip:f32.wast:2357
llvm:skip:f32.wast:2358
llvm:skip:f32.wast:2359
llvm:skip:f32.wast:2360
llvm:skip:f32.wast:2361
llvm:skip:f32.wast:2362
llvm:skip:f32.wast:2363
llvm:skip:f32.wast:2364
llvm:skip:f32.wast:2365
llvm:skip:f32.wast:2366
llvm:skip:f32.wast:2367
llvm:skip:f32.wast:2368
llvm:skip:f32.wast:2369
llvm:skip:f32.wast:2370
llvm:skip:f32.wast:2371
llvm:skip:f32.wast:2372
llvm:skip:f32.wast:2373
llvm:skip:f32.wast:2374
llvm:skip:f32.wast:2375
llvm:skip:f32.wast:2376
llvm:skip:f32.wast:2377
llvm:skip:f32.wast:2378
llvm:skip:f32.wast:2379
llvm:skip:f32.wast:2380
llvm:skip:f32.wast:2381
llvm:skip:f32.wast:2382
llvm:skip:f32.wast:2383
llvm:skip:f32.wast:2384
llvm:skip:f32.wast:2385
llvm:skip:f32.wast:2386
llvm:skip:f32.wast:2387
llvm:skip:f32.wast:2388
llvm:skip:f32.wast:2389
llvm:skip:f32.wast:2390
llvm:skip:f32.wast:2391
llvm:skip:f32.wast:2392
llvm:skip:f32.wast:2393
llvm:skip:f32.wast:2394
llvm:skip:f32.wast:2395
llvm:skip:f32.wast:2396
llvm:skip:f32.wast:2397
llvm:skip:f32.wast:2398
llvm:skip:f32.wast:2399
llvm:skip:f32.wast:2400
llvm:skip:f32.wast:2401
llvm:skip:f32.wast:2402
llvm:skip:f32.wast:2403
llvm:skip:f32.wast:2404
llvm:skip:f32.wast:2405
llvm:skip:f32.wast:2406
llvm:skip:f32.wast:2409
llvm:skip:f32.wast:2410
llvm:skip:f32.wast:2413
llvm:skip:f32.wast:2414
llvm:skip:f32.wast:2417
llvm:skip:f32.wast:2418
llvm:skip:f64.wast:1651
llvm:skip:f64.wast:1652
llvm:skip:f64.wast:1653
llvm:skip:f64.wast:1654
llvm:skip:f64.wast:1655
llvm:skip:f64.wast:1656
llvm:skip:f64.wast:1657
llvm:skip:f64.wast:1658
llvm:skip:f64.wast:1691
llvm:skip:f64.wast:1692
llvm:skip:f64.wast:1693
llvm:skip:f64.wast:1694
llvm:skip:f64.wast:1695
llvm:skip:f64.wast:1696
llvm:skip:f64.wast:1697
llvm:skip:f64.wast:1698
llvm:skip:f64.wast:1731
llvm:skip:f64.wast:1732
llvm:skip:f64.wast:1733
llvm:skip:f64.wast:1734
llvm:skip:f64.wast:1735
llvm:skip:f64.wast:1736
llvm:skip:f64.wast:1737
llvm:skip:f64.wast:1738
llvm:skip:f64.wast:1771
llvm:skip:f64.wast:1772
llvm:skip:f64.wast:1773
llvm:skip:f64.wast:1774
llvm:skip:f64.wast:1775
llvm:skip:f64.wast:1776
llvm:skip:f64.wast:1777
llvm:skip:f64.wast:1778
llvm:skip:f64.wast:1811
llvm:skip:f64.wast:1812
llvm:skip:f64.wast:1813
llvm:skip:f64.wast:1814
llvm:skip:f64.wast:1815
llvm:skip:f64.wast:1816
llvm:skip:f64.wast:1817
llvm:skip:f64.wast:1818
llvm:skip:f64.wast:1851
llvm:skip:f64.wast:1852
llvm:skip:f64.wast:1853
llvm:skip:f64.wast:1854
llvm:skip:f64.wast:1855
llvm:skip:f64.wast:1856
llvm:skip:f64.wast:1857
llvm:skip:f64.wast:1858
llvm:skip:f64.wast:1891
llvm:skip:f64.wast:1892
llvm:skip:f64.wast:1893
llvm:skip:f64.wast:1894
llvm:skip:f64.wast:1895
llvm:skip:f64.wast:1896
llvm:skip:f64.wast:1897
llvm:skip:f64.wast:1898
llvm:skip:f64.wast:1931
llvm:skip:f64.wast:1932
llvm:skip:f64.wast:1933
llvm:skip:f64.wast:1934
llvm:skip:f64.wast:1935
llvm:skip:f64.wast:1936
llvm:skip:f64.wast:1937
llvm:skip:f64.wast:1938
llvm:skip:f64.wast:1939
llvm:skip:f64.wast:1940
llvm:skip:f64.wast:1941
llvm:skip:f64.wast:1942
llvm:skip:f64.wast:1943
llvm:skip:f64.wast:1944
llvm:skip:f64.wast:1945
llvm:skip:f64.wast:1946
llvm:skip:f64.wast:1947
llvm:skip:f64.wast:1948
llvm:skip:f64.wast:1949
llvm:skip:f64.wast:1950
llvm:skip:f64.wast:1951
llvm:skip:f64.wast:1952
llvm:skip:f64.wast:1953
llvm:skip:f64.wast:1954
llvm:skip:f64.wast:1955
llvm:skip:f64.wast:1956
llvm:skip:f64.wast:1957
llvm:skip:f64.wast:1958
llvm:skip:f64.wast:1959
llvm:skip:f64.wast:1960
llvm:skip:f64.wast:1961
llvm:skip:f64.wast:1962
llvm:skip:f64.wast:1963
llvm:skip:f64.wast:1964
llvm:skip:f64.wast:1965
llvm:skip:f64.wast:1966
llvm:skip:f64.wast:1967
llvm:skip:f64.wast:1968
llvm:skip:f64.wast:1969
llvm:skip:f64.wast:1970
llvm:skip:f64.wast:1971
llvm:skip:f64.wast:1972
llvm:skip:f64.wast:1973
llvm:skip:f64.wast:1974
llvm:skip:f64.wast:1975
llvm:skip:f64.wast:1976
llvm:skip:f64.wast:1977
llvm:skip:f64.wast:1978
llvm:skip:f64.wast:1979
llvm:skip:f64.wast:1980
llvm:skip:f64.wast:1981
llvm:skip:f64.wast:1982
llvm:skip:f64.wast:1983
llvm:skip:f64.wast:1984
llvm:skip:f64.wast:1985
llvm:skip:f64.wast:1986
llvm:skip:f64.wast:1987
llvm:skip:f64.wast:1988
llvm:skip:f64.wast:1989
llvm:skip:f64.wast:1990
llvm:skip:f64.wast:1991
llvm:skip:f64.wast:1992
llvm:skip:f64.wast:1993
llvm:skip:f64.wast:1994
llvm:skip:f64.wast:1995
llvm:skip:f64.wast:1996
llvm:skip:f64.wast:1997
llvm:skip:f64.wast:1998
llvm:skip:f64.wast:1999
llvm:skip:f64.wast:2000
llvm:skip:f64.wast:2001
llvm:skip:f64.wast:2002
llvm:skip:f64.wast:2005
llvm:skip:f64.wast:2006
llvm:skip:f64.wast:2009
llvm:skip:f64.wast:2010
llvm:skip:f64.wast:2013
llvm:skip:f64.wast:2014
llvm:skip:f64.wast:2017
llvm:skip:f64.wast:2018
llvm:skip:f64.wast:2051
llvm:skip:f64.wast:2052
llvm:skip:f64.wast:2053
llvm:skip:f64.wast:2054
llvm:skip:f64.wast:2055
llvm:skip:f64.wast:2056
llvm:skip:f64.wast:2057
llvm:skip:f64.wast:2058
llvm:skip:f64.wast:2091
llvm:skip:f64.wast:2092
llvm:skip:f64.wast:2093
llvm:skip:f64.wast:2094
llvm:skip:f64.wast:2095
llvm:skip:f64.wast:2096
llvm:skip:f64.wast:2097
llvm:skip:f64.wast:2098
llvm:skip:f64.wast:2131
llvm:skip:f64.wast:2132
llvm:skip:f64.wast:2133
llvm:skip:f64.wast:2134
llvm:skip:f64.wast:2135
llvm:skip:f64.wast:2136
llvm:skip:f64.wast:2137
llvm:skip:f64.wast:2138
llvm:skip:f64.wast:2171
llvm:skip:f64.wast:2172
llvm:skip:f64.wast:2173
llvm:skip:f64.wast:2174
llvm:skip:f64.wast:2175
llvm:skip:f64.wast:2176
llvm:skip:f64.wast:2177
llvm:skip:f64.wast:2178
llvm:skip:f64.wast:2211
llvm:skip:f64.wast:2212
llvm:skip:f64.wast:2213
llvm:skip:f64.wast:2214
llvm:skip:f64.wast:2215
llvm:skip:f64.wast:2216
llvm:skip:f64.wast:2217
llvm:skip:f64.wast:2218
llvm:skip:f64.wast:2251
llvm:skip:f64.wast:2252
llvm:skip:f64.wast:2253
llvm:skip:f64.wast:2254
llvm:skip:f64.wast:2255
llvm:skip:f64.wast:2256
llvm:skip:f64.wast:2257
llvm:skip:f64.wast:2258
llvm:skip:f64.wast:2291
llvm:skip:f64.wast:2292
llvm:skip:f64.wast:2293
llvm:skip:f64.wast:2294
llvm:skip:f64.wast:2295
llvm:skip:f64.wast:2296
llvm:skip:f64.wast:2297
llvm:skip:f64.wast:2298
llvm:skip:f64.wast:2331
llvm:skip:f64.wast:2332
llvm:skip:f64.wast:2333
llvm:skip:f64.wast:2334
llvm:skip:f64.wast:2335
llvm:skip:f64.wast:2336
llvm:skip:f64.wast:2337
llvm:skip:f64.wast:2338
llvm:skip:f64.wast:2339
llvm:skip:f64.wast:2340
llvm:skip:f64.wast:2341
llvm:skip:f64.wast:2342
llvm:skip:f64.wast:2343
llvm:skip:f64.wast:2344
llvm:skip:f64.wast:2345
llvm:skip:f64.wast:2346
llvm:skip:f64.wast:2347
llvm:skip:f64.wast:2348
llvm:skip:f64.wast:2349
llvm:skip:f64.wast:2350
llvm:skip:f64.wast:2351
llvm:skip:f64.wast:2352
llvm:skip:f64.wast:2353
llvm:skip:f64.wast:2354
llvm:skip:f64.wast:2355
llvm:skip:f64.wast:2356
llvm:skip:f64.wast:2357
llvm:skip:f64.wast:2358
llvm:skip:f64.wast:2359
llvm:skip:f64.wast:2360
llvm:skip:f64.wast:2361
llvm:skip:f64.wast:2362
llvm:skip:f64.wast:2363
llvm:skip:f64.wast:2364
llvm:skip:f64.wast:2365
llvm:skip:f64.wast:2366
llvm:skip:f64.wast:2367
llvm:skip:f64.wast:2368
llvm:skip:f64.wast:2369
llvm:skip:f64.wast:2370
llvm:skip:f64.wast:2371
llvm:skip:f64.wast:2372
llvm:skip:f64.wast:2373
llvm:skip:f64.wast:2374
llvm:skip:f64.wast:2375
llvm:skip:f64.wast:2376
llvm:skip:f64.wast:2377
llvm:skip:f64.wast:2378
llvm:skip:f64.wast:2379
llvm:skip:f64.wast:2380
llvm:skip:f64.wast:2381
llvm:skip:f64.wast:2382
llvm:skip:f64.wast:2383
llvm:skip:f64.wast:2384
llvm:skip:f64.wast:2385
llvm:skip:f64.wast:2386
llvm:skip:f64.wast:2387
llvm:skip:f64.wast:2388
llvm:skip:f64.wast:2389
llvm:skip:f64.wast:2390
llvm:skip:f64.wast:2391
llvm:skip:f64.wast:2392
llvm:skip:f64.wast:2393
llvm:skip:f64.wast:2394
llvm:skip:f64.wast:2395
llvm:skip:f64.wast:2396
llvm:skip:f64.wast:2397
llvm:skip:f64.wast:2398
llvm:skip:f64.wast:2399
llvm:skip:f64.wast:2400
llvm:skip:f64.wast:2401
llvm:skip:f64.wast:2402
llvm:skip:f64.wast:2405
llvm:skip:f64.wast:2406
llvm:skip:f64.wast:2409
llvm:skip:f64.wast:2410
llvm:skip:f64.wast:2413
llvm:skip:f64.wast:2414
llvm:skip:f64.wast:2417
llvm:skip:f64.wast:2418
# LLVM
llvm:skip:br_table.wast:1255
llvm:skip:imports.wast:391 # Running forever
llvm:skip:imports.wast:402 # Running forever
llvm:skip:call.wast:273 # Spec running forever
llvm:skip:call_indirect.wast:556 # Spec running forever
llvm:skip:call_indirect.wast:557 # Spec running forever
llvm:skip:fac.wast:89 # Spec running forever
llvm:skip:skip-stack-guard-page.wast:* # Spec running forever or (signal: 4, SIGILL: illegal instruction)
llvm:skip:linking.wast:236 # terminating with uncaught exception of type WasmTrap
llvm:skip:linking.wast:248 # terminating with uncaught exception of type WasmTrap
llvm:fail:f32.wast:1621 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000")
llvm:fail:f32.wast:2020 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0")
llvm:fail:f64.wast:1621 # AssertReturn - result F64(0) ("0x0") does not match expected F64(9223372036854775808) ("0x8000000000000000")
llvm:fail:f64.wast:2020 # AssertReturn - result F64(9223372036854775808) ("0x8000000000000000") does not match expected F64(0) ("0x0")
llvm:fail:i32.wast:243 # AssertReturn - result I32(283816271) ("0x10eab14f") does not match expected I32(32) ("0x20")
llvm:fail:i32.wast:252 # AssertReturn - result I32(283816288) ("0x10eab160") does not match expected I32(32) ("0x20")
llvm:fail:i64.wast:243 # AssertReturn - result I64(4578783727) ("0x110eab1ef") does not match expected I64(64) ("0x40")
llvm:fail:i64.wast:252 # AssertReturn - result I64(4578783712) ("0x110eab1e0") does not match expected I64(64) ("0x40")
llvm:fail:linking.wast:387 # AssertReturn - result I32(0) ("0x0") does not match expected I32(104) ("0x68")
llvm:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature
llvm:fail:load.wast:201 # AssertReturn - result I32(285315103) ("0x1101901f") does not match expected I32(32) ("0x20")
# LLVM Windows
llvm:skip:address.wast:*:windows

View File

@ -23,7 +23,7 @@ use structopt::StructOpt;
use wasmer::*;
use wasmer_clif_backend::CraneliftCompiler;
#[cfg(feature = "backend-llvm")]
use wasmer_llvm_backend::LLVMCompiler;
use wasmer_llvm_backend::{LLVMCompiler, LLVMOptions};
use wasmer_runtime::{
cache::{Cache as BaseCache, FileSystemCache, WasmHash},
Func, Value, VERSION,
@ -109,7 +109,7 @@ pub struct LLVMCLIOptions {
post_opt_ir: Option<PathBuf>,
/// Emit LLVM generated native code object file.
#[structopt(long = "backend-llvm-object-file", parse(from_os_str))]
#[structopt(long = "llvm-object-file", parse(from_os_str))]
obj_file: Option<PathBuf>,
}
@ -405,6 +405,20 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
None => return Err("the requested backend is not enabled".into()),
};
#[cfg(feature = "backend-llvm")]
{
if options.backend == Backend::LLVM {
let options = options.backend_llvm_options.clone();
unsafe {
wasmer_llvm_backend::GLOBAL_OPTIONS = LLVMOptions {
pre_opt_ir: options.pre_opt_ir,
post_opt_ir: options.post_opt_ir,
obj_file: options.obj_file,
}
}
}
}
let track_state = !options.no_track_state;
#[cfg(feature = "loader-kernel")]