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:
Stuart Cook
2025-09-25 20:31:54 +10:00
committed by GitHub
18 changed files with 118 additions and 135 deletions

View File

@@ -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(())
}
}

View File

@@ -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