mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-23 13:41:32 +00:00
Merge #863
863: Rewrite Min/Max to handle all cases correctly. Fixes 545 spectest failures. r=nlewycky a=nlewycky # Description The llvm backend was not quite following the Wasm spec for {F32,F64,F32x4xF64x2}{Min,Max}. We used the `@llvm.minnum` and `@llvm.maxnum` intrinsics which don't handle the corner cases the same. When we tried to use `@llvm.minimum` and `@llvm.maximum` which do, we get an internal error from the x86 backend. I was hoping that crash would go away with the upgrade to LLVM 9, but it does not. Reimplement these operations using plain LLVM instructions. # Review - [x] Add a short description of the the change to the CHANGELOG.md file Co-authored-by: Nick Lewycky <nick@wasmer.io>
This commit is contained in:
@ -6,6 +6,8 @@ Blocks of changes will separated by version increments.
|
|||||||
|
|
||||||
## **[Unreleased]**
|
## **[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
|
## 0.8.0 - 2019-10-02
|
||||||
|
|
||||||
Special thanks to @jdanford for their contributions!
|
Special thanks to @jdanford for their contributions!
|
||||||
|
@ -2681,86 +2681,404 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
|
|||||||
state.push1(bits);
|
state.push1(bits);
|
||||||
}
|
}
|
||||||
Operator::F32Min => {
|
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 (v1, v2) = state.pop2()?;
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.minimum_f32, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F64Min => {
|
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 (v1, v2) = state.pop2()?;
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.minimum_f64, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F32x4Min => {
|
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, v2) = state.pop2()?;
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
|
||||||
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
|
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.minimum_f32x4, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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, "");
|
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
|
||||||
state.push1(res);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F64x2Min => {
|
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, v2) = state.pop2()?;
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
|
||||||
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
|
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.minimum_f64x2, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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, "");
|
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
|
||||||
state.push1(res);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F32Max => {
|
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 (v1, v2) = state.pop2()?;
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.maximum_f32, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F64Max => {
|
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 (v1, v2) = state.pop2()?;
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.maximum_f64, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_float_value(), v2.into_float_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F32x4Max => {
|
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, v2) = state.pop2()?;
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.f32x4_ty, "");
|
||||||
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
|
let v2 = builder.build_bitcast(v2, intrinsics.f32x4_ty, "");
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.maximum_f32x4, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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, "");
|
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
|
||||||
state.push1(res);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
Operator::F64x2Max => {
|
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, v2) = state.pop2()?;
|
||||||
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
|
let v1 = builder.build_bitcast(v1, intrinsics.f64x2_ty, "");
|
||||||
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
|
let v2 = builder.build_bitcast(v2, intrinsics.f64x2_ty, "");
|
||||||
let res = builder
|
let v1 = canonicalize_nans(builder, intrinsics, v1);
|
||||||
.build_call(intrinsics.maximum_f64x2, &[v1, v2], &state.var_name())
|
let v2 = canonicalize_nans(builder, intrinsics, v2);
|
||||||
.try_as_basic_value()
|
let (v1, v2) = (v1.into_vector_value(), v2.into_vector_value());
|
||||||
.left()
|
let v1_is_nan = builder.build_float_compare(
|
||||||
.unwrap();
|
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, "");
|
let res = builder.build_bitcast(res, intrinsics.i128_ty, "");
|
||||||
state.push1(res);
|
state.push1(res);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ use inkwell::{
|
|||||||
types::{
|
types::{
|
||||||
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
|
BasicType, FloatType, FunctionType, IntType, PointerType, StructType, VectorType, VoidType,
|
||||||
},
|
},
|
||||||
values::{BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue},
|
values::{
|
||||||
|
BasicValue, BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue, VectorValue,
|
||||||
|
},
|
||||||
AddressSpace,
|
AddressSpace,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -125,6 +127,8 @@ pub struct Intrinsics {
|
|||||||
pub i128_zero: IntValue,
|
pub i128_zero: IntValue,
|
||||||
pub f32_zero: FloatValue,
|
pub f32_zero: FloatValue,
|
||||||
pub f64_zero: FloatValue,
|
pub f64_zero: FloatValue,
|
||||||
|
pub f32x4_zero: VectorValue,
|
||||||
|
pub f64x2_zero: VectorValue,
|
||||||
|
|
||||||
pub trap_unreachable: BasicValueEnum,
|
pub trap_unreachable: BasicValueEnum,
|
||||||
pub trap_call_indirect_sig: BasicValueEnum,
|
pub trap_call_indirect_sig: BasicValueEnum,
|
||||||
@ -191,6 +195,8 @@ impl Intrinsics {
|
|||||||
let i128_zero = i128_ty.const_int(0, false);
|
let i128_zero = i128_ty.const_int(0, false);
|
||||||
let f32_zero = f32_ty.const_float(0.0);
|
let f32_zero = f32_ty.const_float(0.0);
|
||||||
let f64_zero = f64_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 i1_ty_basic = i1_ty.as_basic_type_enum();
|
||||||
let i32_ty_basic = i32_ty.as_basic_type_enum();
|
let i32_ty_basic = i32_ty.as_basic_type_enum();
|
||||||
@ -455,6 +461,8 @@ impl Intrinsics {
|
|||||||
i128_zero,
|
i128_zero,
|
||||||
f32_zero,
|
f32_zero,
|
||||||
f64_zero,
|
f64_zero,
|
||||||
|
f32x4_zero,
|
||||||
|
f64x2_zero,
|
||||||
|
|
||||||
trap_unreachable: i32_zero.as_basic_value_enum(),
|
trap_unreachable: i32_zero.as_basic_value_enum(),
|
||||||
trap_call_indirect_sig: i32_ty.const_int(1, false).as_basic_value_enum(),
|
trap_call_indirect_sig: i32_ty.const_int(1, false).as_basic_value_enum(),
|
||||||
|
@ -264,554 +264,6 @@ clif:fail:data.wast:266:windows # AssertUnlinkable - caught panic Any
|
|||||||
clif:fail:data.wast:186: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
|
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
|
||||||
llvm:fail:f32.wast:1621 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000")
|
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:f32.wast:2020 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0")
|
||||||
|
Reference in New Issue
Block a user