Skip to content

Commit 85db539

Browse files
authored
Rollup merge of rust-lang#67328 - rkruppe:simplify-u128-f32-cast, r=matthewjasper
Remove now-redundant range check on u128 -> f32 casts 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 rust-lang#51872
2 parents 03169a9 + 6ad0b55 commit 85db539

File tree

1 file changed

+7
-36
lines changed

1 file changed

+7
-36
lines changed

src/librustc_codegen_ssa/mir/rvalue.rs

+7-36
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
341341
llval
342342
}
343343
}
344+
(CastTy::Int(_), CastTy::Float) => {
345+
if signed {
346+
bx.sitofp(llval, ll_t_out)
347+
} else {
348+
bx.uitofp(llval, ll_t_out)
349+
}
350+
}
344351
(CastTy::Ptr(_), CastTy::Ptr(_)) |
345352
(CastTy::FnPtr, CastTy::Ptr(_)) |
346353
(CastTy::RPtr(_), CastTy::Ptr(_)) =>
@@ -352,8 +359,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
352359
let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed);
353360
bx.inttoptr(usize_llval, ll_t_out)
354361
}
355-
(CastTy::Int(_), CastTy::Float) =>
356-
cast_int_to_float(&mut bx, signed, llval, ll_t_in, ll_t_out),
357362
(CastTy::Float, CastTy::Int(IntTy::I)) =>
358363
cast_float_to_int(&mut bx, true, llval, ll_t_in, ll_t_out),
359364
(CastTy::Float, CastTy::Int(_)) =>
@@ -720,40 +725,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
720725
}
721726
}
722727

723-
fn cast_int_to_float<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
724-
bx: &mut Bx,
725-
signed: bool,
726-
x: Bx::Value,
727-
int_ty: Bx::Type,
728-
float_ty: Bx::Type
729-
) -> Bx::Value {
730-
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
731-
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
732-
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
733-
let is_u128_to_f32 = !signed &&
734-
bx.cx().int_width(int_ty) == 128 &&
735-
bx.cx().float_width(float_ty) == 32;
736-
if is_u128_to_f32 {
737-
// All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity,
738-
// and for everything else LLVM's uitofp works just fine.
739-
use rustc_apfloat::ieee::Single;
740-
const MAX_F32_PLUS_HALF_ULP: u128 = ((1 << (Single::PRECISION + 1)) - 1)
741-
<< (Single::MAX_EXP - Single::PRECISION as i16);
742-
let max = bx.cx().const_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP);
743-
let overflow = bx.icmp(IntPredicate::IntUGE, x, max);
744-
let infinity_bits = bx.cx().const_u32(ieee::Single::INFINITY.to_bits() as u32);
745-
let infinity = bx.bitcast(infinity_bits, float_ty);
746-
let fp = bx.uitofp(x, float_ty);
747-
bx.select(overflow, infinity, fp)
748-
} else {
749-
if signed {
750-
bx.sitofp(x, float_ty)
751-
} else {
752-
bx.uitofp(x, float_ty)
753-
}
754-
}
755-
}
756-
757728
fn cast_float_to_int<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
758729
bx: &mut Bx,
759730
signed: bool,

0 commit comments

Comments
 (0)