From 18379e8e70c6ab5d79bb19d0b37c2a1d964928d6 Mon Sep 17 00:00:00 2001 From: bendn Date: Sat, 11 May 2024 08:41:04 +0700 Subject: [PATCH] support `f*_algebraic` --- src/intrinsics/mod.rs | 22 +++++++++++++ tests/pass/intrinsics/float_algebraic_math.rs | 32 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 tests/pass/intrinsics/float_algebraic_math.rs diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index effd7f6d54..e38a9e4d5e 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -256,6 +256,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let res = this.adjust_nan(res, &[f]); this.write_scalar(res, dest)?; } + #[rustfmt::skip] + | "fadd_algebraic" + | "fsub_algebraic" + | "fmul_algebraic" + | "fdiv_algebraic" + | "frem_algebraic" + => { + let [a, b] = check_arg_count(args)?; + let a = this.read_immediate(a)?; + let b = this.read_immediate(b)?; + let op = match intrinsic_name { + "fadd_algebraic" => mir::BinOp::Add, + "fsub_algebraic" => mir::BinOp::Sub, + "fmul_algebraic" => mir::BinOp::Mul, + "fdiv_algebraic" => mir::BinOp::Div, + "frem_algebraic" => mir::BinOp::Rem, + _ => bug!(), + }; + let res = this.wrapping_binary_op(op, &a, &b)?; + // `wrapping_binary_op` already called `generate_nan` if necessary. + this.write_immediate(*res, dest)?; + } #[rustfmt::skip] | "fadd_fast" diff --git a/tests/pass/intrinsics/float_algebraic_math.rs b/tests/pass/intrinsics/float_algebraic_math.rs new file mode 100644 index 0000000000..f6f083f7b5 --- /dev/null +++ b/tests/pass/intrinsics/float_algebraic_math.rs @@ -0,0 +1,32 @@ +#![feature(core_intrinsics)] + +use std::intrinsics::{ + fadd_algebraic, fdiv_algebraic, fmul_algebraic, frem_algebraic, fsub_algebraic, +}; + +#[inline(never)] +pub fn test_operations_f64(a: f64, b: f64) { + // make sure they all map to the correct operation + assert_eq!(fadd_algebraic(a, b), a + b); + assert_eq!(fsub_algebraic(a, b), a - b); + assert_eq!(fmul_algebraic(a, b), a * b); + assert_eq!(fdiv_algebraic(a, b), a / b); + assert_eq!(frem_algebraic(a, b), a % b); +} + +#[inline(never)] +pub fn test_operations_f32(a: f32, b: f32) { + // make sure they all map to the correct operation + assert_eq!(fadd_algebraic(a, b), a + b); + assert_eq!(fsub_algebraic(a, b), a - b); + assert_eq!(fmul_algebraic(a, b), a * b); + assert_eq!(fdiv_algebraic(a, b), a / b); + assert_eq!(frem_algebraic(a, b), a % b); +} + +fn main() { + test_operations_f64(1., 2.); + test_operations_f64(10., 5.); + test_operations_f32(11., 2.); + test_operations_f32(10., 15.); +}