From f672282bf25db5670f5809f78b1cd701037cc2dc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 1 Mar 2022 18:15:39 -0500 Subject: [PATCH] factor SIMD bool handling into helper functions --- src/helpers.rs | 15 +++++++++++++++ src/shims/intrinsics.rs | 16 +++------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 0c4e0c4e969e..2f1c74a0587e 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -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 { + // 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"), + }) +} diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index a75367b82c12..74914963f74c 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -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; }