Skip to content

Commit 5141436

Browse files
committed
Remove float_to_int_unchecked and inline it into its call sites
1 parent b57bc6d commit 5141436

File tree

3 files changed

+56
-39
lines changed

3 files changed

+56
-39
lines changed

src/shims/intrinsics/mod.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_apfloat::{Float, Round};
99
use rustc_middle::ty::layout::LayoutOf;
1010
use rustc_middle::{
1111
mir,
12-
ty::{self, FloatTy, Ty},
12+
ty::{self, FloatTy},
1313
};
1414
use rustc_target::abi::Size;
1515

@@ -356,10 +356,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
356356
let val = this.read_immediate(val)?;
357357

358358
let res = match val.layout.ty.kind() {
359-
ty::Float(FloatTy::F32) =>
360-
this.float_to_int_unchecked(val.to_scalar().to_f32()?, dest.layout.ty)?,
361-
ty::Float(FloatTy::F64) =>
362-
this.float_to_int_unchecked(val.to_scalar().to_f64()?, dest.layout.ty)?,
359+
ty::Float(FloatTy::F32) => {
360+
let f = val.to_scalar().to_f32()?;
361+
this
362+
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
363+
.ok_or_else(|| {
364+
err_ub_format!(
365+
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
366+
dest.layout.ty
367+
)
368+
})?
369+
}
370+
ty::Float(FloatTy::F64) => {
371+
let f = val.to_scalar().to_f64()?;
372+
this
373+
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
374+
.ok_or_else(|| {
375+
err_ub_format!(
376+
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
377+
dest.layout.ty
378+
)
379+
})?
380+
}
363381
_ =>
364382
span_bug!(
365383
this.cur_span(),
@@ -383,20 +401,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
383401

384402
Ok(())
385403
}
386-
387-
fn float_to_int_unchecked<F>(
388-
&self,
389-
f: F,
390-
dest_ty: Ty<'tcx>,
391-
) -> InterpResult<'tcx, Scalar<Provenance>>
392-
where
393-
F: Float + Into<Scalar<Provenance>>,
394-
{
395-
let this = self.eval_context_ref();
396-
Ok(this
397-
.float_to_int_checked(f, dest_ty, Round::TowardZero)
398-
.ok_or_else(|| err_ub_format!(
399-
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`",
400-
))?)
401-
}
402404
}

src/shims/intrinsics/simd.rs

+31-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_apfloat::Float;
1+
use rustc_apfloat::{Float, Round};
22
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
33
use rustc_middle::{mir, ty, ty::FloatTy};
44
use rustc_target::abi::{Endian, HasDataLayout, Size};
@@ -420,7 +420,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
420420
}
421421
}
422422
}
423-
#[rustfmt::skip]
424423
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
425424
let [op] = check_arg_count(args)?;
426425
let (op, op_len) = this.operand_to_simd(op)?;
@@ -440,7 +439,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
440439

441440
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
442441
// Int-to-(int|float): always safe
443-
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast =>
442+
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_))
443+
if safe_cast || unsafe_cast =>
444444
this.int_to_int_or_float(&op, dest.layout.ty)?,
445445
// Float-to-float: always safe
446446
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
@@ -449,21 +449,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
449449
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
450450
this.float_to_float_or_int(&op, dest.layout.ty)?,
451451
// Float-to-int in unchecked mode
452-
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
453-
this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(),
454-
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
455-
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
456-
// Ptr-to-ptr cast
457-
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
458-
this.ptr_to_ptr(&op, dest.layout.ty)?
459-
}
460-
// Ptr/Int casts
461-
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
462-
this.pointer_expose_address_cast(&op, dest.layout.ty)?
452+
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
453+
let f = op.to_scalar().to_f32()?;
454+
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
455+
.ok_or_else(|| {
456+
err_ub_format!(
457+
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
458+
dest.layout.ty
459+
)
460+
})?
461+
.into()
463462
}
464-
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
465-
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
463+
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
464+
let f = op.to_scalar().to_f64()?;
465+
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
466+
.ok_or_else(|| {
467+
err_ub_format!(
468+
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
469+
dest.layout.ty
470+
)
471+
})?
472+
.into()
466473
}
474+
// Ptr-to-ptr cast
475+
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast =>
476+
this.ptr_to_ptr(&op, dest.layout.ty)?,
477+
// Ptr/Int casts
478+
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
479+
this.pointer_expose_address_cast(&op, dest.layout.ty)?,
480+
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
481+
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?,
467482
// Error otherwise
468483
_ =>
469484
throw_unsup_format!(

tests/fail/intrinsics/simd-float-to-int.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
1+
error: Undefined Behavior: `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
22
--> $DIR/simd-float-to-int.rs:LL:CC
33
|
44
LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
66
|
77
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

0 commit comments

Comments
 (0)