Skip to content
/ rust Public
forked from rust-lang/rust

Commit 9281ddc

Browse files
committed
add gamma function shims
1 parent 2e14f25 commit 9281ddc

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/tools/miri/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(rustc_private)]
2+
#![feature(float_gamma)]
23
#![feature(map_try_insert)]
34
#![feature(never_type)]
45
#![feature(try_blocks)]

src/tools/miri/src/shims/foreign_items.rs

+24
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
815815
| "atanf"
816816
| "log1pf"
817817
| "expm1f"
818+
| "tgammaf"
818819
=> {
819820
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
820821
// FIXME: Using host floats.
@@ -830,6 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
830831
"atanf" => f.atan(),
831832
"log1pf" => f.ln_1p(),
832833
"expm1f" => f.exp_m1(),
834+
"tgammaf" => f.gamma(),
833835
_ => bug!(),
834836
};
835837
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
@@ -866,6 +868,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
866868
| "atan"
867869
| "log1p"
868870
| "expm1"
871+
| "tgamma"
869872
=> {
870873
let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
871874
// FIXME: Using host floats.
@@ -881,6 +884,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
881884
"atan" => f.atan(),
882885
"log1p" => f.ln_1p(),
883886
"expm1" => f.exp_m1(),
887+
"tgamma" => f.gamma(),
884888
_ => bug!(),
885889
};
886890
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
@@ -917,6 +921,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
917921
let res = x.scalbn(exp);
918922
this.write_scalar(Scalar::from_f64(res), dest)?;
919923
}
924+
"lgammaf_r" => {
925+
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
926+
// FIXME: Using host floats.
927+
let x = f32::from_bits(this.read_scalar(x)?.to_u32()?);
928+
let signp = this.deref_pointer(signp)?;
929+
930+
let (res, sign) = x.ln_gamma();
931+
this.write_int(sign, &signp)?;
932+
this.write_scalar(Scalar::from_u32(res.to_bits()), dest)?;
933+
}
934+
"lgamma_r" => {
935+
let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
936+
// FIXME: Using host floats.
937+
let x = f64::from_bits(this.read_scalar(x)?.to_u64()?);
938+
let signp = this.deref_pointer(signp)?;
939+
940+
let (res, sign) = x.ln_gamma();
941+
this.write_int(sign, &signp)?;
942+
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
943+
}
920944

921945
// Architecture-specific shims
922946
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {

src/tools/miri/tests/pass/intrinsics-math.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// SPDX-License-Identifier: MIT OR Apache-2.0
2-
// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org)
1+
#![feature(float_gamma)]
32

43
macro_rules! assert_approx_eq {
54
($a:expr, $b:expr) => {{
@@ -130,4 +129,20 @@ pub fn main() {
130129
);
131130
assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
132131
assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
132+
133+
assert_approx_eq!(5.0f32.gamma(), 24.0);
134+
assert_approx_eq!(5.0f64.gamma(), 24.0);
135+
// These fail even on the host, precision seems to be terrible.
136+
//assert_approx_eq!(-0.5f32.gamma(), -2.0 * f32::consts::PI.sqrt());
137+
//assert_approx_eq!(-0.5f64.gamma(), -2.0 * f64::consts::PI.sqrt());
138+
139+
assert_eq!(2.0f32.ln_gamma(), (0.0, 1));
140+
assert_eq!(2.0f64.ln_gamma(), (0.0, 1));
141+
// Gamma(-0.5) = -2*sqrt(π)
142+
let (val, sign) = (-0.5f32).ln_gamma();
143+
assert_approx_eq!(val, (2.0 * f32::consts::PI.sqrt()).ln());
144+
assert_eq!(sign, -1);
145+
let (val, sign) = (-0.5f64).ln_gamma();
146+
assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln());
147+
assert_eq!(sign, -1);
133148
}

0 commit comments

Comments
 (0)