diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 64c6e0a540f8..b33b9666f712 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -173,6 +173,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "frem_fast" => mir::BinOp::Rem, _ => bug!(), }; + let float_finite = |x: ImmTy<'tcx, _>| -> InterpResult<'tcx, bool> { + Ok(match x.layout.ty.kind() { + ty::Float(FloatTy::F32) => x.to_scalar()?.to_f32()?.is_finite(), + ty::Float(FloatTy::F64) => x.to_scalar()?.to_f64()?.is_finite(), + _ => bug!( + "`{}` called with non-float input type {:?}", + intrinsic_name, + x.layout.ty + ), + }) + }; + match (float_finite(a)?, float_finite(b)?) { + (false, false) => throw_ub_format!( + "`{}` intrinsic called with non-finite value as both parameters", + intrinsic_name, + ), + (false, _) => throw_ub_format!( + "`{}` intrinsic called with non-finite value as first parameter", + intrinsic_name, + ), + (_, false) => throw_ub_format!( + "`{}` intrinsic called with non-finite value as second parameter", + intrinsic_name, + ), + _ => {} + } this.binop_ignore_overflow(op, &a, &b, dest)?; } diff --git a/tests/compile-fail/fast_math_both.rs b/tests/compile-fail/fast_math_both.rs new file mode 100644 index 000000000000..844e4e95211f --- /dev/null +++ b/tests/compile-fail/fast_math_both.rs @@ -0,0 +1,7 @@ +#![feature(core_intrinsics)] + +fn main() { + unsafe { + let _x: f32 = core::intrinsics::fsub_fast(f32::NAN, f32::NAN); //~ ERROR `fsub_fast` intrinsic called with non-finite value as both parameters + } +} diff --git a/tests/compile-fail/fast_math_first.rs b/tests/compile-fail/fast_math_first.rs new file mode 100644 index 000000000000..470ebe620050 --- /dev/null +++ b/tests/compile-fail/fast_math_first.rs @@ -0,0 +1,7 @@ +#![feature(core_intrinsics)] + +fn main() { + unsafe { + let _x: f32 = core::intrinsics::frem_fast(f32::NAN, 3.2); //~ ERROR `frem_fast` intrinsic called with non-finite value as first parameter + } +} diff --git a/tests/compile-fail/fast_math_second.rs b/tests/compile-fail/fast_math_second.rs new file mode 100644 index 000000000000..e8d70a4a79e7 --- /dev/null +++ b/tests/compile-fail/fast_math_second.rs @@ -0,0 +1,7 @@ +#![feature(core_intrinsics)] + +fn main() { + unsafe { + let _x: f32 = core::intrinsics::fmul_fast(3.4f32, f32::INFINITY); //~ ERROR `fmul_fast` intrinsic called with non-finite value as second parameter + } +}