From 40b118cf4767413f7676c97296c222167604485b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 25 Apr 2018 15:26:12 +0200 Subject: [PATCH] Remove ConstFloat --- src/librustc/ich/impls_const_math.rs | 5 - src/librustc/mir/mod.rs | 9 +- src/librustc_const_math/float.rs | 217 ------------------------- src/librustc_const_math/lib.rs | 5 - src/librustc_mir/hair/cx/mod.rs | 24 +-- src/librustc_mir/hair/pattern/mod.rs | 66 +++++--- src/librustc_mir/interpret/cast.rs | 9 +- src/librustc_mir/interpret/operator.rs | 54 +++--- src/librustc_trans/mir/rvalue.rs | 5 +- 9 files changed, 85 insertions(+), 309 deletions(-) delete mode 100644 src/librustc_const_math/float.rs diff --git a/src/librustc/ich/impls_const_math.rs b/src/librustc/ich/impls_const_math.rs index 3c1205a67843d..bbc43987c99de 100644 --- a/src/librustc/ich/impls_const_math.rs +++ b/src/librustc/ich/impls_const_math.rs @@ -11,11 +11,6 @@ //! This module contains `HashStable` implementations for various data types //! from `rustc_const_math` in no particular order. -impl_stable_hash_for!(struct ::rustc_const_math::ConstFloat { - ty, - bits -}); - impl_stable_hash_for!(enum ::rustc_const_math::ConstMathErr { Overflow(op), DivisionByZero, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index c26b3014e53dd..d1e515b2c7767 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -43,6 +43,8 @@ use std::vec::IntoIter; use syntax::ast::{self, Name}; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; +use rustc_apfloat::ieee::{Single, Double}; +use rustc_apfloat::Float; mod cache; pub mod tcx; @@ -1915,12 +1917,13 @@ fn fmt_const_val(fmt: &mut W, const_val: &ty::Const) -> fmt::Result { pub fn print_miri_value(value: Value, ty: Ty, f: &mut W) -> fmt::Result { use ty::TypeVariants::*; - use rustc_const_math::ConstFloat; match (value, &ty.sty) { (Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"), (Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"), - (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(fty)) => - write!(f, "{}", ConstFloat { bits, ty: fty }), + (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) => + write!(f, "{}", Single::from_bits(bits)), + (Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) => + write!(f, "{}", Double::from_bits(bits)), (Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui), (Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i), (Value::ByVal(PrimVal::Bytes(n)), &TyChar) => diff --git a/src/librustc_const_math/float.rs b/src/librustc_const_math/float.rs deleted file mode 100644 index 35cfe466c8a73..0000000000000 --- a/src/librustc_const_math/float.rs +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::cmp::Ordering; -use std::num::ParseFloatError; - -use syntax::ast; - -use rustc_apfloat::{Float, FloatConvert, Status}; -use rustc_apfloat::ieee::{Single, Double}; - -// Note that equality for `ConstFloat` means that the it is the same -// constant, not that the rust values are equal. In particular, `NaN -// == NaN` (at least if it's the same NaN; distinct encodings for NaN -// are considering unequal). -#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub struct ConstFloat { - pub ty: ast::FloatTy, - - // This is a bit inefficient but it makes conversions below more - // ergonomic, and all of this will go away once `miri` is merged. - pub bits: u128, -} - -impl PartialOrd for ConstFloat { - fn partial_cmp(&self, other: &Self) -> Option { - self.try_cmp(*other) - } -} - -impl ConstFloat { - /// Description of the type, not the value - pub fn description(&self) -> &'static str { - self.ty.ty_to_string() - } - - /// Compares the values if they are of the same type - fn try_cmp(self, rhs: Self) -> Option { - match (self.ty, rhs.ty) { - (ast::FloatTy::F64, ast::FloatTy::F64) => { - let a = Double::from_bits(self.bits); - let b = Double::from_bits(rhs.bits); - // This is pretty bad but it is the existing behavior. - Some(a.partial_cmp(&b).unwrap_or(Ordering::Greater)) - } - - (ast::FloatTy::F32, ast::FloatTy::F32) => { - let a = Single::from_bits(self.bits); - let b = Single::from_bits(rhs.bits); - Some(a.partial_cmp(&b).unwrap_or(Ordering::Greater)) - } - - _ => None, - } - } - - pub fn from_i128(input: i128, ty: ast::FloatTy) -> Self { - let bits = match ty { - ast::FloatTy::F32 => Single::from_i128(input).value.to_bits(), - ast::FloatTy::F64 => Double::from_i128(input).value.to_bits() - }; - ConstFloat { bits, ty } - } - - pub fn from_u128(input: u128, ty: ast::FloatTy) -> Self { - let bits = match ty { - ast::FloatTy::F32 => Single::from_u128(input).value.to_bits(), - ast::FloatTy::F64 => Double::from_u128(input).value.to_bits() - }; - ConstFloat { bits, ty } - } - - pub fn from_str(num: &str, ty: ast::FloatTy) -> Result { - let bits = match ty { - ast::FloatTy::F32 => { - let rust_bits = num.parse::()?.to_bits() as u128; - let apfloat = num.parse::().unwrap_or_else(|e| { - panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e); - }); - let apfloat_bits = apfloat.to_bits(); - assert!(rust_bits == apfloat_bits, - "apfloat::ieee::Single gave different result for `{}`: \ - {}({:#x}) vs Rust's {}({:#x})", - num, apfloat, apfloat_bits, - Single::from_bits(rust_bits), rust_bits); - apfloat_bits - } - ast::FloatTy::F64 => { - let rust_bits = num.parse::()?.to_bits() as u128; - let apfloat = num.parse::().unwrap_or_else(|e| { - panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e); - }); - let apfloat_bits = apfloat.to_bits(); - assert!(rust_bits == apfloat_bits, - "apfloat::ieee::Double gave different result for `{}`: \ - {}({:#x}) vs Rust's {}({:#x})", - num, apfloat, apfloat_bits, - Double::from_bits(rust_bits), rust_bits); - apfloat_bits - } - }; - Ok(ConstFloat { bits, ty }) - } - - pub fn to_i128(self, width: usize) -> Option { - assert!(width <= 128); - let r = match self.ty { - ast::FloatTy::F32 => Single::from_bits(self.bits).to_i128(width), - ast::FloatTy::F64 => Double::from_bits(self.bits).to_i128(width) - }; - if r.status.intersects(Status::INVALID_OP) { - None - } else { - Some(r.value) - } - } - - pub fn to_u128(self, width: usize) -> Option { - assert!(width <= 128); - let r = match self.ty { - ast::FloatTy::F32 => Single::from_bits(self.bits).to_u128(width), - ast::FloatTy::F64 => Double::from_bits(self.bits).to_u128(width) - }; - if r.status.intersects(Status::INVALID_OP) { - None - } else { - Some(r.value) - } - } - - pub fn convert(self, to: ast::FloatTy) -> Self { - let bits = match (self.ty, to) { - (ast::FloatTy::F32, ast::FloatTy::F32) | - (ast::FloatTy::F64, ast::FloatTy::F64) => return self, - - (ast::FloatTy::F32, ast::FloatTy::F64) => { - Double::to_bits(Single::from_bits(self.bits).convert(&mut false).value) - } - (ast::FloatTy::F64, ast::FloatTy::F32) => { - Single::to_bits(Double::from_bits(self.bits).convert(&mut false).value) - } - }; - ConstFloat { bits, ty: to } - } -} - -impl ::std::fmt::Display for ConstFloat { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - match self.ty { - ast::FloatTy::F32 => write!(fmt, "{:#}", Single::from_bits(self.bits))?, - ast::FloatTy::F64 => write!(fmt, "{:#}", Double::from_bits(self.bits))?, - } - write!(fmt, "{}", self.ty) - } -} - -impl ::std::fmt::Debug for ConstFloat { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(self, fmt) - } -} - -macro_rules! derive_binop { - ($op:ident, $func:ident) => { - impl ::std::ops::$op for ConstFloat { - type Output = Option; - fn $func(self, rhs: Self) -> Option { - let bits = match (self.ty, rhs.ty) { - (ast::FloatTy::F32, ast::FloatTy::F32) =>{ - let a = Single::from_bits(self.bits); - let b = Single::from_bits(rhs.bits); - a.$func(b).value.to_bits() - } - (ast::FloatTy::F64, ast::FloatTy::F64) => { - let a = Double::from_bits(self.bits); - let b = Double::from_bits(rhs.bits); - a.$func(b).value.to_bits() - } - _ => return None, - }; - Some(ConstFloat { bits, ty: self.ty }) - } - } - } -} - -derive_binop!(Add, add); -derive_binop!(Sub, sub); -derive_binop!(Mul, mul); -derive_binop!(Div, div); -derive_binop!(Rem, rem); - -impl ::std::ops::Neg for ConstFloat { - type Output = Self; - fn neg(self) -> Self { - let bits = match self.ty { - ast::FloatTy::F32 => (-Single::from_bits(self.bits)).to_bits(), - ast::FloatTy::F64 => (-Double::from_bits(self.bits)).to_bits(), - }; - ConstFloat { bits, ty: self.ty } - } -} - -/// This is `f32::MAX + (0.5 ULP)` as an integer. Numbers greater or equal to this -/// are rounded to infinity when converted to `f32`. -/// -/// NB: Computed as maximum significand with an extra 1 bit added (for the half ULP) -/// shifted by the maximum exponent (accounting for normalization). -pub const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1) - << (Single::MAX_EXP - Single::PRECISION as i16); diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs index 499c330be1da8..08996b892f9a6 100644 --- a/src/librustc_const_math/lib.rs +++ b/src/librustc_const_math/lib.rs @@ -18,14 +18,9 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] -extern crate rustc_apfloat; - -extern crate syntax; extern crate serialize as rustc_serialize; // used by deriving -mod float; mod err; -pub use float::*; pub use err::{ConstMathErr, Op}; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index e6aa2d3abb7e0..ff5c808459190 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -30,9 +30,9 @@ use syntax::ast::{self, LitKind}; use syntax::attr; use syntax::symbol::Symbol; use rustc::hir; -use rustc_const_math::ConstFloat; use rustc_data_structures::sync::Lrc; use rustc::mir::interpret::{Value, PrimVal}; +use hair::pattern::parse_float; #[derive(Clone)] pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { @@ -170,14 +170,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { neg: bool, ) -> Literal<'tcx> { trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg); - let tcx = self.tcx.global_tcx(); - - let parse_float = |num: &str, fty| -> ConstFloat { - ConstFloat::from_str(num, fty).unwrap_or_else(|_| { - // FIXME(#31407) this is only necessary because float parsing is buggy - tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)"); - }) - }; let clamp = |n| { let size = self.integer_bit_width(ty); @@ -214,12 +206,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { LitKind::Int(n, _) => Value::ByVal(PrimVal::Bytes(clamp(n))), LitKind::Float(n, fty) => { let n = n.as_str(); - let mut f = parse_float(&n, fty); - if neg { - f = -f; - } - let bits = f.bits; - Value::ByVal(PrimVal::Bytes(bits)) + parse_float(&n, fty, neg).expect("apfloat parsing failed") } LitKind::FloatUnsuffixed(n) => { let fty = match ty.sty { @@ -227,12 +214,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { _ => bug!() }; let n = n.as_str(); - let mut f = parse_float(&n, fty); - if neg { - f = -f; - } - let bits = f.bits; - Value::ByVal(PrimVal::Bytes(bits)) + parse_float(&n, fty, neg).expect("apfloat parsing failed") } LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)), LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 776b24a8648e7..590cc77c46d77 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -28,7 +28,6 @@ use rustc::hir::def::{Def, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc_data_structures::indexed_vec::Idx; -use rustc_const_math::ConstFloat; use std::cmp::Ordering; use std::fmt; @@ -1053,22 +1052,21 @@ pub fn compare_const_vals<'a, 'tcx>( b: &ConstVal, ty: Ty<'tcx>, ) -> Option { - use rustc_const_math::ConstFloat; trace!("compare_const_vals: {:?}, {:?}", a, b); use rustc::mir::interpret::{Value, PrimVal}; match (a, b) { (&ConstVal::Value(Value::ByVal(PrimVal::Bytes(a))), &ConstVal::Value(Value::ByVal(PrimVal::Bytes(b)))) => { + use ::rustc_apfloat::Float; match ty.sty { - ty::TyFloat(ty) => { - let l = ConstFloat { - bits: a, - ty, - }; - let r = ConstFloat { - bits: b, - ty, - }; + ty::TyFloat(ast::FloatTy::F32) => { + let l = ::rustc_apfloat::ieee::Single::from_bits(a); + let r = ::rustc_apfloat::ieee::Single::from_bits(b); + l.partial_cmp(&r) + }, + ty::TyFloat(ast::FloatTy::F64) => { + let l = ::rustc_apfloat::ieee::Double::from_bits(a); + let r = ::rustc_apfloat::ieee::Double::from_bits(b); l.partial_cmp(&r) }, ty::TyInt(_) => { @@ -1148,12 +1146,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, }, LitKind::Float(n, fty) => { let n = n.as_str(); - let mut f = parse_float(&n, fty)?; - if neg { - f = -f; - } - let bits = f.bits; - Value::ByVal(PrimVal::Bytes(bits)) + parse_float(&n, fty, neg).map_err(|_| ())? } LitKind::FloatUnsuffixed(n) => { let fty = match ty.sty { @@ -1161,12 +1154,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, _ => bug!() }; let n = n.as_str(); - let mut f = parse_float(&n, fty)?; - if neg { - f = -f; - } - let bits = f.bits; - Value::ByVal(PrimVal::Bytes(bits)) + parse_float(&n, fty, neg).map_err(|_| ())? } LitKind::Bool(b) => Value::ByVal(PrimVal::Bytes(b as u128)), LitKind::Char(c) => Value::ByVal(PrimVal::Bytes(c as u128)), @@ -1174,7 +1162,33 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, Ok(ConstVal::Value(lit)) } -fn parse_float<'tcx>(num: &str, fty: ast::FloatTy) - -> Result { - ConstFloat::from_str(num, fty).map_err(|_| ()) +pub fn parse_float( + num: &str, + fty: ast::FloatTy, + neg: bool, +) -> Result { + use rustc_apfloat::ieee::{Single, Double}; + use rustc_apfloat::Float; + let bits = match fty { + ast::FloatTy::F32 => { + let mut f = num.parse::().map_err(|e| { + format!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e) + })?; + if neg { + f = -f; + } + f.to_bits() + } + ast::FloatTy::F64 => { + let mut f = num.parse::().map_err(|e| { + format!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e) + })?; + if neg { + f = -f; + } + f.to_bits() + } + }; + + Ok(Value::ByVal(PrimVal::Bytes(bits))) } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index e654142d2164c..002b5eb187db3 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -2,10 +2,9 @@ use rustc::ty::Ty; use rustc::ty::layout::LayoutOf; use syntax::ast::{FloatTy, IntTy, UintTy}; -use rustc_const_math::ConstFloat; +use rustc_apfloat::ieee::{Single, Double}; use super::{EvalContext, Machine}; use rustc::mir::interpret::{PrimVal, EvalResult, MemoryPointer, PointerArithmetic}; -use rustc_apfloat::ieee::{Single, Double}; use rustc_apfloat::Float; impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { @@ -50,8 +49,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { Ok(PrimVal::Bytes(v)) } - TyFloat(fty) if signed => Ok(PrimVal::Bytes(ConstFloat::from_i128(v as i128, fty).bits)), - TyFloat(fty) => Ok(PrimVal::Bytes(ConstFloat::from_u128(v, fty).bits)), + TyFloat(FloatTy::F32) if signed => Ok(PrimVal::Bytes(Single::from_i128(v as i128).value.to_bits())), + TyFloat(FloatTy::F64) if signed => Ok(PrimVal::Bytes(Double::from_i128(v as i128).value.to_bits())), + TyFloat(FloatTy::F32) => Ok(PrimVal::Bytes(Single::from_u128(v).value.to_bits())), + TyFloat(FloatTy::F64) => Ok(PrimVal::Bytes(Double::from_u128(v).value.to_bits())), TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)), TyChar => err!(InvalidChar(v)), diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 0c748f818ccc8..5a815e0dc67ef 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -1,9 +1,10 @@ use rustc::mir; use rustc::ty::{self, Ty}; -use rustc_const_math::ConstFloat; use syntax::ast::FloatTy; use std::cmp::Ordering; use rustc::ty::layout::LayoutOf; +use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::Float; use super::{EvalContext, Place, Machine, ValTy}; @@ -125,31 +126,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { return err!(Unimplemented(msg)); } - let float_op = |op, l, r, ty| { - let l = ConstFloat { - bits: l, - ty, - }; - let r = ConstFloat { - bits: r, - ty, - }; - match op { - Eq => PrimVal::from_bool(l.partial_cmp(&r).unwrap() == Ordering::Equal), - Ne => PrimVal::from_bool(l.partial_cmp(&r).unwrap() != Ordering::Equal), - Lt => PrimVal::from_bool(l.partial_cmp(&r).unwrap() == Ordering::Less), - Le => PrimVal::from_bool(l.partial_cmp(&r).unwrap() != Ordering::Greater), - Gt => PrimVal::from_bool(l.partial_cmp(&r).unwrap() == Ordering::Greater), - Ge => PrimVal::from_bool(l.partial_cmp(&r).unwrap() != Ordering::Less), - Add => PrimVal::Bytes((l + r).unwrap().bits), - Sub => PrimVal::Bytes((l - r).unwrap().bits), - Mul => PrimVal::Bytes((l * r).unwrap().bits), - Div => PrimVal::Bytes((l / r).unwrap().bits), - Rem => PrimVal::Bytes((l % r).unwrap().bits), - _ => bug!("invalid float op: `{:?}`", op), - } - }; - if left_layout.abi.is_signed() { let op: Option bool> = match bin_op { Lt => Some(i128::lt), @@ -199,7 +175,31 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { } if let ty::TyFloat(fty) = left_ty.sty { - return Ok((float_op(bin_op, l, r, fty), false)); + macro_rules! float_math { + ($ty:path) => {{ + let l = <$ty>::from_bits(l); + let r = <$ty>::from_bits(r); + let val = match bin_op { + Eq => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Equal), + Ne => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Equal), + Lt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Less), + Le => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Greater), + Gt => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) == Ordering::Greater), + Ge => PrimVal::from_bool(l.partial_cmp(&r).unwrap_or(Ordering::Greater) != Ordering::Less), + Add => PrimVal::Bytes((l + r).value.to_bits()), + Sub => PrimVal::Bytes((l - r).value.to_bits()), + Mul => PrimVal::Bytes((l * r).value.to_bits()), + Div => PrimVal::Bytes((l / r).value.to_bits()), + Rem => PrimVal::Bytes((l % r).value.to_bits()), + _ => bug!("invalid float op: `{:?}`", bin_op), + }; + return Ok((val, false)); + }}; + } + match fty { + FloatTy::F32 => float_math!(Single), + FloatTy::F64 => float_math!(Double), + } } // only ints left diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 79e906ca975fb..6e16590bf35a3 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -15,7 +15,6 @@ use rustc::ty::layout::{self, LayoutOf}; use rustc::mir; use rustc::middle::lang_items::ExchangeMallocFnLangItem; use rustc_apfloat::{ieee, Float, Status, Round}; -use rustc_const_math::MAX_F32_PLUS_HALF_ULP; use std::{u128, i128}; use base; @@ -805,6 +804,10 @@ fn cast_int_to_float(bx: &Builder, if is_u128_to_f32 { // All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity, // and for everything else LLVM's uitofp works just fine. + use rustc_apfloat::ieee::Single; + use rustc_apfloat::Float; + const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1) + << (Single::MAX_EXP - Single::PRECISION as i16); let max = C_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP); let overflow = bx.icmp(llvm::IntUGE, x, max); let infinity_bits = C_u32(bx.cx, ieee::Single::INFINITY.to_bits() as u32);