Skip to content

Commit

Permalink
Fix saturating float casts test
Browse files Browse the repository at this point in the history
Fixes #737
  • Loading branch information
bjorn3 committed Mar 25, 2022
1 parent e336e1b commit f3d97cc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
6 changes: 5 additions & 1 deletion example/std_example.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![feature(core_intrinsics, generators, generator_trait, is_sorted)]
#![feature(core_intrinsics, generators, generator_trait, is_sorted, bench_black_box)]

#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*;
use std::hint::black_box;
use std::io::Write;
use std::ops::Generator;

Expand Down Expand Up @@ -86,6 +87,9 @@ fn main() {
assert_eq!(houndred_f64 as i128, 100);
assert_eq!(1u128.rotate_left(2), 4);

assert_eq!(black_box(f32::NAN) as i128, 0);
assert_eq!(black_box(f32::NAN) as u128, 0);

// Test signed 128bit comparing
let max = usize::MAX as i128;
if 100i128 < 0i128 || 100i128 > max {
Expand Down
1 change: 0 additions & 1 deletion scripts/test_rustc_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ rm src/test/ui/abi/stack-protector.rs # requires stack protector support

# giving different but possibly correct results
# =============================================
rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result
rm src/test/ui/simd/intrinsic/float-minmax-pass.rs # same
rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
Expand Down
29 changes: 21 additions & 8 deletions src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(crate) fn clif_int_or_float_cast(
fx.bcx.ins().fcvt_from_uint(to_ty, from)
}
} else if from_ty.is_float() && to_ty.is_int() {
if to_ty == types::I128 {
let val = if to_ty == types::I128 {
// _____sssf___
// __fix sfti: f32 -> i128
// __fix dfti: f64 -> i128
Expand All @@ -109,13 +109,9 @@ pub(crate) fn clif_int_or_float_cast(

let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 };

return fx
.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
.load_scalar(fx);
}

// float -> int-like
if to_ty == types::I8 || to_ty == types::I16 {
fx.easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty)
.load_scalar(fx)
} else if to_ty == types::I8 || to_ty == types::I16 {
// FIXME implement fcvt_to_*int_sat.i8/i16
let val = if to_signed {
fx.bcx.ins().fcvt_to_sint_sat(types::I32, from)
Expand Down Expand Up @@ -146,6 +142,23 @@ pub(crate) fn clif_int_or_float_cast(
fx.bcx.ins().fcvt_to_sint_sat(to_ty, from)
} else {
fx.bcx.ins().fcvt_to_uint_sat(to_ty, from)
};

if let Some(false) = fx.tcx.sess.opts.debugging_opts.saturating_float_casts {
return val;
}

let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
if to_ty == types::I128 {
// FIXME(bytecodealliance/wasmtime#3963): select.i128 on fcmp eq miscompiles
let (lsb, msb) = fx.bcx.ins().isplit(val);
let zero = fx.bcx.ins().iconst(types::I64, 0);
let lsb = fx.bcx.ins().select(is_not_nan, lsb, zero);
let msb = fx.bcx.ins().select(is_not_nan, msb, zero);
fx.bcx.ins().iconcat(lsb, msb)
} else {
let zero = fx.bcx.ins().iconst(to_ty, 0);
fx.bcx.ins().select(is_not_nan, val, zero)
}
} else if from_ty.is_float() && to_ty.is_float() {
// float -> float
Expand Down

0 comments on commit f3d97cc

Please sign in to comment.