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_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::{
|
||||
mir,
|
||||
ty::{self, FloatTy, Ty},
|
||||
ty::{self, FloatTy},
|
||||
};
|
||||
use rustc_target::abi::Size;
|
||||
|
||||
@ -356,10 +356,28 @@ fn emulate_intrinsic_by_name(
|
||||
let val = this.read_immediate(val)?;
|
||||
|
||||
let res = match val.layout.ty.kind() {
|
||||
ty::Float(FloatTy::F32) =>
|
||||
this.float_to_int_unchecked(val.to_scalar().to_f32()?, dest.layout.ty)?,
|
||||
ty::Float(FloatTy::F64) =>
|
||||
this.float_to_int_unchecked(val.to_scalar().to_f64()?, dest.layout.ty)?,
|
||||
ty::Float(FloatTy::F32) => {
|
||||
let f = val.to_scalar().to_f32()?;
|
||||
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
|
||||
)
|
||||
})?
|
||||
}
|
||||
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!(
|
||||
this.cur_span(),
|
||||
@ -383,20 +401,4 @@ fn emulate_intrinsic_by_name(
|
||||
|
||||
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::{mir, ty, ty::FloatTy};
|
||||
use rustc_target::abi::{Endian, HasDataLayout, Size};
|
||||
@ -420,7 +420,6 @@ enum Op {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
|
||||
let [op] = check_arg_count(args)?;
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
@ -440,7 +439,8 @@ enum Op {
|
||||
|
||||
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
|
||||
// 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)?,
|
||||
// Float-to-float: always safe
|
||||
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
|
||||
@ -449,21 +449,36 @@ enum Op {
|
||||
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
|
||||
this.float_to_float_or_int(&op, dest.layout.ty)?,
|
||||
// Float-to-int in unchecked mode
|
||||
(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(),
|
||||
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
|
||||
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
|
||||
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
|
||||
let f = op.to_scalar().to_f32()?;
|
||||
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()
|
||||
}
|
||||
(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
|
||||
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
|
||||
this.ptr_to_ptr(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast =>
|
||||
this.ptr_to_ptr(&op, dest.layout.ty)?,
|
||||
// Ptr/Int casts
|
||||
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
|
||||
this.pointer_expose_address_cast(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
|
||||
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
|
||||
this.pointer_expose_address_cast(&op, dest.layout.ty)?,
|
||||
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
|
||||
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?,
|
||||
// Error otherwise
|
||||
_ =>
|
||||
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
|
||||
|
|
||||
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: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
Loading…
Reference in New Issue
Block a user