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"),
+ })
+}
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),
// 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);
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;
}