diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index cae9c813c17..b33b9666f71 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -173,35 +173,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "frem_fast" => mir::BinOp::Rem, _ => bug!(), }; - let a_valid = match a.layout.ty.kind() { - ty::Float(FloatTy::F32) => a.to_scalar()?.to_f32()?.is_finite(), - ty::Float(FloatTy::F64) => a.to_scalar()?.to_f64()?.is_finite(), - _ => bug!( - "`{}` called with non-float input type {:?}", - intrinsic_name, - a.layout.ty - ), + 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 + ), + }) }; - if !a_valid { - throw_ub_format!( + 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, - ); - } - let b_valid = match b.layout.ty.kind() { - ty::Float(FloatTy::F32) => b.to_scalar()?.to_f32()?.is_finite(), - ty::Float(FloatTy::F64) => b.to_scalar()?.to_f64()?.is_finite(), - _ => bug!( - "`{}` called with non-float input type {:?}", - intrinsic_name, - b.layout.ty ), - }; - if !b_valid { - throw_ub_format!( + (_, 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 index 470ebe62005..844e4e95211 100644 --- a/tests/compile-fail/fast_math_both.rs +++ b/tests/compile-fail/fast_math_both.rs @@ -2,6 +2,6 @@ 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 + 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 index 184476a4741..470ebe62005 100644 --- a/tests/compile-fail/fast_math_first.rs +++ b/tests/compile-fail/fast_math_first.rs @@ -2,6 +2,6 @@ fn main() { unsafe { - let _x: f32 = core::intrinsics::fsub_fast(f32::NAN, f32::NAN); //~ ERROR `fsub_fast` intrinsic called with non-finite value as first parameter + let _x: f32 = core::intrinsics::frem_fast(f32::NAN, 3.2); //~ ERROR `frem_fast` intrinsic called with non-finite value as first parameter } }