Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 454de78

Browse files
committed
Add basic library support for f16 and f128
Implement basic operation traits that get lowered to intrinsics. This includes codegen tests for implemented operations.
1 parent 88bcc79 commit 454de78

File tree

8 files changed

+296
-29
lines changed

8 files changed

+296
-29
lines changed

library/core/src/convert/num.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ macro_rules! impl_float_to_int {
3434
}
3535
}
3636

37+
impl_float_to_int!(f16 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
3738
impl_float_to_int!(f32 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
3839
impl_float_to_int!(f64 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
40+
impl_float_to_int!(f128 => u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
3941

4042
// Conversion traits for primitive integer and float types
4143
// 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"
163165
impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
164166

165167
// float -> float
168+
impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
169+
impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
170+
impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
166171
impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
172+
impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
173+
impl_from!(f64 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);
167174

168175
macro_rules! impl_float_from_bool {
169176
($float:ty) => {

library/core/src/fmt/nofloat.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ macro_rules! floating {
1111
};
1212
}
1313

14+
floating! { f16 }
1415
floating! { f32 }
1516
floating! { f64 }
17+
floating! { f128 }

library/core/src/ops/arith.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ macro_rules! add_impl {
109109
)*)
110110
}
111111

112-
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
112+
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
113113

114114
/// The subtraction operator `-`.
115115
///
@@ -218,7 +218,7 @@ macro_rules! sub_impl {
218218
)*)
219219
}
220220

221-
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
221+
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
222222

223223
/// The multiplication operator `*`.
224224
///
@@ -348,7 +348,7 @@ macro_rules! mul_impl {
348348
)*)
349349
}
350350

351-
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
351+
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
352352

353353
/// The division operator `/`.
354354
///
@@ -506,7 +506,7 @@ macro_rules! div_impl_float {
506506
)*)
507507
}
508508

509-
div_impl_float! { f32 f64 }
509+
div_impl_float! { f16 f32 f64 f128 }
510510

511511
/// The remainder operator `%`.
512512
///
@@ -623,7 +623,7 @@ macro_rules! rem_impl_float {
623623
)*)
624624
}
625625

626-
rem_impl_float! { f32 f64 }
626+
rem_impl_float! { f16 f32 f64 f128 }
627627

628628
/// The unary negation operator `-`.
629629
///
@@ -698,7 +698,7 @@ macro_rules! neg_impl {
698698
)*)
699699
}
700700

701-
neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
701+
neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
702702

703703
/// The addition assignment operator `+=`.
704704
///
@@ -765,7 +765,7 @@ macro_rules! add_assign_impl {
765765
)+)
766766
}
767767

768-
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
768+
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
769769

770770
/// The subtraction assignment operator `-=`.
771771
///
@@ -832,7 +832,7 @@ macro_rules! sub_assign_impl {
832832
)+)
833833
}
834834

835-
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
835+
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
836836

837837
/// The multiplication assignment operator `*=`.
838838
///
@@ -890,7 +890,7 @@ macro_rules! mul_assign_impl {
890890
)+)
891891
}
892892

893-
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
893+
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
894894

895895
/// The division assignment operator `/=`.
896896
///
@@ -947,7 +947,7 @@ macro_rules! div_assign_impl {
947947
)+)
948948
}
949949

950-
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
950+
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
951951

952952
/// The remainder assignment operator `%=`.
953953
///
@@ -1008,4 +1008,4 @@ macro_rules! rem_assign_impl {
10081008
)+)
10091009
}
10101010

1011-
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
1011+
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }

tests/codegen/float/f128.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Verify that our intrinsics generate the correct LLVM calls for f128
2+
3+
#![crate_type = "lib"]
4+
#![feature(f128)]
5+
#![feature(core_intrinsics)]
6+
7+
// CHECK-LABEL: i1 @f128_eq(
8+
#[no_mangle]
9+
pub fn f128_eq(a: f128, b: f128) -> bool {
10+
// CHECK: fcmp oeq fp128 %{{.+}}, %{{.+}}
11+
a == b
12+
}
13+
14+
// CHECK-LABEL: i1 @f128_ne(
15+
#[no_mangle]
16+
pub fn f128_ne(a: f128, b: f128) -> bool {
17+
// CHECK: fcmp une fp128 %{{.+}}, %{{.+}}
18+
a != b
19+
}
20+
21+
// CHECK-LABEL: i1 @f128_gt(
22+
#[no_mangle]
23+
pub fn f128_gt(a: f128, b: f128) -> bool {
24+
// CHECK: fcmp ogt fp128 %{{.+}}, %{{.+}}
25+
a > b
26+
}
27+
28+
// CHECK-LABEL: i1 @f128_ge(
29+
#[no_mangle]
30+
pub fn f128_ge(a: f128, b: f128) -> bool {
31+
// CHECK: fcmp oge fp128 %{{.+}}, %{{.+}}
32+
a >= b
33+
}
34+
35+
// CHECK-LABEL: i1 @f128_lt(
36+
#[no_mangle]
37+
pub fn f128_lt(a: f128, b: f128) -> bool {
38+
// CHECK: fcmp olt fp128 %{{.+}}, %{{.+}}
39+
a < b
40+
}
41+
42+
// CHECK-LABEL: i1 @f128_le(
43+
#[no_mangle]
44+
pub fn f128_le(a: f128, b: f128) -> bool {
45+
// CHECK: fcmp ole fp128 %{{.+}}, %{{.+}}
46+
a <= b
47+
}
48+
49+
// CHECK-LABEL: fp128 @f128_neg(
50+
#[no_mangle]
51+
pub fn f128_neg(a: f128) -> f128 {
52+
// CHECK: fneg fp128
53+
-a
54+
}
55+
56+
// CHECK-LABEL: fp128 @f128_add(
57+
#[no_mangle]
58+
pub fn f128_add(a: f128, b: f128) -> f128 {
59+
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
60+
a + b
61+
}
62+
63+
// CHECK-LABEL: fp128 @f128_sub(
64+
#[no_mangle]
65+
pub fn f128_sub(a: f128, b: f128) -> f128 {
66+
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
67+
a - b
68+
}
69+
70+
// CHECK-LABEL: fp128 @f128_mul(
71+
#[no_mangle]
72+
pub fn f128_mul(a: f128, b: f128) -> f128 {
73+
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
74+
a * b
75+
}
76+
77+
// CHECK-LABEL: fp128 @f128_div(
78+
#[no_mangle]
79+
pub fn f128_div(a: f128, b: f128) -> f128 {
80+
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
81+
a / b
82+
}
83+
84+
// CHECK-LABEL: fp128 @f128_rem(
85+
#[no_mangle]
86+
pub fn f128_rem(a: f128, b: f128) -> f128 {
87+
// CHECK: frem fp128 %{{.+}}, %{{.+}}
88+
a % b
89+
}
90+
91+
// CHECK-LABEL: void @f128_add_assign(
92+
#[no_mangle]
93+
pub fn f128_add_assign(a: &mut f128, b: f128) {
94+
// CHECK: fadd fp128 %{{.+}}, %{{.+}}
95+
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
96+
*a += b;
97+
}
98+
99+
// CHECK-LABEL: void @f128_sub_assign(
100+
#[no_mangle]
101+
pub fn f128_sub_assign(a: &mut f128, b: f128) {
102+
// CHECK: fsub fp128 %{{.+}}, %{{.+}}
103+
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
104+
*a -= b;
105+
}
106+
107+
// CHECK-LABEL: void @f128_mul_assign(
108+
#[no_mangle]
109+
pub fn f128_mul_assign(a: &mut f128, b: f128) {
110+
// CHECK: fmul fp128 %{{.+}}, %{{.+}}
111+
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
112+
*a *= b
113+
}
114+
115+
// CHECK-LABEL: void @f128_div_assign(
116+
#[no_mangle]
117+
pub fn f128_div_assign(a: &mut f128, b: f128) {
118+
// CHECK: fdiv fp128 %{{.+}}, %{{.+}}
119+
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
120+
*a /= b
121+
}
122+
123+
// CHECK-LABEL: void @f128_rem_assign(
124+
#[no_mangle]
125+
pub fn f128_rem_assign(a: &mut f128, b: f128) {
126+
// CHECK: frem fp128 %{{.+}}, %{{.+}}
127+
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
128+
*a %= b
129+
}

tests/codegen/float/f16.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Verify that our intrinsics generate the correct LLVM calls for f16
2+
3+
#![crate_type = "lib"]
4+
#![feature(f16)]
5+
#![feature(core_intrinsics)]
6+
7+
// CHECK-LABEL: i1 @f16_eq(
8+
#[no_mangle]
9+
pub fn f16_eq(a: f16, b: f16) -> bool {
10+
// CHECK: fcmp oeq half %{{.+}}, %{{.+}}
11+
a == b
12+
}
13+
14+
// CHECK-LABEL: i1 @f16_ne(
15+
#[no_mangle]
16+
pub fn f16_ne(a: f16, b: f16) -> bool {
17+
// CHECK: fcmp une half %{{.+}}, %{{.+}}
18+
a != b
19+
}
20+
21+
// CHECK-LABEL: i1 @f16_gt(
22+
#[no_mangle]
23+
pub fn f16_gt(a: f16, b: f16) -> bool {
24+
// CHECK: fcmp ogt half %{{.+}}, %{{.+}}
25+
a > b
26+
}
27+
28+
// CHECK-LABEL: i1 @f16_ge(
29+
#[no_mangle]
30+
pub fn f16_ge(a: f16, b: f16) -> bool {
31+
// CHECK: fcmp oge half %{{.+}}, %{{.+}}
32+
a >= b
33+
}
34+
35+
// CHECK-LABEL: i1 @f16_lt(
36+
#[no_mangle]
37+
pub fn f16_lt(a: f16, b: f16) -> bool {
38+
// CHECK: fcmp olt half %{{.+}}, %{{.+}}
39+
a < b
40+
}
41+
42+
// CHECK-LABEL: i1 @f16_le(
43+
#[no_mangle]
44+
pub fn f16_le(a: f16, b: f16) -> bool {
45+
// CHECK: fcmp ole half %{{.+}}, %{{.+}}
46+
a <= b
47+
}
48+
49+
// CHECK-LABEL: half @f16_neg(
50+
#[no_mangle]
51+
pub fn f16_neg(a: f16) -> f16 {
52+
// CHECK: fneg half %{{.+}}
53+
-a
54+
}
55+
56+
// CHECK-LABEL: half @f16_add(
57+
#[no_mangle]
58+
pub fn f16_add(a: f16, b: f16) -> f16 {
59+
// CHECK: fadd half %{{.+}}, %{{.+}}
60+
a + b
61+
}
62+
63+
// CHECK-LABEL: half @f16_sub(
64+
#[no_mangle]
65+
pub fn f16_sub(a: f16, b: f16) -> f16 {
66+
// CHECK: fsub half %{{.+}}, %{{.+}}
67+
a - b
68+
}
69+
70+
// CHECK-LABEL: half @f16_mul(
71+
#[no_mangle]
72+
pub fn f16_mul(a: f16, b: f16) -> f16 {
73+
// CHECK: fmul half %{{.+}}, %{{.+}}
74+
a * b
75+
}
76+
77+
// CHECK-LABEL: half @f16_div(
78+
#[no_mangle]
79+
pub fn f16_div(a: f16, b: f16) -> f16 {
80+
// CHECK: fdiv half %{{.+}}, %{{.+}}
81+
a / b
82+
}
83+
84+
// CHECK-LABEL: half @f16_rem(
85+
#[no_mangle]
86+
pub fn f16_rem(a: f16, b: f16) -> f16 {
87+
// CHECK: frem half %{{.+}}, %{{.+}}
88+
a % b
89+
}
90+
91+
// CHECK-LABEL: void @f16_add_assign(
92+
#[no_mangle]
93+
pub fn f16_add_assign(a: &mut f16, b: f16) {
94+
// CHECK: fadd half %{{.+}}, %{{.+}}
95+
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
96+
*a += b;
97+
}
98+
99+
// CHECK-LABEL: void @f16_sub_assign(
100+
#[no_mangle]
101+
pub fn f16_sub_assign(a: &mut f16, b: f16) {
102+
// CHECK: fsub half %{{.+}}, %{{.+}}
103+
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
104+
*a -= b;
105+
}
106+
107+
// CHECK-LABEL: void @f16_mul_assign(
108+
#[no_mangle]
109+
pub fn f16_mul_assign(a: &mut f16, b: f16) {
110+
// CHECK: fmul half %{{.+}}, %{{.+}}
111+
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
112+
*a *= b
113+
}
114+
115+
// CHECK-LABEL: void @f16_div_assign(
116+
#[no_mangle]
117+
pub fn f16_div_assign(a: &mut f16, b: f16) {
118+
// CHECK: fdiv half %{{.+}}, %{{.+}}
119+
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
120+
*a /= b
121+
}
122+
123+
// CHECK-LABEL: void @f16_rem_assign(
124+
#[no_mangle]
125+
pub fn f16_rem_assign(a: &mut f16, b: f16) {
126+
// CHECK: frem half %{{.+}}, %{{.+}}
127+
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
128+
*a %= b
129+
}

0 commit comments

Comments
 (0)