mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 17:53:56 +00:00
add gamma function shims
This commit is contained in:
parent
2e14f25c9b
commit
9281ddc644
@ -1,4 +1,5 @@
|
||||
#![feature(rustc_private)]
|
||||
#![feature(float_gamma)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(never_type)]
|
||||
#![feature(try_blocks)]
|
||||
|
@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
| "atanf"
|
||||
| "log1pf"
|
||||
| "expm1f"
|
||||
| "tgammaf"
|
||||
=> {
|
||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
// FIXME: Using host floats.
|
||||
@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"atanf" => f.atan(),
|
||||
"log1pf" => f.ln_1p(),
|
||||
"expm1f" => f.exp_m1(),
|
||||
"tgammaf" => f.gamma(),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||
@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
| "atan"
|
||||
| "log1p"
|
||||
| "expm1"
|
||||
| "tgamma"
|
||||
=> {
|
||||
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
// FIXME: Using host floats.
|
||||
@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
"atan" => f.atan(),
|
||||
"log1p" => f.ln_1p(),
|
||||
"expm1" => f.exp_m1(),
|
||||
"tgamma" => f.gamma(),
|
||||
_ => bug!(),
|
||||
};
|
||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||
@ -917,6 +921,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let res = x.scalbn(exp);
|
||||
this.write_scalar(Scalar::from_f64(res), dest)?;
|
||||
}
|
||||
"lgammaf_r" => {
|
||||
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
// FIXME: Using host floats.
|
||||
let x = f32::from_bits(this.read_scalar(x)?.to_u32()?);
|
||||
let signp = this.deref_pointer(signp)?;
|
||||
|
||||
let (res, sign) = x.ln_gamma();
|
||||
this.write_int(sign, &signp)?;
|
||||
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
|
||||
}
|
||||
"lgamma_r" => {
|
||||
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
// FIXME: Using host floats.
|
||||
let x = f64::from_bits(this.read_scalar(x)?.to_u64()?);
|
||||
let signp = this.deref_pointer(signp)?;
|
||||
|
||||
let (res, sign) = x.ln_gamma();
|
||||
this.write_int(sign, &signp)?;
|
||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||
}
|
||||
|
||||
// Architecture-specific shims
|
||||
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
|
||||
|
@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org)
|
||||
#![feature(float_gamma)]
|
||||
|
||||
macro_rules! assert_approx_eq {
|
||||
($a:expr, $b:expr) => {{
|
||||
@ -130,4 +129,20 @@ pub fn main() {
|
||||
);
|
||||
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
|
||||
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
|
||||
|
||||
assert_approx_eq!(5.0f32.gamma(), 24.0);
|
||||
assert_approx_eq!(5.0f64.gamma(), 24.0);
|
||||
// These fail even on the host, precision seems to be terrible.
|
||||
//assert_approx_eq!(-0.5f32.gamma(), -2.0 * f32::consts::PI.sqrt());
|
||||
//assert_approx_eq!(-0.5f64.gamma(), -2.0 * f64::consts::PI.sqrt());
|
||||
|
||||
assert_eq!(2.0f32.ln_gamma(), (0.0, 1));
|
||||
assert_eq!(2.0f64.ln_gamma(), (0.0, 1));
|
||||
// Gamma(-0.5) = -2*sqrt(π)
|
||||
let (val, sign) = (-0.5f32).ln_gamma();
|
||||
assert_approx_eq!(val, (2.0 * f32::consts::PI.sqrt()).ln());
|
||||
assert_eq!(sign, -1);
|
||||
let (val, sign) = (-0.5f64).ln_gamma();
|
||||
assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln());
|
||||
assert_eq!(sign, -1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user