Skip to content

Commit c09ed3e

Browse files
committed
Make some float methods unstable const fn
Some float methods are now `const fn` under the `const_float_methods` feature gate. In order to support `min`, `max`, `abs` and `copysign`, the implementation of some intrinsics had to be moved from Miri to rustc_const_eval.
1 parent b73e613 commit c09ed3e

File tree

14 files changed

+498
-243
lines changed

14 files changed

+498
-243
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+80
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
use std::assert_matches::assert_matches;
66

7+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
78
use rustc_hir::def_id::DefId;
89
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
910
use rustc_middle::ty::layout::{LayoutOf as _, TyAndLayout, ValidityRequirement};
@@ -438,6 +439,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
438439
self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?;
439440
}
440441

442+
sym::minnumf16 => self.float_min_intrinsic::<Half>(args, dest)?,
443+
sym::minnumf32 => self.float_min_intrinsic::<Single>(args, dest)?,
444+
sym::minnumf64 => self.float_min_intrinsic::<Double>(args, dest)?,
445+
sym::minnumf128 => self.float_min_intrinsic::<Quad>(args, dest)?,
446+
447+
sym::maxnumf16 => self.float_max_intrinsic::<Half>(args, dest)?,
448+
sym::maxnumf32 => self.float_max_intrinsic::<Single>(args, dest)?,
449+
sym::maxnumf64 => self.float_max_intrinsic::<Double>(args, dest)?,
450+
sym::maxnumf128 => self.float_max_intrinsic::<Quad>(args, dest)?,
451+
452+
sym::copysignf16 => self.float_copysign_intrinsic::<Half>(args, dest)?,
453+
sym::copysignf32 => self.float_copysign_intrinsic::<Single>(args, dest)?,
454+
sym::copysignf64 => self.float_copysign_intrinsic::<Double>(args, dest)?,
455+
sym::copysignf128 => self.float_copysign_intrinsic::<Quad>(args, dest)?,
456+
457+
sym::fabsf16 => self.float_abs_intrinsic::<Half>(args, dest)?,
458+
sym::fabsf32 => self.float_abs_intrinsic::<Single>(args, dest)?,
459+
sym::fabsf64 => self.float_abs_intrinsic::<Double>(args, dest)?,
460+
sym::fabsf128 => self.float_abs_intrinsic::<Quad>(args, dest)?,
461+
441462
// Unsupported intrinsic: skip the return_to_block below.
442463
_ => return interp_ok(false),
443464
}
@@ -697,4 +718,63 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
697718
let rhs_bytes = get_bytes(self, rhs)?;
698719
interp_ok(Scalar::from_bool(lhs_bytes == rhs_bytes))
699720
}
721+
722+
fn float_min_intrinsic<F>(
723+
&mut self,
724+
args: &[OpTy<'tcx, M::Provenance>],
725+
dest: &MPlaceTy<'tcx, M::Provenance>,
726+
) -> InterpResult<'tcx, ()>
727+
where
728+
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
729+
{
730+
let a: F = self.read_scalar(&args[0])?.to_float()?;
731+
let b: F = self.read_scalar(&args[1])?.to_float()?;
732+
let res = self.adjust_nan(a.min(b), &[a, b]);
733+
self.write_scalar(res, dest)?;
734+
interp_ok(())
735+
}
736+
737+
fn float_max_intrinsic<F>(
738+
&mut self,
739+
args: &[OpTy<'tcx, M::Provenance>],
740+
dest: &MPlaceTy<'tcx, M::Provenance>,
741+
) -> InterpResult<'tcx, ()>
742+
where
743+
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
744+
{
745+
let a: F = self.read_scalar(&args[0])?.to_float()?;
746+
let b: F = self.read_scalar(&args[1])?.to_float()?;
747+
let res = self.adjust_nan(a.max(b), &[a, b]);
748+
self.write_scalar(res, dest)?;
749+
interp_ok(())
750+
}
751+
752+
fn float_copysign_intrinsic<F>(
753+
&mut self,
754+
args: &[OpTy<'tcx, M::Provenance>],
755+
dest: &MPlaceTy<'tcx, M::Provenance>,
756+
) -> InterpResult<'tcx, ()>
757+
where
758+
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
759+
{
760+
let a: F = self.read_scalar(&args[0])?.to_float()?;
761+
let b: F = self.read_scalar(&args[1])?.to_float()?;
762+
// bitwise, no NaN adjustments
763+
self.write_scalar(a.copy_sign(b), dest)?;
764+
interp_ok(())
765+
}
766+
767+
fn float_abs_intrinsic<F>(
768+
&mut self,
769+
args: &[OpTy<'tcx, M::Provenance>],
770+
dest: &MPlaceTy<'tcx, M::Provenance>,
771+
) -> InterpResult<'tcx, ()>
772+
where
773+
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
774+
{
775+
let x: F = self.read_scalar(&args[0])?.to_float()?;
776+
// bitwise, no NaN adjustments
777+
self.write_scalar(x.abs(), dest)?;
778+
interp_ok(())
779+
}
700780
}

0 commit comments

Comments
 (0)