Rollup merge of #146735 - Qelxiros:const_mul_add, r=tgross35,RalfJung
unstably constify float mul_add methods Tracking issue: rust-lang/rust#146724 r? `@tgross35`
This commit is contained in:
@@ -636,6 +636,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
dest,
|
||||
rustc_apfloat::Round::NearestTiesToEven,
|
||||
)?,
|
||||
sym::fmaf16 => self.fma_intrinsic::<Half>(args, dest)?,
|
||||
sym::fmaf32 => self.fma_intrinsic::<Single>(args, dest)?,
|
||||
sym::fmaf64 => self.fma_intrinsic::<Double>(args, dest)?,
|
||||
sym::fmaf128 => self.fma_intrinsic::<Quad>(args, dest)?,
|
||||
sym::fmuladdf16 => self.float_muladd_intrinsic::<Half>(args, dest)?,
|
||||
sym::fmuladdf32 => self.float_muladd_intrinsic::<Single>(args, dest)?,
|
||||
sym::fmuladdf64 => self.float_muladd_intrinsic::<Double>(args, dest)?,
|
||||
sym::fmuladdf128 => self.float_muladd_intrinsic::<Quad>(args, dest)?,
|
||||
|
||||
// Unsupported intrinsic: skip the return_to_block below.
|
||||
_ => return interp_ok(false),
|
||||
@@ -1035,4 +1043,42 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self.write_scalar(res, dest)?;
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
fn fma_intrinsic<F>(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, M::Provenance>],
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, ()>
|
||||
where
|
||||
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
|
||||
{
|
||||
let a: F = self.read_scalar(&args[0])?.to_float()?;
|
||||
let b: F = self.read_scalar(&args[1])?.to_float()?;
|
||||
let c: F = self.read_scalar(&args[2])?.to_float()?;
|
||||
|
||||
let res = a.mul_add(b, c).value;
|
||||
let res = self.adjust_nan(res, &[a, b, c]);
|
||||
self.write_scalar(res, dest)?;
|
||||
interp_ok(())
|
||||
}
|
||||
|
||||
fn float_muladd_intrinsic<F>(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, M::Provenance>],
|
||||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx, ()>
|
||||
where
|
||||
F: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F> + Into<Scalar<M::Provenance>>,
|
||||
{
|
||||
let a: F = self.read_scalar(&args[0])?.to_float()?;
|
||||
let b: F = self.read_scalar(&args[1])?.to_float()?;
|
||||
let c: F = self.read_scalar(&args[2])?.to_float()?;
|
||||
|
||||
let fuse = M::float_fuse_mul_add(self);
|
||||
|
||||
let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value };
|
||||
let res = self.adjust_nan(res, &[a, b, c]);
|
||||
self.write_scalar(res, dest)?;
|
||||
interp_ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +289,9 @@ pub trait Machine<'tcx>: Sized {
|
||||
a
|
||||
}
|
||||
|
||||
/// Determines whether the `fmuladd` intrinsics fuse the multiply-add or use separate operations.
|
||||
fn float_fuse_mul_add(_ecx: &mut InterpCx<'tcx, Self>) -> bool;
|
||||
|
||||
/// Called before a basic block terminator is executed.
|
||||
#[inline]
|
||||
fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
|
||||
@@ -672,6 +675,11 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
|
||||
match fn_val {}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn float_fuse_mul_add(_ecx: &mut InterpCx<$tcx, Self>) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ub_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> {
|
||||
// We can't look at `tcx.sess` here as that can differ across crates, which can lead to
|
||||
|
||||
Reference in New Issue
Block a user