Skip to content

Commit fc8be3d

Browse files
committed
Change parsing fallbacks
clif build override Enable required features for mir_build Fix parsing modules for new float types Improve wording on different result message Correct some f16/f128 constants Bless UI tests Work on getting tests to pass Get a few more tests passing Bless output with new consts modules Update bug printing Bless tests for CI once again (not sure why these are OK on my local but not on CI) Fix some float tests Fixup implementations of RawFloat Some things to help improve tidy Cover f16 and f128 in more cases Add f16 and f128 tests Improve tests results for f16 and f128
1 parent 006c0da commit fc8be3d

File tree

31 files changed

+4521
-405
lines changed

31 files changed

+4521
-405
lines changed

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,10 @@ impl<'ll> CodegenCx<'ll, '_> {
682682
let t_i64 = self.type_i64();
683683
let t_i128 = self.type_i128();
684684
let t_isize = self.type_isize();
685+
let t_f16 = self.type_f16();
685686
let t_f32 = self.type_f32();
686687
let t_f64 = self.type_f64();
688+
let t_f128 = self.type_f128();
687689
let t_metadata = self.type_metadata();
688690
let t_token = self.type_token();
689691

@@ -725,69 +727,115 @@ impl<'ll> CodegenCx<'ll, '_> {
725727
ifn!("llvm.debugtrap", fn() -> void);
726728
ifn!("llvm.frameaddress", fn(t_i32) -> ptr);
727729

730+
ifn!("llvm.powi.f16", fn(t_f32, t_i32) -> t_f16);
728731
ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
729732
ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
733+
ifn!("llvm.powi.f128", fn(t_f128, t_i32) -> t_f128);
730734

735+
ifn!("llvm.pow.f16", fn(t_f32, t_f16) -> t_f16);
731736
ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
732737
ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
738+
ifn!("llvm.pow.f128", fn(t_f128, t_f128) -> t_f128);
733739

740+
ifn!("llvm.sqrt.f16", fn(t_f16) -> t_f16);
734741
ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
735742
ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
743+
ifn!("llvm.sqrt.f128", fn(t_f128) -> t_f128);
736744

745+
ifn!("llvm.sin.f16", fn(t_f16) -> t_f16);
737746
ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
738747
ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
748+
ifn!("llvm.sin.f128", fn(t_f128) -> t_f128);
739749

750+
ifn!("llvm.cos.f16", fn(t_f16) -> t_f16);
740751
ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
741752
ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
753+
ifn!("llvm.cos.f128", fn(t_f128) -> t_f128);
742754

755+
ifn!("llvm.exp.f16", fn(t_f16) -> t_f16);
743756
ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
744757
ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
758+
ifn!("llvm.exp.f128", fn(t_f128) -> t_f128);
745759

760+
ifn!("llvm.exp2.f16", fn(t_f16) -> t_f16);
746761
ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
747762
ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
763+
ifn!("llvm.exp2.f128", fn(t_f128) -> t_f128);
748764

765+
ifn!("llvm.log.f16", fn(t_f16) -> t_f16);
749766
ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
750767
ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
768+
ifn!("llvm.log.f128", fn(t_f128) -> t_f128);
751769

770+
ifn!("llvm.log10.f16", fn(t_f16) -> t_f16);
752771
ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
753772
ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
773+
ifn!("llvm.log10.f128", fn(t_f128) -> t_f128);
754774

775+
ifn!("llvm.log2.f16", fn(t_f16) -> t_f16);
755776
ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
756777
ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
778+
ifn!("llvm.log2.f128", fn(t_f128) -> t_f128);
757779

780+
ifn!("llvm.fma.f16", fn(t_f32, t_f32, t_f32) -> t_f32);
758781
ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
759782
ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
783+
ifn!("llvm.fma.f128", fn(t_f128, t_f128, t_f128) -> t_f128);
760784

785+
ifn!("llvm.fabs.f16", fn(t_f16) -> t_f16);
761786
ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
762787
ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
788+
ifn!("llvm.fabs.f128", fn(t_f128) -> t_f128);
763789

790+
ifn!("llvm.minnum.f16", fn(t_f16, t_f16) -> t_f16);
764791
ifn!("llvm.minnum.f32", fn(t_f32, t_f32) -> t_f32);
765792
ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
793+
ifn!("llvm.minnum.f128", fn(t_f128, t_f128) -> t_f128);
794+
795+
ifn!("llvm.maxnum.f16", fn(t_f16, t_f16) -> t_f16);
766796
ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32);
767797
ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
798+
ifn!("llvm.maxnum.f128", fn(t_f128, t_f128) -> t_f128);
768799

800+
ifn!("llvm.floor.f16", fn(t_f16) -> t_f16);
769801
ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
770802
ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
803+
ifn!("llvm.floor.f128", fn(t_f128) -> t_f128);
771804

805+
ifn!("llvm.ceil.f16", fn(t_f16) -> t_f16);
772806
ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
773807
ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
808+
ifn!("llvm.ceil.f128", fn(t_f128) -> t_f128);
774809

810+
ifn!("llvm.trunc.f16", fn(t_f16) -> t_f16);
775811
ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
776812
ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
813+
ifn!("llvm.trunc.f128", fn(t_f128) -> t_f128);
777814

815+
ifn!("llvm.copysign.f16", fn(t_f16, t_f16) -> t_f16);
778816
ifn!("llvm.copysign.f32", fn(t_f32, t_f32) -> t_f32);
779817
ifn!("llvm.copysign.f64", fn(t_f64, t_f64) -> t_f64);
818+
ifn!("llvm.copysign.f128", fn(t_f128, t_f128) -> t_f128);
780819

820+
ifn!("llvm.round.f16", fn(t_f16) -> t_f16);
781821
ifn!("llvm.round.f32", fn(t_f32) -> t_f32);
782822
ifn!("llvm.round.f64", fn(t_f64) -> t_f64);
823+
ifn!("llvm.round.f128", fn(t_f128) -> t_f128);
783824

825+
ifn!("llvm.roundeven.f16", fn(t_f16) -> t_f16);
784826
ifn!("llvm.roundeven.f32", fn(t_f32) -> t_f32);
785827
ifn!("llvm.roundeven.f64", fn(t_f64) -> t_f64);
828+
ifn!("llvm.roundeven.f128", fn(t_f128) -> t_f128);
786829

830+
ifn!("llvm.rint.f16", fn(t_f16) -> t_f16);
787831
ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
788832
ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
833+
ifn!("llvm.rint.f128", fn(t_f128) -> t_f128);
834+
835+
ifn!("llvm.nearbyint.f16", fn(t_f16) -> t_f16);
789836
ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
790837
ifn!("llvm.nearbyint.f64", fn(t_f64) -> t_f64);
838+
ifn!("llvm.nearbyint.f128", fn(t_f128) -> t_f128);
791839

792840
ifn!("llvm.ctpop.i8", fn(t_i8) -> t_i8);
793841
ifn!("llvm.ctpop.i16", fn(t_i16) -> t_i16);

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn get_simple_intrinsic<'ll>(
103103
sym::rintf16 => "llvm.rint.f16",
104104
sym::rintf32 => "llvm.rint.f32",
105105
sym::rintf64 => "llvm.rint.f64",
106-
sym::rintf128 => "llvm.rint.128",
106+
sym::rintf128 => "llvm.rint.f128",
107107
sym::nearbyintf16 => "llvm.nearbyint.f16",
108108
sym::nearbyintf32 => "llvm.nearbyint.f32",
109109
sym::nearbyintf64 => "llvm.nearbyint.f64",

compiler/rustc_codegen_llvm/src/type_.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
205205
match self.type_kind(ty) {
206206
TypeKind::Array | TypeKind::Vector => unsafe { llvm::LLVMGetElementType(ty) },
207207
TypeKind::Pointer => bug!("element_type is not supported for opaque pointers"),
208-
other => bug!("element_type called on unsupported type {:?}", other),
208+
other => bug!("element_type called on unsupported type {other:?}"),
209209
}
210210
}
211211

@@ -215,11 +215,12 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
215215

216216
fn float_width(&self, ty: &'ll Type) -> usize {
217217
match self.type_kind(ty) {
218+
TypeKind::Half => 16,
218219
TypeKind::Float => 32,
219220
TypeKind::Double => 64,
220221
TypeKind::X86_FP80 => 80,
221222
TypeKind::FP128 | TypeKind::PPC_FP128 => 128,
222-
_ => bug!("llvm_float_width called on a non-float type"),
223+
other => bug!("llvm_float_width called on a non-float type {other:?}"),
223224
}
224225
}
225226

compiler/rustc_codegen_ssa/src/traits/builder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,10 @@ pub trait BuilderMethods<'a, 'tcx>:
217217
} else {
218218
(in_ty, dest_ty)
219219
};
220-
assert!(matches!(self.cx().type_kind(float_ty), TypeKind::Float | TypeKind::Double));
220+
assert!(matches!(
221+
self.cx().type_kind(float_ty),
222+
TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::FP128
223+
));
221224
assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer);
222225

223226
if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts {

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::assert_matches::assert_matches;
22

3-
use rustc_apfloat::ieee::{Double, Single};
3+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
44
use rustc_apfloat::{Float, FloatConvert};
55
use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
66
use rustc_middle::mir::CastKind;
@@ -182,12 +182,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
182182

183183
match src.layout.ty.kind() {
184184
// Floating point
185+
Float(FloatTy::F16) => {
186+
return Ok(self.cast_from_float(src.to_scalar().to_f16()?, cast_ty).into());
187+
}
185188
Float(FloatTy::F32) => {
186189
return Ok(self.cast_from_float(src.to_scalar().to_f32()?, cast_ty).into());
187190
}
188191
Float(FloatTy::F64) => {
189192
return Ok(self.cast_from_float(src.to_scalar().to_f64()?, cast_ty).into());
190193
}
194+
Float(FloatTy::F128) => {
195+
return Ok(self.cast_from_float(src.to_scalar().to_f128()?, cast_ty).into());
196+
}
191197
_ => {
192198
bug!("Can't cast 'Float' type into {:?}", cast_ty);
193199
}
@@ -287,10 +293,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
287293
Scalar::from_uint(v, size)
288294
}
289295

296+
Float(FloatTy::F16) if signed => Scalar::from_f16(Half::from_i128(v as i128).value),
290297
Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value),
291298
Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value),
299+
Float(FloatTy::F128) if signed => Scalar::from_f128(Quad::from_i128(v as i128).value),
300+
Float(FloatTy::F16) => Scalar::from_f16(Half::from_u128(v).value),
292301
Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value),
293302
Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value),
303+
Float(FloatTy::F128) => Scalar::from_f128(Quad::from_u128(v).value),
294304

295305
Char => {
296306
// `u8` to `char` cast

compiler/rustc_const_eval/src/interpret/operator.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
465465
}
466466
ty::Float(fty) => {
467467
let res = match (un_op, fty) {
468+
(Neg, FloatTy::F16) => Scalar::from_f16(-val.to_f16()?),
468469
(Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?),
469470
(Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?),
471+
(Neg, FloatTy::F128) => Scalar::from_f128(-val.to_f128()?),
470472
_ => span_bug!(self.cur_span(), "Invalid float op {:?}", un_op),
471473
};
472474
Ok((res, false, layout.ty))

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::ty::{
66
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
77
};
88
use crate::ty::{GenericArg, GenericArgKind};
9-
use rustc_apfloat::ieee::{Double, Single};
9+
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
1010
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
1111
use rustc_data_structures::sso::SsoHashSet;
1212
use rustc_hir as hir;
@@ -1479,12 +1479,18 @@ pub trait PrettyPrinter<'tcx>:
14791479
ty::Bool if int == ScalarInt::FALSE => p!("false"),
14801480
ty::Bool if int == ScalarInt::TRUE => p!("true"),
14811481
// Float
1482+
ty::Float(ty::FloatTy::F16) => {
1483+
p!(write("{}f16", Half::try_from(int).unwrap()))
1484+
}
14821485
ty::Float(ty::FloatTy::F32) => {
14831486
p!(write("{}f32", Single::try_from(int).unwrap()))
14841487
}
14851488
ty::Float(ty::FloatTy::F64) => {
14861489
p!(write("{}f64", Double::try_from(int).unwrap()))
14871490
}
1491+
ty::Float(ty::FloatTy::F128) => {
1492+
p!(write("{}f128", Quad::try_from(int).unwrap()))
1493+
}
14881494
// Int
14891495
ty::Uint(_) | ty::Int(_) => {
14901496
let int =

compiler/rustc_mir_build/src/build/mod.rs

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -966,26 +966,48 @@ fn parse_float_into_constval<'tcx>(
966966
parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar)
967967
}
968968

969-
// #[cfg(not(bootstrap))]
970-
// fn parse_f16(num: &str) -> Option<f16> {
971-
// num.parse().ok()
972-
// }
973-
974-
// FIXME: bootstrap `f16` parsing via `f32`
975-
// #[cfg(bootstrap)]
976-
fn parse_f16(num: &str) -> Option<f32> {
977-
num.parse().ok()
969+
#[cfg(not(bootstrap))]
970+
fn parse_check_f16(num: &str, f: Half) -> Option<()> {
971+
let Ok(rust_f) = num.parse::<f16>() else { return None };
972+
973+
assert!(
974+
u128::from(rust_f.to_bits()) == f.to_bits(),
975+
"apfloat::ieee::Half gave a different result for `{num}`: \
976+
{f} ({:#x}) vs Rust's {} ({:#x})",
977+
f.to_bits(),
978+
Single::from_bits(rust_f.to_bits().into()),
979+
rust_f.to_bits()
980+
);
981+
982+
Some(())
978983
}
979984

980-
// #[cfg(not(bootstrap))]
981-
// fn parse_f128(num: &str) -> Option<f128> {
982-
// num.parse().ok()
983-
// }
985+
// FIXME:f16_f128: bootstrap `f16` parsing via `f32`
986+
#[cfg(bootstrap)]
987+
fn parse_check_f16(_num: &str, _f: Half) -> Option<()> {
988+
Some(())
989+
}
990+
991+
#[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+
);
9841003

985-
// FIXME: bootstrap `f16` parsing via `f32`
986-
// #[cfg(bootstrap)]
987-
fn parse_f128(num: &str) -> Option<f64> {
988-
num.parse().ok()
1004+
Some(())
1005+
}
1006+
1007+
// FIXME:f16_f128: bootstrap `f128` parsing via `f64`
1008+
#[cfg(bootstrap)]
1009+
fn parse_check_f128(_num: &str, _f: Quad) -> Option<()> {
1010+
Some(())
9891011
}
9901012

9911013
pub(crate) fn parse_float_into_scalar(
@@ -997,22 +1019,11 @@ pub(crate) fn parse_float_into_scalar(
9971019

9981020
match float_ty {
9991021
ty::FloatTy::F16 => {
1000-
let rust_f = parse_f16(num)?;
1001-
10021022
let mut f = num
10031023
.parse::<Half>()
10041024
.unwrap_or_else(|e| panic!("apfloat::ieee::Half failed to parse `{num}`: {e:?}"));
10051025

1006-
assert!(
1007-
u128::from(rust_f.to_bits()) == f.to_bits(),
1008-
"apfloat::ieee::Half gave different result for `{}`: \
1009-
{}({:#x}) vs Rust's {}({:#x})",
1010-
rust_f,
1011-
f,
1012-
f.to_bits(),
1013-
Half::from_bits(rust_f.to_bits().into()),
1014-
rust_f.to_bits()
1015-
);
1026+
parse_check_f16(num, f)?;
10161027

10171028
if neg {
10181029
f = -f;
@@ -1028,10 +1039,8 @@ pub(crate) fn parse_float_into_scalar(
10281039

10291040
assert!(
10301041
u128::from(rust_f.to_bits()) == f.to_bits(),
1031-
"apfloat::ieee::Single gave different result for `{}`: \
1032-
{}({:#x}) vs Rust's {}({:#x})",
1033-
rust_f,
1034-
f,
1042+
"apfloat::ieee::Single gave a different result for `{num}`: \
1043+
{f} ({:#x}) vs Rust's {} ({:#x})",
10351044
f.to_bits(),
10361045
Single::from_bits(rust_f.to_bits().into()),
10371046
rust_f.to_bits()
@@ -1051,10 +1060,8 @@ pub(crate) fn parse_float_into_scalar(
10511060

10521061
assert!(
10531062
u128::from(rust_f.to_bits()) == f.to_bits(),
1054-
"apfloat::ieee::Double gave different result for `{}`: \
1055-
{}({:#x}) vs Rust's {}({:#x})",
1056-
rust_f,
1057-
f,
1063+
"apfloat::ieee::Double gave a different result for `{num}`: \
1064+
{f} ({:#x}) vs Rust's {} ({:#x})",
10581065
f.to_bits(),
10591066
Double::from_bits(rust_f.to_bits().into()),
10601067
rust_f.to_bits()
@@ -1067,21 +1074,11 @@ pub(crate) fn parse_float_into_scalar(
10671074
Some(Scalar::from_f64(f))
10681075
}
10691076
ty::FloatTy::F128 => {
1070-
let rust_f = parse_f128(num)?;
10711077
let mut f = num
10721078
.parse::<Quad>()
10731079
.unwrap_or_else(|e| panic!("apfloat::ieee::Quad failed to parse `{num}`: {e:?}"));
10741080

1075-
assert!(
1076-
u128::from(rust_f.to_bits()) == f.to_bits(),
1077-
"apfloat::ieee::Quad gave different result for `{}`: \
1078-
{}({:#x}) vs Rust's {}({:#x})",
1079-
rust_f,
1080-
f,
1081-
f.to_bits(),
1082-
Quad::from_bits(rust_f.to_bits().into()),
1083-
rust_f.to_bits()
1084-
);
1081+
parse_check_f128(num, f);
10851082

10861083
if neg {
10871084
f = -f;

compiler/rustc_mir_build/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#![feature(let_chains)]
1010
#![feature(min_specialization)]
1111
#![feature(try_blocks)]
12+
#![cfg_attr(not(bootstrap), feature(f16))]
13+
#![cfg_attr(not(bootstrap), feature(f128))]
1214
#![recursion_limit = "256"]
1315

1416
#[macro_use]

0 commit comments

Comments
 (0)