mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-02 01:52:51 +00:00
Rollup merge of #122470 - tgross35:f16-f128-step4-libs-min, r=Amanieu
`f16` and `f128` step 4: basic library support This is the next step after https://github.com/rust-lang/rust/pull/121926, another portion of https://github.com/rust-lang/rust/pull/114607 Tracking issue: https://github.com/rust-lang/rust/issues/116909 This PR adds the most basic operations to `f16` and `f128` that get lowered as LLVM intrinsics. This is a very small step but it seemed reasonable enough to add unopinionated basic operations before the larger modules that are built on top of them. r? ```@Amanieu``` since you were pretty involved in the RFC cc ```@compiler-errors``` ```@rustbot``` label +T-libs-api +S-blocked +F-f16_and_f128
This commit is contained in:
commit
aac3f24054
@ -227,13 +227,10 @@ mod impls {
|
||||
impl_clone! {
|
||||
usize u8 u16 u32 u64 u128
|
||||
isize i8 i16 i32 i64 i128
|
||||
f32 f64
|
||||
f16 f32 f64 f128
|
||||
bool char
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
impl_clone! { f16 f128 }
|
||||
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
impl Clone for ! {
|
||||
#[inline]
|
||||
|
@ -1497,12 +1497,9 @@ mod impls {
|
||||
}
|
||||
|
||||
partial_eq_impl! {
|
||||
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
|
||||
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
partial_eq_impl! { f16 f128 }
|
||||
|
||||
macro_rules! eq_impl {
|
||||
($($t:ty)*) => ($(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -1553,10 +1550,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
|
||||
partial_ord_impl! { f32 f64 }
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
partial_ord_impl! { f16 f128 }
|
||||
partial_ord_impl! { f16 f32 f64 f128 }
|
||||
|
||||
macro_rules! ord_impl {
|
||||
($($t:ty)*) => ($(
|
||||
|
@ -34,8 +34,10 @@ macro_rules! impl_float_to_int {
|
||||
}
|
||||
}
|
||||
|
||||
impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
|
||||
|
||||
// Conversion traits for primitive integer and float types
|
||||
// Conversions T -> T are covered by a blanket impl and therefore excluded
|
||||
@ -163,7 +165,12 @@ impl_from!(u16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
|
||||
impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
// float -> float
|
||||
impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
|
||||
|
||||
macro_rules! impl_float_from_bool {
|
||||
($float:ty) => {
|
||||
|
@ -11,5 +11,7 @@ macro_rules! floating {
|
||||
};
|
||||
}
|
||||
|
||||
floating! { f16 }
|
||||
floating! { f32 }
|
||||
floating! { f64 }
|
||||
floating! { f128 }
|
||||
|
@ -200,8 +200,6 @@
|
||||
//
|
||||
// Language features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(not(bootstrap), feature(f128))]
|
||||
#![cfg_attr(not(bootstrap), feature(f16))]
|
||||
#![feature(abi_unadjusted)]
|
||||
#![feature(adt_const_params)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
@ -226,6 +224,8 @@
|
||||
#![feature(doc_notable_trait)]
|
||||
#![feature(effects)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(freeze_impls)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(generic_arg_infer)]
|
||||
@ -347,6 +347,10 @@ pub mod u8;
|
||||
#[path = "num/shells/usize.rs"]
|
||||
pub mod usize;
|
||||
|
||||
#[path = "num/f128.rs"]
|
||||
pub mod f128;
|
||||
#[path = "num/f16.rs"]
|
||||
pub mod f16;
|
||||
#[path = "num/f32.rs"]
|
||||
pub mod f32;
|
||||
#[path = "num/f64.rs"]
|
||||
|
@ -422,17 +422,11 @@ marker_impls! {
|
||||
Copy for
|
||||
usize, u8, u16, u32, u64, u128,
|
||||
isize, i8, i16, i32, i64, i128,
|
||||
f32, f64,
|
||||
f16, f32, f64, f128,
|
||||
bool, char,
|
||||
{T: ?Sized} *const T,
|
||||
{T: ?Sized} *mut T,
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
marker_impls! {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
Copy for
|
||||
f16, f128,
|
||||
}
|
||||
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
|
16
library/core/src/num/f128.rs
Normal file
16
library/core/src/num/f128.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! Constants for the `f128` quadruple-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f128` primitive type][f128].*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
//!
|
||||
//! For the constants defined directly in this module
|
||||
//! (as distinct from those defined in the `consts` sub-module),
|
||||
//! new code should instead use the associated constants
|
||||
//! defined directly on the `f128` type.
|
||||
|
||||
#![unstable(feature = "f128", issue = "116909")]
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub mod consts {}
|
16
library/core/src/num/f16.rs
Normal file
16
library/core/src/num/f16.rs
Normal file
@ -0,0 +1,16 @@
|
||||
//! Constants for the `f16` half-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f16` primitive type][f16].*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
//!
|
||||
//! For the constants defined directly in this module
|
||||
//! (as distinct from those defined in the `consts` sub-module),
|
||||
//! new code should instead use the associated constants
|
||||
//! defined directly on the `f16` type.
|
||||
|
||||
#![unstable(feature = "f16", issue = "116909")]
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub mod consts {}
|
@ -109,7 +109,7 @@ macro_rules! add_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The subtraction operator `-`.
|
||||
///
|
||||
@ -218,7 +218,7 @@ macro_rules! sub_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The multiplication operator `*`.
|
||||
///
|
||||
@ -348,7 +348,7 @@ macro_rules! mul_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The division operator `/`.
|
||||
///
|
||||
@ -506,7 +506,7 @@ macro_rules! div_impl_float {
|
||||
)*)
|
||||
}
|
||||
|
||||
div_impl_float! { f32 f64 }
|
||||
div_impl_float! { f16 f32 f64 f128 }
|
||||
|
||||
/// The remainder operator `%`.
|
||||
///
|
||||
@ -623,7 +623,7 @@ macro_rules! rem_impl_float {
|
||||
)*)
|
||||
}
|
||||
|
||||
rem_impl_float! { f32 f64 }
|
||||
rem_impl_float! { f16 f32 f64 f128 }
|
||||
|
||||
/// The unary negation operator `-`.
|
||||
///
|
||||
@ -698,7 +698,7 @@ macro_rules! neg_impl {
|
||||
)*)
|
||||
}
|
||||
|
||||
neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The addition assignment operator `+=`.
|
||||
///
|
||||
@ -765,7 +765,7 @@ macro_rules! add_assign_impl {
|
||||
)+)
|
||||
}
|
||||
|
||||
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The subtraction assignment operator `-=`.
|
||||
///
|
||||
@ -832,7 +832,7 @@ macro_rules! sub_assign_impl {
|
||||
)+)
|
||||
}
|
||||
|
||||
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The multiplication assignment operator `*=`.
|
||||
///
|
||||
@ -890,7 +890,7 @@ macro_rules! mul_assign_impl {
|
||||
)+)
|
||||
}
|
||||
|
||||
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The division assignment operator `/=`.
|
||||
///
|
||||
@ -947,7 +947,7 @@ macro_rules! div_assign_impl {
|
||||
)+)
|
||||
}
|
||||
|
||||
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
||||
/// The remainder assignment operator `%=`.
|
||||
///
|
||||
@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl {
|
||||
)+)
|
||||
}
|
||||
|
||||
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
|
||||
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
|
||||
|
@ -1074,7 +1074,22 @@ mod prim_tuple {}
|
||||
#[doc(hidden)]
|
||||
impl<T> (T,) {}
|
||||
|
||||
#[rustc_doc_primitive = "f16"]
|
||||
#[doc(alias = "half")]
|
||||
/// A 16-bit floating point type (specifically, the "binary16" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`prim@f32`] but has decreased precision because it uses half as many
|
||||
/// bits. Please see [the documentation for [`prim@f32`] or [Wikipedia on
|
||||
/// half-precision values][wikipedia] for more information.
|
||||
///
|
||||
/// *[See also the `std::f16::consts` module](crate::f16::consts).*
|
||||
///
|
||||
/// [wikipedia]: https://en.wikipedia.org/wiki/Half-precision_floating-point_format
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
mod prim_f16 {}
|
||||
|
||||
#[rustc_doc_primitive = "f32"]
|
||||
#[doc(alias = "single")]
|
||||
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
|
||||
@ -1143,6 +1158,7 @@ impl<T> (T,) {}
|
||||
mod prim_f32 {}
|
||||
|
||||
#[rustc_doc_primitive = "f64"]
|
||||
#[doc(alias = "double")]
|
||||
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`f32`], but has increased
|
||||
@ -1157,6 +1173,20 @@ mod prim_f32 {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
mod prim_f64 {}
|
||||
|
||||
#[rustc_doc_primitive = "f128"]
|
||||
#[doc(alias = "quad")]
|
||||
/// A 128-bit floating point type (specifically, the "binary128" type defined in IEEE 754-2008).
|
||||
///
|
||||
/// This type is very similar to [`prim@f32`] and [`prim@f64`], but has increased precision by using twice
|
||||
/// as many bits as `f64`. Please see [the documentation for [`prim@f32`] or [Wikipedia on
|
||||
/// quad-precision values][wikipedia] for more information.
|
||||
///
|
||||
/// *[See also the `std::f128::consts` module](crate::f128::consts).*
|
||||
///
|
||||
/// [wikipedia]: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
mod prim_f128 {}
|
||||
|
||||
#[rustc_doc_primitive = "i8"]
|
||||
//
|
||||
/// The 8-bit signed integer type.
|
||||
|
11
library/std/src/f128.rs
Normal file
11
library/std/src/f128.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//! Constants for the `f128` double-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f128` primitive type](primitive@f128).*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub use core::f128::consts;
|
40
library/std/src/f128/tests.rs
Normal file
40
library/std/src/f128/tests.rs
Normal file
@ -0,0 +1,40 @@
|
||||
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
|
||||
|
||||
/// Smallest number
|
||||
const TINY_BITS: u128 = 0x1;
|
||||
/// Next smallest number
|
||||
const TINY_UP_BITS: u128 = 0x2;
|
||||
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
|
||||
const MAX_DOWN_BITS: u128 = 0x7ffeffffffffffffffffffffffffffff;
|
||||
/// Zeroed exponent, full significant
|
||||
const LARGEST_SUBNORMAL_BITS: u128 = 0x0000ffffffffffffffffffffffffffff;
|
||||
/// Exponent = 0b1, zeroed significand
|
||||
const SMALLEST_NORMAL_BITS: u128 = 0x00010000000000000000000000000000;
|
||||
/// First pattern over the mantissa
|
||||
const NAN_MASK1: u128 = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa;
|
||||
/// Second pattern over the mantissa
|
||||
const NAN_MASK2: u128 = 0x00005555555555555555555555555555;
|
||||
|
||||
/// Compare by value
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f128_eq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f128, &f128) = (&$a, &$b);
|
||||
assert_eq!(*l, *r, "\na: {:#0130x}\nb: {:#0130x}", l.to_bits(), r.to_bits())
|
||||
};
|
||||
}
|
||||
|
||||
/// Compare by representation
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f128_biteq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f128, &f128) = (&$a, &$b);
|
||||
let lb = l.to_bits();
|
||||
let rb = r.to_bits();
|
||||
assert_eq!(
|
||||
lb, rb,
|
||||
"float {:?} is not bitequal to {:?}.\na: {:#0130x}\nb: {:#0130x}",
|
||||
*l, *r, lb, rb
|
||||
);
|
||||
};
|
||||
}
|
11
library/std/src/f16.rs
Normal file
11
library/std/src/f16.rs
Normal file
@ -0,0 +1,11 @@
|
||||
//! Constants for the `f16` double-precision floating point type.
|
||||
//!
|
||||
//! *[See also the `f16` primitive type](primitive@f16).*
|
||||
//!
|
||||
//! Mathematically significant numbers are provided in the `consts` sub-module.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub use core::f16::consts;
|
46
library/std/src/f16/tests.rs
Normal file
46
library/std/src/f16/tests.rs
Normal file
@ -0,0 +1,46 @@
|
||||
#![allow(dead_code)] // FIXME(f16_f128): remove once constants are used
|
||||
|
||||
// We run out of precision pretty quickly with f16
|
||||
const F16_APPROX_L1: f16 = 0.001;
|
||||
const F16_APPROX_L2: f16 = 0.01;
|
||||
const F16_APPROX_L3: f16 = 0.1;
|
||||
const F16_APPROX_L4: f16 = 0.5;
|
||||
|
||||
/// Smallest number
|
||||
const TINY_BITS: u16 = 0x1;
|
||||
/// Next smallest number
|
||||
const TINY_UP_BITS: u16 = 0x2;
|
||||
/// Exponent = 0b11...10, Sifnificand 0b1111..10. Min val > 0
|
||||
const MAX_DOWN_BITS: u16 = 0x7bfe;
|
||||
/// Zeroed exponent, full significant
|
||||
const LARGEST_SUBNORMAL_BITS: u16 = 0x03ff;
|
||||
/// Exponent = 0b1, zeroed significand
|
||||
const SMALLEST_NORMAL_BITS: u16 = 0x0400;
|
||||
/// First pattern over the mantissa
|
||||
const NAN_MASK1: u16 = 0x02aa;
|
||||
/// Second pattern over the mantissa
|
||||
const NAN_MASK2: u16 = 0x0155;
|
||||
|
||||
/// Compare by value
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f16_eq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f16, &f16) = (&$a, &$b);
|
||||
assert_eq!(*l, *r, "\na: {:#018x}\nb: {:#018x}", l.to_bits(), r.to_bits())
|
||||
};
|
||||
}
|
||||
|
||||
/// Compare by representation
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! assert_f16_biteq {
|
||||
($a:expr, $b:expr) => {
|
||||
let (l, r): (&f16, &f16) = (&$a, &$b);
|
||||
let lb = l.to_bits();
|
||||
let rb = r.to_bits();
|
||||
assert_eq!(
|
||||
lb, rb,
|
||||
"float {:?} is not bitequal to {:?}.\na: {:#018x}\nb: {:#018x}",
|
||||
*l, *r, lb, rb
|
||||
);
|
||||
};
|
||||
}
|
@ -283,6 +283,8 @@
|
||||
#![feature(doc_masked)]
|
||||
#![feature(doc_notable_trait)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(f128)]
|
||||
#![feature(f16)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(intra_doc_pointers)]
|
||||
#![feature(lang_items)]
|
||||
@ -558,6 +560,10 @@ pub use core::u8;
|
||||
#[allow(deprecated, deprecated_in_future)]
|
||||
pub use core::usize;
|
||||
|
||||
#[unstable(feature = "f128", issue = "116909")]
|
||||
pub mod f128;
|
||||
#[unstable(feature = "f16", issue = "116909")]
|
||||
pub mod f16;
|
||||
pub mod f32;
|
||||
pub mod f64;
|
||||
|
||||
|
129
tests/codegen/float/f128.rs
Normal file
129
tests/codegen/float/f128.rs
Normal file
@ -0,0 +1,129 @@
|
||||
// Verify that our intrinsics generate the correct LLVM calls for f128
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(f128)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// CHECK-LABEL: i1 @f128_eq(
|
||||
#[no_mangle]
|
||||
pub fn f128_eq(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp oeq fp128 %{{.+}}, %{{.+}}
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_ne(
|
||||
#[no_mangle]
|
||||
pub fn f128_ne(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp une fp128 %{{.+}}, %{{.+}}
|
||||
a != b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_gt(
|
||||
#[no_mangle]
|
||||
pub fn f128_gt(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp ogt fp128 %{{.+}}, %{{.+}}
|
||||
a > b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_ge(
|
||||
#[no_mangle]
|
||||
pub fn f128_ge(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp oge fp128 %{{.+}}, %{{.+}}
|
||||
a >= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_lt(
|
||||
#[no_mangle]
|
||||
pub fn f128_lt(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp olt fp128 %{{.+}}, %{{.+}}
|
||||
a < b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f128_le(
|
||||
#[no_mangle]
|
||||
pub fn f128_le(a: f128, b: f128) -> bool {
|
||||
// CHECK: fcmp ole fp128 %{{.+}}, %{{.+}}
|
||||
a <= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_neg(
|
||||
#[no_mangle]
|
||||
pub fn f128_neg(a: f128) -> f128 {
|
||||
// CHECK: fneg fp128
|
||||
-a
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_add(
|
||||
#[no_mangle]
|
||||
pub fn f128_add(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
|
||||
a + b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_sub(
|
||||
#[no_mangle]
|
||||
pub fn f128_sub(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
|
||||
a - b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_mul(
|
||||
#[no_mangle]
|
||||
pub fn f128_mul(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
|
||||
a * b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_div(
|
||||
#[no_mangle]
|
||||
pub fn f128_div(a: f128, b: f128) -> f128 {
|
||||
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
|
||||
a / b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: fp128 @f128_rem(
|
||||
#[no_mangle]
|
||||
pub fn f128_rem(a: f128, b: f128) -> f128 {
|
||||
// CHECK: frem fp128 %{{.+}}, %{{.+}}
|
||||
a % b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_add_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_add_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a += b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_sub_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_sub_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a -= b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_mul_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_mul_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a *= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_div_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_div_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a /= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f128_rem_assign(
|
||||
#[no_mangle]
|
||||
pub fn f128_rem_assign(a: &mut f128, b: f128) {
|
||||
// CHECK: frem fp128 %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||
*a %= b
|
||||
}
|
129
tests/codegen/float/f16.rs
Normal file
129
tests/codegen/float/f16.rs
Normal file
@ -0,0 +1,129 @@
|
||||
// Verify that our intrinsics generate the correct LLVM calls for f16
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(f16)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// CHECK-LABEL: i1 @f16_eq(
|
||||
#[no_mangle]
|
||||
pub fn f16_eq(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp oeq half %{{.+}}, %{{.+}}
|
||||
a == b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_ne(
|
||||
#[no_mangle]
|
||||
pub fn f16_ne(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp une half %{{.+}}, %{{.+}}
|
||||
a != b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_gt(
|
||||
#[no_mangle]
|
||||
pub fn f16_gt(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp ogt half %{{.+}}, %{{.+}}
|
||||
a > b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_ge(
|
||||
#[no_mangle]
|
||||
pub fn f16_ge(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp oge half %{{.+}}, %{{.+}}
|
||||
a >= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_lt(
|
||||
#[no_mangle]
|
||||
pub fn f16_lt(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp olt half %{{.+}}, %{{.+}}
|
||||
a < b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: i1 @f16_le(
|
||||
#[no_mangle]
|
||||
pub fn f16_le(a: f16, b: f16) -> bool {
|
||||
// CHECK: fcmp ole half %{{.+}}, %{{.+}}
|
||||
a <= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_neg(
|
||||
#[no_mangle]
|
||||
pub fn f16_neg(a: f16) -> f16 {
|
||||
// CHECK: fneg half %{{.+}}
|
||||
-a
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_add(
|
||||
#[no_mangle]
|
||||
pub fn f16_add(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fadd half %{{.+}}, %{{.+}}
|
||||
a + b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_sub(
|
||||
#[no_mangle]
|
||||
pub fn f16_sub(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fsub half %{{.+}}, %{{.+}}
|
||||
a - b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_mul(
|
||||
#[no_mangle]
|
||||
pub fn f16_mul(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fmul half %{{.+}}, %{{.+}}
|
||||
a * b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_div(
|
||||
#[no_mangle]
|
||||
pub fn f16_div(a: f16, b: f16) -> f16 {
|
||||
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
||||
a / b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: half @f16_rem(
|
||||
#[no_mangle]
|
||||
pub fn f16_rem(a: f16, b: f16) -> f16 {
|
||||
// CHECK: frem half %{{.+}}, %{{.+}}
|
||||
a % b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_add_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_add_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fadd half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a += b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_sub_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_sub_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fsub half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a -= b;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_mul_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_mul_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fmul half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a *= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_div_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_div_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a /= b
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @f16_rem_assign(
|
||||
#[no_mangle]
|
||||
pub fn f16_rem_assign(a: &mut f16, b: f16) {
|
||||
// CHECK: frem half %{{.+}}, %{{.+}}
|
||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||
*a %= b
|
||||
}
|
@ -6,15 +6,15 @@ LL | 1 +
|
||||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error[E0277]: cannot add `()` to `{integer}`
|
||||
--> $DIR/issue-11771.rs:8:7
|
||||
@ -24,15 +24,15 @@ LL | 1 +
|
||||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -16,15 +16,15 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
|
||||
|
|
||||
= help: the trait `Add<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -6,15 +6,15 @@ LL | 1 + Some(1);
|
||||
|
|
||||
= help: the trait `Add<Option<{integer}>>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Add<Rhs>`:
|
||||
<&'a f128 as Add<f128>>
|
||||
<&'a f16 as Add<f16>>
|
||||
<&'a f32 as Add<f32>>
|
||||
<&'a f64 as Add<f64>>
|
||||
<&'a i128 as Add<i128>>
|
||||
<&'a i16 as Add<i16>>
|
||||
<&'a i32 as Add<i32>>
|
||||
<&'a i64 as Add<i64>>
|
||||
<&'a i8 as Add<i8>>
|
||||
<&'a isize as Add<isize>>
|
||||
and 48 others
|
||||
and 56 others
|
||||
|
||||
error[E0277]: cannot subtract `Option<{integer}>` from `usize`
|
||||
--> $DIR/binops.rs:3:16
|
||||
@ -37,15 +37,15 @@ LL | 3 * ();
|
||||
|
|
||||
= help: the trait `Mul<()>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Mul<Rhs>`:
|
||||
<&'a f128 as Mul<f128>>
|
||||
<&'a f16 as Mul<f16>>
|
||||
<&'a f32 as Mul<f32>>
|
||||
<&'a f64 as Mul<f64>>
|
||||
<&'a i128 as Mul<i128>>
|
||||
<&'a i16 as Mul<i16>>
|
||||
<&'a i32 as Mul<i32>>
|
||||
<&'a i64 as Mul<i64>>
|
||||
<&'a i8 as Mul<i8>>
|
||||
<&'a isize as Mul<isize>>
|
||||
and 49 others
|
||||
and 57 others
|
||||
|
||||
error[E0277]: cannot divide `{integer}` by `&str`
|
||||
--> $DIR/binops.rs:5:7
|
||||
@ -55,15 +55,15 @@ LL | 4 / "";
|
||||
|
|
||||
= help: the trait `Div<&str>` is not implemented for `{integer}`
|
||||
= help: the following other types implement trait `Div<Rhs>`:
|
||||
<&'a f128 as Div<f128>>
|
||||
<&'a f16 as Div<f16>>
|
||||
<&'a f32 as Div<f32>>
|
||||
<&'a f64 as Div<f64>>
|
||||
<&'a i128 as Div<i128>>
|
||||
<&'a i16 as Div<i16>>
|
||||
<&'a i32 as Div<i32>>
|
||||
<&'a i64 as Div<i64>>
|
||||
<&'a i8 as Div<i8>>
|
||||
<&'a isize as Div<isize>>
|
||||
and 54 others
|
||||
and 62 others
|
||||
|
||||
error[E0277]: can't compare `{integer}` with `String`
|
||||
--> $DIR/binops.rs:6:7
|
||||
|
Loading…
Reference in New Issue
Block a user