extract core operation name instead of listing all function name variants
This commit is contained in:
parent
94ab2b9f15
commit
e00051299a
1 changed files with 26 additions and 17 deletions
|
|
@ -210,61 +210,70 @@ where
|
|||
let pi_over_2 = (pi / two).value;
|
||||
let pi_over_4 = (pi_over_2 / two).value;
|
||||
|
||||
Some(match (intrinsic_name, args) {
|
||||
// Remove `f32`/`f64` suffix, if any.
|
||||
let name = intrinsic_name
|
||||
.strip_suffix("f32")
|
||||
.or_else(|| intrinsic_name.strip_suffix("f64"))
|
||||
.unwrap_or(intrinsic_name);
|
||||
// Also strip trailing `f` (indicates "float"), with an exception for "erf" to avoid
|
||||
// removing that `f`.
|
||||
let name = if name == "erf" { name } else { name.strip_suffix("f").unwrap_or(name) };
|
||||
Some(match (name, args) {
|
||||
// cos(±0) and cosh(±0)= 1
|
||||
("cosf32" | "cosf64" | "coshf" | "cosh", [input]) if input.is_zero() => one,
|
||||
("cos" | "cosh", [input]) if input.is_zero() => one,
|
||||
|
||||
// e^0 = 1
|
||||
("expf32" | "expf64" | "exp2f32" | "exp2f64", [input]) if input.is_zero() => one,
|
||||
("exp" | "exp2", [input]) if input.is_zero() => one,
|
||||
|
||||
// tanh(±INF) = ±1
|
||||
("tanhf" | "tanh", [input]) if input.is_infinite() => one.copy_sign(*input),
|
||||
("tanh", [input]) if input.is_infinite() => one.copy_sign(*input),
|
||||
|
||||
// atan(±INF) = ±π/2
|
||||
("atanf" | "atan", [input]) if input.is_infinite() => pi_over_2.copy_sign(*input),
|
||||
("atan", [input]) if input.is_infinite() => pi_over_2.copy_sign(*input),
|
||||
|
||||
// erf(±INF) = ±1
|
||||
("erff" | "erf", [input]) if input.is_infinite() => one.copy_sign(*input),
|
||||
("erf", [input]) if input.is_infinite() => one.copy_sign(*input),
|
||||
|
||||
// erfc(-INF) = 2
|
||||
("erfcf" | "erfc", [input]) if input.is_neg_infinity() => (one + one).value,
|
||||
("erfc", [input]) if input.is_neg_infinity() => (one + one).value,
|
||||
|
||||
// hypot(x, ±0) = abs(x), if x is not a NaN.
|
||||
("_hypotf" | "hypotf" | "_hypot" | "hypot", [x, y]) if !x.is_nan() && y.is_zero() =>
|
||||
// `_hypot` is the Windows name for this.
|
||||
("_hypot" | "hypot", [x, y]) if !x.is_nan() && y.is_zero() =>
|
||||
x.abs(),
|
||||
|
||||
// atan2(±0,−0) = ±π.
|
||||
// atan2(±0, y) = ±π for y < 0.
|
||||
// Must check for non NaN because `y.is_negative()` also applies to NaN.
|
||||
("atan2f" | "atan2", [x, y]) if (x.is_zero() && (y.is_negative() && !y.is_nan())) =>
|
||||
("atan2", [x, y]) if (x.is_zero() && (y.is_negative() && !y.is_nan())) =>
|
||||
pi.copy_sign(*x),
|
||||
|
||||
// atan2(±x,−∞) = ±π for finite x > 0.
|
||||
("atan2f" | "atan2", [x, y])
|
||||
("atan2", [x, y])
|
||||
if (!x.is_zero() && !x.is_infinite()) && y.is_neg_infinity() =>
|
||||
pi.copy_sign(*x),
|
||||
|
||||
// atan2(x, ±0) = −π/2 for x < 0.
|
||||
// atan2(x, ±0) = π/2 for x > 0.
|
||||
("atan2f" | "atan2", [x, y]) if !x.is_zero() && y.is_zero() => pi_over_2.copy_sign(*x),
|
||||
("atan2", [x, y]) if !x.is_zero() && y.is_zero() => pi_over_2.copy_sign(*x),
|
||||
|
||||
//atan2(±∞, −∞) = ±3π/4
|
||||
("atan2f" | "atan2", [x, y]) if x.is_infinite() && y.is_neg_infinity() =>
|
||||
("atan2", [x, y]) if x.is_infinite() && y.is_neg_infinity() =>
|
||||
(pi_over_4 * three).value.copy_sign(*x),
|
||||
|
||||
//atan2(±∞, +∞) = ±π/4
|
||||
("atan2f" | "atan2", [x, y]) if x.is_infinite() && y.is_pos_infinity() =>
|
||||
("atan2", [x, y]) if x.is_infinite() && y.is_pos_infinity() =>
|
||||
pi_over_4.copy_sign(*x),
|
||||
|
||||
// atan2(±∞, y) returns ±π/2 for finite y.
|
||||
("atan2f" | "atan2", [x, y]) if x.is_infinite() && (!y.is_infinite() && !y.is_nan()) =>
|
||||
("atan2", [x, y]) if x.is_infinite() && (!y.is_infinite() && !y.is_nan()) =>
|
||||
pi_over_2.copy_sign(*x),
|
||||
|
||||
// (-1)^(±INF) = 1
|
||||
("powf32" | "powf64", [base, exp]) if *base == -one && exp.is_infinite() => one,
|
||||
("pow", [base, exp]) if *base == -one && exp.is_infinite() => one,
|
||||
|
||||
// 1^y = 1 for any y, even a NaN
|
||||
("powf32" | "powf64", [base, exp]) if *base == one => {
|
||||
("pow", [base, exp]) if *base == one => {
|
||||
let rng = this.machine.rng.get_mut();
|
||||
// SNaN exponents get special treatment: they might return 1, or a NaN.
|
||||
let return_nan = exp.is_signaling() && this.machine.float_nondet && rng.random();
|
||||
|
|
@ -273,7 +282,7 @@ where
|
|||
}
|
||||
|
||||
// x^(±0) = 1 for any x, even a NaN
|
||||
("powf32" | "powf64", [base, exp]) if exp.is_zero() => {
|
||||
("pow", [base, exp]) if exp.is_zero() => {
|
||||
let rng = this.machine.rng.get_mut();
|
||||
// SNaN bases get special treatment: they might return 1, or a NaN.
|
||||
let return_nan = base.is_signaling() && this.machine.float_nondet && rng.random();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue