cranelift: Remove booleans (#5031)

Remove the boolean types from cranelift, and the associated instructions breduce, bextend, bconst, and bint. Standardize on using 1/0 for the return value from instructions that produce scalar boolean results, and -1/0 for boolean vector elements.

Fixes #3205

Co-authored-by: Afonso Bordado <afonso360@users.noreply.github.com>
Co-authored-by: Ulrich Weigand <ulrich.weigand@de.ibm.com>
Co-authored-by: Chris Fallin <chris@cfallin.org>
This commit is contained in:
Trevor Elliott
2022-10-17 16:00:27 -07:00
committed by GitHub
parent 766ecb561e
commit 32a7593c94
242 changed files with 7695 additions and 10010 deletions

View File

@@ -12,7 +12,6 @@ use core::fmt::{self, Display, Formatter};
#[allow(missing_docs)]
#[derive(Clone, Debug, PartialOrd)]
pub enum DataValue {
B(bool),
I8(i8),
I16(i16),
I32(i32),
@@ -33,8 +32,6 @@ impl PartialEq for DataValue {
fn eq(&self, other: &Self) -> bool {
use DataValue::*;
match (self, other) {
(B(l), B(r)) => l == r,
(B(_), _) => false,
(I8(l), I8(r)) => l == r,
(I8(_), _) => false,
(I16(l), I16(r)) => l == r,
@@ -84,7 +81,6 @@ impl DataValue {
/// Return the Cranelift IR [Type] for this [DataValue].
pub fn ty(&self) -> Type {
match self {
DataValue::B(_) => types::B8, // A default type.
DataValue::I8(_) | DataValue::U8(_) => types::I8,
DataValue::I16(_) | DataValue::U16(_) => types::I16,
DataValue::I32(_) | DataValue::U32(_) => types::I32,
@@ -105,14 +101,6 @@ impl DataValue {
}
}
/// Return true if the value is a bool (i.e. `DataValue::B`).
pub fn is_bool(&self) -> bool {
match self {
DataValue::B(_) => true,
_ => false,
}
}
/// Write a [DataValue] to a slice.
///
/// # Panics:
@@ -120,8 +108,6 @@ impl DataValue {
/// Panics if the slice does not have enough space to accommodate the [DataValue]
pub fn write_to_slice(&self, dst: &mut [u8]) {
match self {
DataValue::B(true) => dst[..16].copy_from_slice(&[u8::MAX; 16][..]),
DataValue::B(false) => dst[..16].copy_from_slice(&[0; 16][..]),
DataValue::I8(i) => dst[..1].copy_from_slice(&i.to_ne_bytes()[..]),
DataValue::I16(i) => dst[..2].copy_from_slice(&i.to_ne_bytes()[..]),
DataValue::I32(i) => dst[..4].copy_from_slice(&i.to_ne_bytes()[..]),
@@ -153,13 +139,6 @@ impl DataValue {
types::F64 => DataValue::F64(Ieee64::with_bits(u64::from_ne_bytes(
src[..8].try_into().unwrap(),
))),
_ if ty.is_bool() => {
// Only `ty.bytes()` are guaranteed to be written
// so we can only test the first n bytes of `src`
let size = ty.bytes() as usize;
DataValue::B(src[..size].iter().any(|&i| i != 0))
}
_ if ty.is_vector() => {
if ty.bytes() == 16 {
DataValue::V128(src[..16].try_into().unwrap())
@@ -175,13 +154,7 @@ impl DataValue {
/// Write a [DataValue] to a memory location.
pub unsafe fn write_value_to(&self, p: *mut u128) {
// Since `DataValue` does not have type info for bools we always
// write out a full 16 byte slot.
let size = match self.ty() {
ty if ty.is_bool() => 16,
ty => ty.bytes() as usize,
};
let size = self.ty().bytes() as usize;
self.write_to_slice(std::slice::from_raw_parts_mut(p as *mut u8, size));
}
@@ -270,7 +243,6 @@ macro_rules! build_conversion_impl {
}
};
}
build_conversion_impl!(bool, B, B8);
build_conversion_impl!(i8, I8, I8);
build_conversion_impl!(i16, I16, I16);
build_conversion_impl!(i32, I32, I32);
@@ -294,7 +266,6 @@ impl From<Offset32> for DataValue {
impl Display for DataValue {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
DataValue::B(dv) => write!(f, "{}", dv),
DataValue::I8(dv) => write!(f, "{}", dv),
DataValue::I16(dv) => write!(f, "{}", dv),
DataValue::I32(dv) => write!(f, "{}", dv),
@@ -354,16 +325,6 @@ mod test {
#[test]
fn type_conversions() {
assert_eq!(DataValue::B(true).ty(), types::B8);
assert_eq!(
TryInto::<bool>::try_into(DataValue::B(false)).unwrap(),
false
);
assert_eq!(
TryInto::<i32>::try_into(DataValue::B(false)).unwrap_err(),
DataValueCastFailure::TryInto(types::B8, types::I32)
);
assert_eq!(DataValue::V128([0; 16]).ty(), types::I8X16);
assert_eq!(
TryInto::<[u8; 16]>::try_into(DataValue::V128([0; 16])).unwrap(),