From c457b26e33ccd83da9055acb19f6099e4a353a12 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Sun, 30 Jul 2017 20:43:53 +0300
Subject: [PATCH] rustc_trans: do not pass floating-point values to LLVM
 through FFI.

---
 src/librustc_llvm/ffi.rs           |  1 -
 src/librustc_trans/base.rs         |  3 +--
 src/librustc_trans/common.rs       |  6 ------
 src/librustc_trans/consts.rs       |  6 ++++++
 src/librustc_trans/mir/constant.rs | 12 ++++++------
 5 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 24d4040ccb0..20735af69e3 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -598,7 +598,6 @@ extern "C" {
     // Operations on scalar constants
     pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
     pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef;
-    pub fn LLVMConstReal(RealTy: TypeRef, N: f64) -> ValueRef;
     pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
     pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
     pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 14c73de64bc..086a8290cff 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -844,8 +844,7 @@ fn create_imps(sess: &Session,
             let imp = llvm::LLVMAddGlobal(llvm_module.llmod,
                                           i8p_ty.to_ref(),
                                           imp_name.as_ptr() as *const _);
-            let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
-            llvm::LLVMSetInitializer(imp, init);
+            llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
             llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
         }
     }
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 9b0803908b1..61766a3db2c 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -223,12 +223,6 @@ pub fn C_big_integral(t: Type, u: u128) -> ValueRef {
     }
 }
 
-pub fn C_floating_f64(f: f64, t: Type) -> ValueRef {
-    unsafe {
-        llvm::LLVMConstReal(t.to_ref(), f)
-    }
-}
-
 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
     C_struct(ccx, &[], false)
 }
diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs
index da2a5839863..310cd6fe955 100644
--- a/src/librustc_trans/consts.rs
+++ b/src/librustc_trans/consts.rs
@@ -36,6 +36,12 @@ pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
     }
 }
 
+pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef {
+    unsafe {
+        llvm::LLVMConstBitCast(val, ty.to_ref())
+    }
+}
+
 pub fn addr_of_mut(ccx: &CrateContext,
                    cv: ValueRef,
                    align: machine::llalign,
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 7ece5a42ca1..265600a35e7 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -11,7 +11,6 @@
 use llvm::{self, ValueRef};
 use rustc::middle::const_val::{ConstEvalErr, ConstVal, ErrKind};
 use rustc_const_math::ConstInt::*;
-use rustc_const_math::ConstFloat;
 use rustc_const_math::{ConstInt, ConstMathErr};
 use rustc::hir::def_id::DefId;
 use rustc::infer::TransNormalize;
@@ -27,7 +26,7 @@ use abi::{self, Abi};
 use callee;
 use builder::Builder;
 use common::{self, CrateContext, const_get_elt, val_ty};
-use common::{C_array, C_bool, C_bytes, C_floating_f64, C_integral, C_big_integral};
+use common::{C_array, C_bool, C_bytes, C_integral, C_big_integral, C_u32, C_u64};
 use common::{C_null, C_struct, C_str_slice, C_undef, C_uint, C_vector, is_undef};
 use common::const_to_opt_u128;
 use consts;
@@ -37,6 +36,7 @@ use type_::Type;
 use value::Value;
 
 use syntax_pos::Span;
+use syntax::ast;
 
 use std::fmt;
 use std::ptr;
@@ -96,11 +96,11 @@ impl<'tcx> Const<'tcx> {
         let llty = type_of::type_of(ccx, ty);
         let val = match cv {
             ConstVal::Float(v) => {
-                let v_f64 = match v {
-                    ConstFloat::F32(v) => f32::from_bits(v) as f64,
-                    ConstFloat::F64(v) => f64::from_bits(v)
+                let bits = match v.ty {
+                    ast::FloatTy::F32 => C_u32(ccx, v.bits as u32),
+                    ast::FloatTy::F64 => C_u64(ccx, v.bits as u64)
                 };
-                C_floating_f64(v_f64, llty)
+                consts::bitcast(bits, llty)
             }
             ConstVal::Bool(v) => C_bool(ccx, v),
             ConstVal::Integral(ref i) => return Const::from_constint(ccx, i),