diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2022-03-25 19:17:19 +0100 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2022-03-25 19:32:14 +0100 |
| commit | f3d97cce279fd2372aafec3761791b4110d70bf5 (patch) | |
| tree | 00101f6e59b07d1b0d8605b5123ece3c82b2da60 | |
| parent | e336e1bccf3831097283469243b0228accea85d4 (diff) | |
| download | rust-f3d97cce279fd2372aafec3761791b4110d70bf5.tar.gz rust-f3d97cce279fd2372aafec3761791b4110d70bf5.zip | |
Fix saturating float casts test
Fixes #737
| -rw-r--r-- | example/std_example.rs | 6 | ||||
| -rwxr-xr-x | scripts/test_rustc_tests.sh | 1 | ||||
| -rw-r--r-- | src/cast.rs | 29 |
3 files changed, 26 insertions, 10 deletions
diff --git a/example/std_example.rs b/example/std_example.rs index 5bc51a541b5..0a2bce2621d 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -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; @@ -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 { diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index f03a921d6a3..5f47e7204ea 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -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 diff --git a/src/cast.rs b/src/cast.rs index e7e6afeb865..e19070774c6 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -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 @@ -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) @@ -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 |
