Remove float_to_int_unchecked
and inline it into its call sites
This commit is contained in:
parent
fe35dd1afc
commit
29b38ed76a
@ -9,7 +9,7 @@ use rustc_apfloat::{Float, Round};
|
|||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
mir,
|
mir,
|
||||||
ty::{self, FloatTy, Ty},
|
ty::{self, FloatTy},
|
||||||
};
|
};
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
|
|
||||||
@ -356,10 +356,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
let val = this.read_immediate(val)?;
|
let val = this.read_immediate(val)?;
|
||||||
|
|
||||||
let res = match val.layout.ty.kind() {
|
let res = match val.layout.ty.kind() {
|
||||||
ty::Float(FloatTy::F32) =>
|
ty::Float(FloatTy::F32) => {
|
||||||
this.float_to_int_unchecked(val.to_scalar().to_f32()?, dest.layout.ty)?,
|
let f = val.to_scalar().to_f32()?;
|
||||||
ty::Float(FloatTy::F64) =>
|
this
|
||||||
this.float_to_int_unchecked(val.to_scalar().to_f64()?, dest.layout.ty)?,
|
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
err_ub_format!(
|
||||||
|
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||||
|
dest.layout.ty
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
ty::Float(FloatTy::F64) => {
|
||||||
|
let f = val.to_scalar().to_f64()?;
|
||||||
|
this
|
||||||
|
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
err_ub_format!(
|
||||||
|
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||||
|
dest.layout.ty
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
}
|
||||||
_ =>
|
_ =>
|
||||||
span_bug!(
|
span_bug!(
|
||||||
this.cur_span(),
|
this.cur_span(),
|
||||||
@ -383,20 +401,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn float_to_int_unchecked<F>(
|
|
||||||
&self,
|
|
||||||
f: F,
|
|
||||||
dest_ty: Ty<'tcx>,
|
|
||||||
) -> InterpResult<'tcx, Scalar<Provenance>>
|
|
||||||
where
|
|
||||||
F: Float + Into<Scalar<Provenance>>,
|
|
||||||
{
|
|
||||||
let this = self.eval_context_ref();
|
|
||||||
Ok(this
|
|
||||||
.float_to_int_checked(f, dest_ty, Round::TowardZero)
|
|
||||||
.ok_or_else(|| err_ub_format!(
|
|
||||||
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`",
|
|
||||||
))?)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use rustc_apfloat::Float;
|
use rustc_apfloat::{Float, Round};
|
||||||
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
|
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
|
||||||
use rustc_middle::{mir, ty, ty::FloatTy};
|
use rustc_middle::{mir, ty, ty::FloatTy};
|
||||||
use rustc_target::abi::{Endian, HasDataLayout, Size};
|
use rustc_target::abi::{Endian, HasDataLayout, Size};
|
||||||
@ -420,7 +420,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[rustfmt::skip]
|
|
||||||
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
|
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
|
||||||
let [op] = check_arg_count(args)?;
|
let [op] = check_arg_count(args)?;
|
||||||
let (op, op_len) = this.operand_to_simd(op)?;
|
let (op, op_len) = this.operand_to_simd(op)?;
|
||||||
@ -440,7 +439,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
|
|
||||||
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
|
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
|
||||||
// Int-to-(int|float): always safe
|
// Int-to-(int|float): always safe
|
||||||
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast =>
|
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_))
|
||||||
|
if safe_cast || unsafe_cast =>
|
||||||
this.int_to_int_or_float(&op, dest.layout.ty)?,
|
this.int_to_int_or_float(&op, dest.layout.ty)?,
|
||||||
// Float-to-float: always safe
|
// Float-to-float: always safe
|
||||||
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
|
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
|
||||||
@ -449,21 +449,36 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||||||
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
|
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
|
||||||
this.float_to_float_or_int(&op, dest.layout.ty)?,
|
this.float_to_float_or_int(&op, dest.layout.ty)?,
|
||||||
// Float-to-int in unchecked mode
|
// Float-to-int in unchecked mode
|
||||||
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
|
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
|
||||||
this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(),
|
let f = op.to_scalar().to_f32()?;
|
||||||
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
|
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||||
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
|
.ok_or_else(|| {
|
||||||
|
err_ub_format!(
|
||||||
|
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||||
|
dest.layout.ty
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
|
||||||
|
let f = op.to_scalar().to_f64()?;
|
||||||
|
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||||
|
.ok_or_else(|| {
|
||||||
|
err_ub_format!(
|
||||||
|
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||||
|
dest.layout.ty
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.into()
|
||||||
|
}
|
||||||
// Ptr-to-ptr cast
|
// Ptr-to-ptr cast
|
||||||
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
|
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast =>
|
||||||
this.ptr_to_ptr(&op, dest.layout.ty)?
|
this.ptr_to_ptr(&op, dest.layout.ty)?,
|
||||||
}
|
|
||||||
// Ptr/Int casts
|
// Ptr/Int casts
|
||||||
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
|
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
|
||||||
this.pointer_expose_address_cast(&op, dest.layout.ty)?
|
this.pointer_expose_address_cast(&op, dest.layout.ty)?,
|
||||||
}
|
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
|
||||||
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
|
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?,
|
||||||
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
|
|
||||||
}
|
|
||||||
// Error otherwise
|
// Error otherwise
|
||||||
_ =>
|
_ =>
|
||||||
throw_unsup_format!(
|
throw_unsup_format!(
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
error: Undefined Behavior: `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||||
--> $DIR/simd-float-to-int.rs:LL:CC
|
--> $DIR/simd-float-to-int.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
|
LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||||
|
|
|
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
Loading…
x
Reference in New Issue
Block a user