-
Notifications
You must be signed in to change notification settings - Fork 72
Closed
Labels
UnsoundSomething breaks Rust safety guaranteesSomething breaks Rust safety guarantees
Description
See it live: https://play.rust-lang.org/?gist=2ccd8fb4e41fc1b28a1cc6a2e5774a7b&version=nightly
#![feature(repr_simd)]
#![feature(platform_intrinsics)]
extern "platform-intrinsic" {
fn simd_reduce_min<T,U>(a: T) -> U;
}
#[repr(simd)]
pub struct F(f32, f32);
pub fn foo(x: F) -> f32 {
unsafe { simd_reduce_min(x) }
}
fn main() {
let x = F(1.0, -1.0);
assert_eq!(foo(x), -1.0); // OK
let y = F(std::f32::NAN, -1.0);
assert_eq!(foo(y), -1.0); // OK
let z = F(-1.0, std::f32::NAN);
assert_eq!(foo(z), -1.0); // FAILS: returns NaN
}So I've filled: https://bugs.llvm.org/show_bug.cgi?id=36982
This issue is probably because llvm.vector.reduce.fmin/fmax have the semantics of fcmp instead of minnum/maxnum. We will probably need to workaround this issue in stdsimd.
What we want is the same semantics that Rust specifies for min/max on floating-point primitive types. For min this is:
Returns the minimum of the two numbers. If one of the arguments is NaN, then the other argument is returned.
This looks compatible with the specifications of IEEE754-2018 (drafts are here: http://754r.ucbtest.org/drafts/). From the latest draft (P754-233 17-Mar-2018):
**minimumNumber**(x, y) is x if x<y, y if y<x, and the number if one operand is a number and the
other is a NaN. For this operation, −0 compares less than +0. If x=y and signs are the same it is
either x or y. If both operands are NaNs, a quiet NaN is returned, according to 6.2. If either
operand is a signaling NaN, an invalid operation exception is signaled, but unless both operands
are NaNs, the signaling NaN is otherwise ignored and not converted to a quiet NaN as stated in
6.2 for other operations.
**maximumNumber**(x, y) is x if x>y, y if y>x, and the number if one operand is a number and the
other is a NaN. For this operation, +0 compares greater than −0. If x=y and signs are the same it
is either x or y.If both operands are NaNs, a quiet NaN is returned, according to 6.2. If either
operand is a signaling NaN, an invalid operation exception is signaled, but unless both operands
are NaNs, the signaling NaN is otherwise ignored and not converted to a quiet NaN as stated in
6.2 for other operations
Metadata
Metadata
Assignees
Labels
UnsoundSomething breaks Rust safety guaranteesSomething breaks Rust safety guarantees