Skip to content

Commit 518f848

Browse files
committed
Add llvm cg tests for f16
Add f128 tests, both codegen tests passing Add more to codegen tests Fix intrinsics and add tests for them Get a lot more f16 and f128 tests passing Update a few more f128 tests Disable rust vs ieee parse checking
1 parent fc8be3d commit 518f848

File tree

8 files changed

+473
-105
lines changed

8 files changed

+473
-105
lines changed

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,12 @@ impl<'ll> CodegenCx<'ll, '_> {
727727
ifn!("llvm.debugtrap", fn() -> void);
728728
ifn!("llvm.frameaddress", fn(t_i32) -> ptr);
729729

730-
ifn!("llvm.powi.f16", fn(t_f32, t_i32) -> t_f16);
730+
ifn!("llvm.powi.f16", fn(t_f16, t_i32) -> t_f16);
731731
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
732732
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
733733
ifn!("llvm.powi.f128", fn(t_f128, t_i32) -> t_f128);
734734

735-
ifn!("llvm.pow.f16", fn(t_f32, t_f16) -> t_f16);
735+
ifn!("llvm.pow.f16", fn(t_f16, t_f16) -> t_f16);
736736
ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
737737
ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
738738
ifn!("llvm.pow.f128", fn(t_f128, t_f128) -> t_f128);
@@ -777,7 +777,7 @@ impl<'ll> CodegenCx<'ll, '_> {
777777
ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
778778
ifn!("llvm.log2.f128", fn(t_f128) -> t_f128);
779779

780-
ifn!("llvm.fma.f16", fn(t_f32, t_f32, t_f32) -> t_f32);
780+
ifn!("llvm.fma.f16", fn(t_f16, t_f16, t_f16) -> t_f16);
781781
ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
782782
ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
783783
ifn!("llvm.fma.f128", fn(t_f128, t_f128, t_f128) -> t_f128);

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ fn get_simple_intrinsic<'ll>(
107107
sym::nearbyintf16 => "llvm.nearbyint.f16",
108108
sym::nearbyintf32 => "llvm.nearbyint.f32",
109109
sym::nearbyintf64 => "llvm.nearbyint.f64",
110-
sym::nearbyintf128 => "llvm.nearbyint.128",
110+
sym::nearbyintf128 => "llvm.nearbyint.f128",
111111
sym::roundf16 => "llvm.round.f16",
112112
sym::roundf32 => "llvm.round.f32",
113113
sym::roundf64 => "llvm.round.f64",

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -989,17 +989,18 @@ fn parse_check_f16(_num: &str, _f: Half) -> Option<()> {
989989
}
990990

991991
#[cfg(not(bootstrap))]
992-
fn parse_check_f128(num: &str, f: Quad) -> Option<()> {
993-
let Ok(rust_f) = num.parse::<f128>() else { return None };
994-
995-
assert!(
996-
u128::from(rust_f.to_bits()) == f.to_bits(),
997-
"apfloat::ieee::Quad gave a different result for `{num}`: \
998-
{f} ({:#x}) vs Rust's {} ({:#x})",
999-
f.to_bits(),
1000-
Quad::from_bits(rust_f.to_bits().into()),
1001-
rust_f.to_bits()
1002-
);
992+
fn parse_check_f128(_num: &str, _f: Quad) -> Option<()> {
993+
// TODO: reenable this once our f128 FromStr doesn't just use f64
994+
// let Ok(rust_f) = num.parse::<f128>() else { return None };
995+
996+
// assert!(
997+
// u128::from(rust_f.to_bits()) == f.to_bits(),
998+
// "apfloat::ieee::Quad gave a different result for `{num}`: \
999+
// {f} ({:#x}) vs Rust's {} ({:#x})",
1000+
// f.to_bits(),
1001+
// Quad::from_bits(rust_f.to_bits().into()),
1002+
// rust_f.to_bits()
1003+
// );
10031004

10041005
Some(())
10051006
}

library/core/src/num/f128.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,15 @@ impl f128 {
127127

128128
/// Smallest finite `f128` value.
129129
#[unstable(feature = "f128", issue = "none")]
130-
pub const MIN: f128 = -1.18973e+4932_f128;
130+
pub const MIN: f128 = 1.1897314953572317650857593266280070162e+4932_f128;
131131

132132
/// Smallest positive normal `f128` value.
133133
#[unstable(feature = "f128", issue = "none")]
134134
pub const MIN_POSITIVE: f128 = 1.94652e-4855_f128;
135135

136136
/// Largest finite `f128` value.
137137
#[unstable(feature = "f128", issue = "none")]
138-
pub const MAX: f128 = 1.18973e+4932_f128;
138+
pub const MAX: f128 = 1.1897314953572317650857593266280070162e+4932_f128;
139139

140140
/// One greater than the minimum possible normal power of 2 exponent.
141141
#[unstable(feature = "f128", issue = "none")]

library/std/src/tests/f128_tests.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ fn test_is_normal() {
158158
assert!(!zero.is_normal());
159159
assert!(!neg_zero.is_normal());
160160
assert!(1f128.is_normal());
161-
assert!(1e-37f128.is_normal());
162-
assert!(!1e-38f128.is_normal());
161+
assert!(1e-4931_f128.is_normal());
162+
assert!(!1e-4932_f128.is_normal());
163163
}
164164

165165
#[test]
@@ -175,8 +175,8 @@ fn test_classify() {
175175
assert_eq!(zero.classify(), Fp::Zero);
176176
assert_eq!(neg_zero.classify(), Fp::Zero);
177177
assert_eq!(1f128.classify(), Fp::Normal);
178-
assert_eq!(1e-37f128.classify(), Fp::Normal);
179-
assert_eq!(1e-38f128.classify(), Fp::Subnormal);
178+
assert_eq!(1e-4931_f128.classify(), Fp::Normal);
179+
assert_eq!(1e-4932_f128.classify(), Fp::Subnormal);
180180
}
181181

182182
#[test]
@@ -499,6 +499,7 @@ fn test_ln() {
499499
assert_approx_eq!(1.0f128.exp().ln(), 1.0);
500500
assert!(nan.ln().is_nan());
501501
assert_eq!(inf.ln(), inf);
502+
dbg!(neg_inf.ln(), neg_inf.ln().to_bits());
502503
assert!(neg_inf.ln().is_nan());
503504
assert!((-2.3f128).ln().is_nan());
504505
assert_eq!((-0.0f128).ln(), neg_inf);
@@ -581,6 +582,7 @@ fn test_to_radians() {
581582
assert_eq!(0.0f128.to_radians(), 0.0);
582583
assert_approx_eq!(154.6f128.to_radians(), 2.698279);
583584
assert_approx_eq!((-332.31f128).to_radians(), -5.799903);
585+
dbg!(180.0f128.to_radians().to_bits(), pi.to_bits());
584586
assert_eq!(180.0f128.to_radians(), pi);
585587
assert!(nan.to_radians().is_nan());
586588
assert_eq!(inf.to_radians(), inf);

library/std/src/tests/f16_tests.rs

Lines changed: 74 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ use crate::f16::consts;
22
use crate::num::FpCategory as Fp;
33
use crate::num::*;
44

5-
const F16_APPROX: f16 = 0.001;
5+
// We run out of precision pretty quickly with f16
6+
const F16_APPROX_L1: f16 = 0.001;
7+
const F16_APPROX_L2: f16 = 0.01;
8+
const F16_APPROX_L3: f16 = 0.1;
9+
const F16_APPROX_L4: f16 = 0.5;
610

711
#[test]
812
fn test_num_f16() {
@@ -160,8 +164,8 @@ fn test_is_normal() {
160164
assert!(!zero.is_normal());
161165
assert!(!neg_zero.is_normal());
162166
assert!(1f16.is_normal());
163-
assert!(1e-37f16.is_normal());
164-
assert!(!1e-38f16.is_normal());
167+
assert!(1e-4f16.is_normal());
168+
assert!(!1e-5f16.is_normal());
165169
}
166170

167171
#[test]
@@ -177,8 +181,8 @@ fn test_classify() {
177181
assert_eq!(zero.classify(), Fp::Zero);
178182
assert_eq!(neg_zero.classify(), Fp::Zero);
179183
assert_eq!(1f16.classify(), Fp::Normal);
180-
assert_eq!(1e-37f16.classify(), Fp::Normal);
181-
assert_eq!(1e-38f16.classify(), Fp::Subnormal);
184+
assert_eq!(1e-4f16.classify(), Fp::Normal);
185+
assert_eq!(1e-5f16.classify(), Fp::Subnormal);
182186
}
183187

184188
#[test]
@@ -255,16 +259,16 @@ fn test_trunc() {
255259

256260
#[test]
257261
fn test_fract() {
258-
assert_approx_eq!(1.0f16.fract(), 0.0f16, F16_APPROX);
259-
assert_approx_eq!(1.3f16.fract(), 0.3f16, F16_APPROX);
260-
assert_approx_eq!(1.5f16.fract(), 0.5f16, F16_APPROX);
261-
assert_approx_eq!(1.7f16.fract(), 0.7f16, F16_APPROX);
262-
assert_approx_eq!(0.0f16.fract(), 0.0f16, F16_APPROX);
263-
assert_approx_eq!((-0.0f16).fract(), -0.0f16, F16_APPROX);
264-
assert_approx_eq!((-1.0f16).fract(), -0.0f16, F16_APPROX);
265-
assert_approx_eq!((-1.3f16).fract(), -0.3f16, F16_APPROX);
266-
assert_approx_eq!((-1.5f16).fract(), -0.5f16, F16_APPROX);
267-
assert_approx_eq!((-1.7f16).fract(), -0.7f16, F16_APPROX);
262+
assert_approx_eq!(1.0f16.fract(), 0.0f16, F16_APPROX_L1);
263+
assert_approx_eq!(1.3f16.fract(), 0.3f16, F16_APPROX_L1);
264+
assert_approx_eq!(1.5f16.fract(), 0.5f16, F16_APPROX_L1);
265+
assert_approx_eq!(1.7f16.fract(), 0.7f16, F16_APPROX_L1);
266+
assert_approx_eq!(0.0f16.fract(), 0.0f16, F16_APPROX_L1);
267+
assert_approx_eq!((-0.0f16).fract(), -0.0f16, F16_APPROX_L1);
268+
assert_approx_eq!((-1.0f16).fract(), -0.0f16, F16_APPROX_L1);
269+
assert_approx_eq!((-1.3f16).fract(), -0.3f16, F16_APPROX_L1);
270+
assert_approx_eq!((-1.5f16).fract(), -0.5f16, F16_APPROX_L1);
271+
assert_approx_eq!((-1.7f16).fract(), -0.7f16, F16_APPROX_L1);
268272
}
269273

270274
#[test]
@@ -402,10 +406,10 @@ fn test_mul_add() {
402406
let nan: f16 = f16::NAN;
403407
let inf: f16 = f16::INFINITY;
404408
let neg_inf: f16 = f16::NEG_INFINITY;
405-
assert_approx_eq!(12.3f16.mul_add(4.5, 6.7), 62.05, F16_APPROX);
406-
assert_approx_eq!((-12.3f16).mul_add(-4.5, -6.7), 48.65, F16_APPROX);
407-
assert_approx_eq!(0.0f16.mul_add(8.9, 1.2), 1.2, F16_APPROX);
408-
assert_approx_eq!(3.4f16.mul_add(-0.0, 5.6), 5.6, F16_APPROX);
409+
assert_approx_eq!(12.3f16.mul_add(4.5, 6.7), 62.05, F16_APPROX_L3);
410+
assert_approx_eq!((-12.3f16).mul_add(-4.5, -6.7), 48.65, F16_APPROX_L4);
411+
assert_approx_eq!(0.0f16.mul_add(8.9, 1.2), 1.2, F16_APPROX_L2);
412+
assert_approx_eq!(3.4f16.mul_add(-0.0, 5.6), 5.6, F16_APPROX_L2);
409413
assert!(nan.mul_add(7.8, 9.0).is_nan());
410414
assert_eq!(inf.mul_add(7.8, 9.0), inf);
411415
assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
@@ -427,48 +431,35 @@ fn test_recip() {
427431
assert_eq!(neg_inf.recip(), 0.0);
428432
}
429433

430-
// TODO: powi gives me LLVM errors:
431-
//
432-
// Both operands to a binary operator are not of the same type!
433-
// %10 = fadd float %9, half 0xHC8CE
434-
// Call parameter type does not match function signature!
435-
// %10 = fadd float %9, half 0xHC8CE
436-
// half %11 = tail call half @llvm.fabs.f16(float %10)
437-
// Intrinsic has incorrect argument type!
438-
// ptr @llvm.powi.f16
439-
// in function _ZN3std3f165tests9test_powi17h5053d7d11c8cb05dE
440-
// LLVM ERROR: Broken function found, compilation aborted!
441-
//
442-
// #[test]
443-
// fn test_powi() {
444-
// let nan: f16 = f16::NAN;
445-
// let inf: f16 = f16::INFINITY;
446-
// let neg_inf: f16 = f16::NEG_INFINITY;
447-
// assert_eq!(1.0f16.powi(1), 1.0);
448-
// assert_approx_eq!((-3.1f16).powi(2), 9.61);
449-
// assert_approx_eq!(5.9f16.powi(-2), 0.028727);
450-
// assert_eq!(8.3f16.powi(0), 1.0);
451-
// assert!(nan.powi(2).is_nan());
452-
// assert_eq!(inf.powi(3), inf);
453-
// assert_eq!(neg_inf.powi(2), inf);
454-
// }
434+
#[test]
435+
fn test_powi() {
436+
let nan: f16 = f16::NAN;
437+
let inf: f16 = f16::INFINITY;
438+
let neg_inf: f16 = f16::NEG_INFINITY;
439+
assert_eq!(1.0f16.powi(1), 1.0);
440+
assert_approx_eq!((-3.1f16).powi(2), 9.61);
441+
assert_approx_eq!(5.9f16.powi(-2), 0.028727);
442+
assert_eq!(8.3f16.powi(0), 1.0);
443+
assert!(nan.powi(2).is_nan());
444+
assert_eq!(inf.powi(3), inf);
445+
assert_eq!(neg_inf.powi(2), inf);
446+
}
455447

456-
// TODO: LLVM errors
457-
// #[test]
458-
// fn test_powf() {
459-
// let nan: f16 = f16::NAN;
460-
// let inf: f16 = f16::INFINITY;
461-
// let neg_inf: f16 = f16::NEG_INFINITY;
462-
// assert_eq!(1.0f16.powf(1.0), 1.0);
463-
// assert_approx_eq!(3.4f16.powf(4.5), 246.408218);
464-
// assert_approx_eq!(2.7f16.powf(-3.2), 0.041652);
465-
// assert_approx_eq!((-3.1f16).powf(2.0), 9.61);
466-
// assert_approx_eq!(5.9f16.powf(-2.0), 0.028727);
467-
// assert_eq!(8.3f16.powf(0.0), 1.0);
468-
// assert!(nan.powf(2.0).is_nan());
469-
// assert_eq!(inf.powf(2.0), inf);
470-
// assert_eq!(neg_inf.powf(3.0), neg_inf);
471-
// }
448+
#[test]
449+
fn test_powf() {
450+
let nan: f16 = f16::NAN;
451+
let inf: f16 = f16::INFINITY;
452+
let neg_inf: f16 = f16::NEG_INFINITY;
453+
assert_eq!(1.0f16.powf(1.0), 1.0);
454+
assert_approx_eq!(3.4f16.powf(4.5), 246.408218, F16_APPROX_L4);
455+
assert_approx_eq!(2.7f16.powf(-3.2), 0.041652, F16_APPROX_L1);
456+
assert_approx_eq!((-3.1f16).powf(2.0), 9.61, F16_APPROX_L1);
457+
assert_approx_eq!(5.9f16.powf(-2.0), 0.028727, F16_APPROX_L1);
458+
assert_eq!(8.3f16.powf(0.0), 1.0);
459+
assert!(nan.powf(2.0).is_nan());
460+
assert_eq!(inf.powf(2.0), inf);
461+
assert_eq!(neg_inf.powf(3.0), neg_inf);
462+
}
472463

473464
#[test]
474465
fn test_sqrt_domain() {
@@ -546,9 +537,9 @@ fn test_log2() {
546537
let nan: f16 = f16::NAN;
547538
let inf: f16 = f16::INFINITY;
548539
let neg_inf: f16 = f16::NEG_INFINITY;
549-
assert_approx_eq!(10.0f16.log2(), 3.321928, F16_APPROX);
550-
assert_approx_eq!(2.3f16.log2(), 1.201634, F16_APPROX);
551-
assert_approx_eq!(1.0f16.exp().log2(), 1.442695, F16_APPROX);
540+
assert_approx_eq!(10.0f16.log2(), 3.321928, F16_APPROX_L1);
541+
assert_approx_eq!(2.3f16.log2(), 1.201634, F16_APPROX_L1);
542+
assert_approx_eq!(1.0f16.exp().log2(), 1.442695, F16_APPROX_L1);
552543
assert!(nan.log2().is_nan());
553544
assert_eq!(inf.log2(), inf);
554545
assert!(neg_inf.log2().is_nan());
@@ -581,13 +572,12 @@ fn test_to_degrees() {
581572
let inf: f16 = f16::INFINITY;
582573
let neg_inf: f16 = f16::NEG_INFINITY;
583574
assert_eq!(0.0f16.to_degrees(), 0.0);
584-
// Loss of precision here, increase our bounds
585-
assert_approx_eq!((-5.8f16).to_degrees(), -332.315521, F16_APPROX * 1.1);
575+
assert_approx_eq!((-5.8f16).to_degrees(), -332.315521, F16_APPROX_L4);
586576
assert_eq!(pi.to_degrees(), 180.0);
587577
assert!(nan.to_degrees().is_nan());
588578
assert_eq!(inf.to_degrees(), inf);
589579
assert_eq!(neg_inf.to_degrees(), neg_inf);
590-
assert_eq!(1_f16.to_degrees(), 57.2957795130823208767981548141051703);
580+
assert_approx_eq!(1_f16.to_degrees(), 57.29577951, F16_APPROX_L3);
591581
}
592582

593583
#[test]
@@ -597,15 +587,15 @@ fn test_to_radians() {
597587
let inf: f16 = f16::INFINITY;
598588
let neg_inf: f16 = f16::NEG_INFINITY;
599589
assert_eq!(0.0f16.to_radians(), 0.0);
600-
// Loss of precision here, increase our bounds
601-
assert_approx_eq!(154.6f16.to_radians(), 2.698279, F16_APPROX * 1.1);
602-
assert_approx_eq!((-332.31f16).to_radians(), -5.799903, F16_APPROX);
603-
assert_eq!(180.0f16.to_radians(), pi);
590+
assert_approx_eq!(154.6f16.to_radians(), 2.698279, F16_APPROX_L3);
591+
assert_approx_eq!((-332.31f16).to_radians(), -5.799903, F16_APPROX_L3);
592+
assert_approx_eq!(180.0f16.to_radians(), pi, F16_APPROX_L3);
604593
assert!(nan.to_radians().is_nan());
605594
assert_eq!(inf.to_radians(), inf);
606595
assert_eq!(neg_inf.to_radians(), neg_inf);
607596
}
608597

598+
// Disabled since this relies on cmath
609599
// #[test]
610600
// fn test_asinh() {
611601
// assert_eq!(0.0f16.asinh(), 0.0f16);
@@ -724,20 +714,20 @@ fn test_real_consts() {
724714
let ln_2: f16 = consts::LN_2;
725715
let ln_10: f16 = consts::LN_10;
726716

727-
assert_approx_eq!(frac_pi_2, pi / 2f16, F16_APPROX);
728-
assert_approx_eq!(frac_pi_3, pi / 3f16, F16_APPROX);
729-
assert_approx_eq!(frac_pi_4, pi / 4f16, F16_APPROX);
730-
assert_approx_eq!(frac_pi_6, pi / 6f16, F16_APPROX);
731-
assert_approx_eq!(frac_pi_8, pi / 8f16, F16_APPROX);
732-
assert_approx_eq!(frac_1_pi, 1f16 / pi, F16_APPROX);
733-
assert_approx_eq!(frac_2_pi, 2f16 / pi, F16_APPROX);
734-
assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), F16_APPROX);
735-
assert_approx_eq!(sqrt2, 2f16.sqrt(), F16_APPROX);
736-
assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), F16_APPROX);
737-
assert_approx_eq!(log2_e, e.log2(), F16_APPROX);
738-
assert_approx_eq!(log10_e, e.log10(), F16_APPROX);
739-
assert_approx_eq!(ln_2, 2f16.ln(), F16_APPROX);
740-
assert_approx_eq!(ln_10, 10f16.ln(), F16_APPROX);
717+
assert_approx_eq!(frac_pi_2, pi / 2f16, F16_APPROX_L1);
718+
assert_approx_eq!(frac_pi_3, pi / 3f16, F16_APPROX_L1);
719+
assert_approx_eq!(frac_pi_4, pi / 4f16, F16_APPROX_L1);
720+
assert_approx_eq!(frac_pi_6, pi / 6f16, F16_APPROX_L1);
721+
assert_approx_eq!(frac_pi_8, pi / 8f16, F16_APPROX_L1);
722+
assert_approx_eq!(frac_1_pi, 1f16 / pi, F16_APPROX_L1);
723+
assert_approx_eq!(frac_2_pi, 2f16 / pi, F16_APPROX_L1);
724+
assert_approx_eq!(frac_2_sqrtpi, 2f16 / pi.sqrt(), F16_APPROX_L1);
725+
assert_approx_eq!(sqrt2, 2f16.sqrt(), F16_APPROX_L1);
726+
assert_approx_eq!(frac_1_sqrt2, 1f16 / 2f16.sqrt(), F16_APPROX_L1);
727+
assert_approx_eq!(log2_e, e.log2(), F16_APPROX_L1);
728+
assert_approx_eq!(log10_e, e.log10(), F16_APPROX_L1);
729+
assert_approx_eq!(ln_2, 2f16.ln(), F16_APPROX_L1);
730+
assert_approx_eq!(ln_10, 10f16.ln(), F16_APPROX_L1);
741731
}
742732

743733
#[test]

0 commit comments

Comments
 (0)