factor SIMD bool handling into helper functions
This commit is contained in:
parent
e05a543f74
commit
f672282bf2
2 changed files with 18 additions and 13 deletions
|
|
@ -758,3 +758,18 @@ pub fn immty_from_uint_checked<'tcx>(
|
|||
err_unsup_format!("unsigned value {:#x} does not fit in {} bits", int, layout.size.bits())
|
||||
})?)
|
||||
}
|
||||
|
||||
pub fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Tag> {
|
||||
// SIMD uses all-1 as pattern for "true"
|
||||
let val = if b { -1 } else { 0 };
|
||||
Scalar::from_int(val, size)
|
||||
}
|
||||
|
||||
pub fn simd_element_to_bool<'tcx>(elem: ImmTy<'tcx, Tag>) -> InterpResult<'tcx, bool> {
|
||||
let val = elem.to_scalar()?.to_int(elem.layout.size)?;
|
||||
Ok(match val {
|
||||
0 => false,
|
||||
-1 => true,
|
||||
_ => throw_ub_format!("each element of a SIMD mask must be all-0-bits or all-1-bits"),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use rustc_middle::{mir, mir::BinOp, ty, ty::FloatTy};
|
|||
use rustc_target::abi::{Align, Integer};
|
||||
|
||||
use crate::*;
|
||||
use helpers::check_arg_count;
|
||||
use helpers::{bool_to_simd_element, check_arg_count, simd_element_to_bool};
|
||||
|
||||
pub enum AtomicOp {
|
||||
MirOp(mir::BinOp, bool),
|
||||
|
|
@ -365,8 +365,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
// Special handling for boolean-returning operations
|
||||
assert_eq!(ty, this.tcx.types.bool);
|
||||
let val = val.to_bool().unwrap();
|
||||
let val = if val { -1 } else { 0 }; // SIMD uses all-1 as pattern for "true"
|
||||
let val = Scalar::from_int(val, dest.layout.size);
|
||||
let val = bool_to_simd_element(val, dest.layout.size);
|
||||
this.write_scalar(val, &dest.into())?;
|
||||
} else {
|
||||
assert_eq!(ty, dest.layout.ty);
|
||||
|
|
@ -381,16 +380,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
let mut res = false; // the neutral element
|
||||
for i in 0..arg_len {
|
||||
let op = this.read_immediate(&this.mplace_index(&arg, i)?.into())?;
|
||||
// We convert it to a *signed* integer and expect either 0 or -1 (the latter means all bits were set).
|
||||
let val = op.to_scalar()?.to_int(op.layout.size)?;
|
||||
let val = match val {
|
||||
0 => false,
|
||||
-1 => true,
|
||||
_ =>
|
||||
throw_ub_format!(
|
||||
"each element of a simd_reduce_any operand must be all-0-bits or all-1-bits"
|
||||
),
|
||||
};
|
||||
let val = simd_element_to_bool(op)?;
|
||||
res = res | val;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue