Skip to content

Commit 3684027

Browse files
committed
Enable const evaluation for f16 and f128
This excludes casting, which needs more tests.
1 parent 921645c commit 3684027

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 17 additions & 10 deletions
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;
@@ -189,10 +189,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
189189
bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)
190190
};
191191
let val = match fty {
192-
FloatTy::F16 => unimplemented!("f16_f128"),
192+
FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty),
193193
FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
194194
FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
195-
FloatTy::F128 => unimplemented!("f16_f128"),
195+
FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty),
196196
};
197197
Ok(ImmTy::from_scalar(val, cast_to))
198198
}
@@ -298,18 +298,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
298298
Float(fty) if signed => {
299299
let v = v as i128;
300300
match fty {
301-
FloatTy::F16 => unimplemented!("f16_f128"),
301+
FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value),
302302
FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),
303303
FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),
304-
FloatTy::F128 => unimplemented!("f16_f128"),
304+
FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value),
305305
}
306306
}
307307
// unsigned int -> float
308308
Float(fty) => match fty {
309-
FloatTy::F16 => unimplemented!("f16_f128"),
309+
FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value),
310310
FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
311311
FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
312-
FloatTy::F128 => unimplemented!("f16_f128"),
312+
FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value),
313313
},
314314

315315
// u8 -> char
@@ -323,7 +323,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
323323
/// Low-level cast helper function. Converts an apfloat `f` into int or float types.
324324
fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance>
325325
where
326-
F: Float + Into<Scalar<M::Provenance>> + FloatConvert<Single> + FloatConvert<Double>,
326+
F: Float
327+
+ Into<Scalar<M::Provenance>>
328+
+ FloatConvert<Half>
329+
+ FloatConvert<Single>
330+
+ FloatConvert<Double>
331+
+ FloatConvert<Quad>,
327332
{
328333
use rustc_type_ir::TyKind::*;
329334

@@ -360,10 +365,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
360365
}
361366
// float -> float
362367
Float(fty) => match fty {
363-
FloatTy::F16 => unimplemented!("f16_f128"),
368+
FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)),
364369
FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)),
365370
FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)),
366-
FloatTy::F128 => unimplemented!("f16_f128"),
371+
FloatTy::F128 => {
372+
Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value))
373+
}
367374
},
368375
// That's it.
369376
_ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),

compiler/rustc_const_eval/src/interpret/operator.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,14 +362,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
362362
let left = left.to_scalar();
363363
let right = right.to_scalar();
364364
Ok(match fty {
365-
FloatTy::F16 => unimplemented!("f16_f128"),
365+
FloatTy::F16 => {
366+
self.binary_float_op(bin_op, layout, left.to_f16()?, right.to_f16()?)
367+
}
366368
FloatTy::F32 => {
367369
self.binary_float_op(bin_op, layout, left.to_f32()?, right.to_f32()?)
368370
}
369371
FloatTy::F64 => {
370372
self.binary_float_op(bin_op, layout, left.to_f64()?, right.to_f64()?)
371373
}
372-
FloatTy::F128 => unimplemented!("f16_f128"),
374+
FloatTy::F128 => {
375+
self.binary_float_op(bin_op, layout, left.to_f128()?, right.to_f128()?)
376+
}
373377
})
374378
}
375379
_ if left.layout.ty.is_integral() => {
@@ -431,8 +435,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
431435
let val = val.to_scalar();
432436
// No NaN adjustment here, `-` is a bitwise operation!
433437
let res = match (un_op, fty) {
438+
(Neg, FloatTy::F16) => Scalar::from_f16(-val.to_f16()?),
434439
(Neg, FloatTy::F32) => Scalar::from_f32(-val.to_f32()?),
435440
(Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?),
441+
(Neg, FloatTy::F128) => Scalar::from_f128(-val.to_f128()?),
436442
_ => span_bug!(self.cur_span(), "Invalid float op {:?}", un_op),
437443
};
438444
Ok(ImmTy::from_scalar(res, layout))

compiler/rustc_middle/src/mir/interpret/value.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ impl<Prov: Provenance> fmt::LowerHex for Scalar<Prov> {
6969
}
7070
}
7171

72+
impl<Prov> From<Half> for Scalar<Prov> {
73+
#[inline(always)]
74+
fn from(f: Half) -> Self {
75+
Scalar::from_f16(f)
76+
}
77+
}
78+
7279
impl<Prov> From<Single> for Scalar<Prov> {
7380
#[inline(always)]
7481
fn from(f: Single) -> Self {
@@ -83,6 +90,13 @@ impl<Prov> From<Double> for Scalar<Prov> {
8390
}
8491
}
8592

93+
impl<Prov> From<Quad> for Scalar<Prov> {
94+
#[inline(always)]
95+
fn from(f: Quad) -> Self {
96+
Scalar::from_f128(f)
97+
}
98+
}
99+
86100
impl<Prov> From<ScalarInt> for Scalar<Prov> {
87101
#[inline(always)]
88102
fn from(ptr: ScalarInt) -> Self {

0 commit comments

Comments
 (0)