]> git.lizzy.rs Git - rust.git/commitdiff
Remove now-redundant range check on u128 -> f32 casts
authorRobin Kruppe <robin.kruppe@gmail.com>
Sun, 15 Dec 2019 17:17:00 +0000 (18:17 +0100)
committerRobin Kruppe <robin.kruppe@gmail.com>
Sun, 15 Dec 2019 17:17:00 +0000 (18:17 +0100)
This code was added to avoid UB in LLVM 6 and earlier, but we no longer support those LLVM versions.
Since https://reviews.llvm.org/D47807 (released in LLVM 7), uitofp does exactly what we need.

Closes #51872

src/librustc_codegen_ssa/mir/rvalue.rs

index 488ae8dbf9036c91701a4f3038564679b558851b..55d63f18cd906a7711940d1005a1d581b40bdc91 100644 (file)
@@ -341,6 +341,13 @@ pub fn codegen_rvalue_operand(
                                     llval
                                 }
                             }
+                            (CastTy::Int(_), CastTy::Float) => {
+                                if signed {
+                                    bx.sitofp(llval, ll_t_out)
+                                } else {
+                                    bx.uitofp(llval, ll_t_out)
+                                }
+                            }
                             (CastTy::Ptr(_), CastTy::Ptr(_)) |
                             (CastTy::FnPtr, CastTy::Ptr(_)) |
                             (CastTy::RPtr(_), CastTy::Ptr(_)) =>
@@ -352,8 +359,6 @@ pub fn codegen_rvalue_operand(
                                 let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed);
                                 bx.inttoptr(usize_llval, ll_t_out)
                             }
-                            (CastTy::Int(_), CastTy::Float) =>
-                                cast_int_to_float(&mut bx, signed, llval, ll_t_in, ll_t_out),
                             (CastTy::Float, CastTy::Int(IntTy::I)) =>
                                 cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out),
                             (CastTy::Float, CastTy::Int(_)) =>
@@ -720,40 +725,6 @@ pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) ->
     }
 }
 
-fn cast_int_to_float<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
-    bx: &mut Bx,
-    signed: bool,
-    x: Bx::Value,
-    int_ty: Bx::Type,
-    float_ty: Bx::Type
-) -> Bx::Value {
-    // Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
-    // It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
-    // LLVM's uitofp produces undef in those cases, so we manually check for that case.
-    let is_u128_to_f32 = !signed &&
-        bx.cx().int_width(int_ty) == 128 &&
-        bx.cx().float_width(float_ty) == 32;
-    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;
-        const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
-                                            << (Single::MAX_EXP - Single::PRECISION as i16);
-        let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
-        let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
-        let infinity_bits = bx.cx().const_u32(ieee::Single::INFINITY.to_bits() as u32);
-        let infinity = bx.bitcast(infinity_bits, float_ty);
-        let fp = bx.uitofp(x, float_ty);
-        bx.select(overflow, infinity, fp)
-    } else {
-        if signed {
-            bx.sitofp(x, float_ty)
-        } else {
-            bx.uitofp(x, float_ty)
-        }
-    }
-}
-
 fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     signed: bool,