Skip to content

Commit

Permalink
Switch DataValue to use Ieee32/Ieee64
Browse files Browse the repository at this point in the history
As discussed in bytecodealliance#2251, in order to be very confident that NaN signaling bits are correctly handled by the compiler, this switches `DataValue` to use Cranelift's `Ieee32` and `Ieee64` structures. This makes it a bit more inconvenient to interpreter Cranelift FP operations but this should change to something like `rustc_apfloat` in the future.
  • Loading branch information
abrown committed Oct 7, 2020
1 parent b7afac9 commit c7aac34
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 28 deletions.
24 changes: 7 additions & 17 deletions cranelift/codegen/src/data_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub enum DataValue {
I16(i16),
I32(i32),
I64(i64),
F32(f32),
F64(f64),
F32(Ieee32),
F64(Ieee64),
V128([u8; 16]),
}

Expand Down Expand Up @@ -97,19 +97,9 @@ build_conversion_impl!(i8, I8, I8);
build_conversion_impl!(i16, I16, I16);
build_conversion_impl!(i32, I32, I32);
build_conversion_impl!(i64, I64, I64);
build_conversion_impl!(f32, F32, F32);
build_conversion_impl!(f64, F64, F64);
build_conversion_impl!(Ieee32, F32, F32);
build_conversion_impl!(Ieee64, F64, F64);
build_conversion_impl!([u8; 16], V128, I8X16);
impl From<Ieee64> for DataValue {
fn from(f: Ieee64) -> Self {
DataValue::from(f64::from_bits(f.bits()))
}
}
impl From<Ieee32> for DataValue {
fn from(f: Ieee32) -> Self {
DataValue::from(f32::from_bits(f.bits()))
}
}
impl From<Offset32> for DataValue {
fn from(o: Offset32) -> Self {
DataValue::from(Into::<i32>::into(o))
Expand All @@ -124,9 +114,9 @@ impl Display for DataValue {
DataValue::I16(dv) => write!(f, "{}", dv),
DataValue::I32(dv) => write!(f, "{}", dv),
DataValue::I64(dv) => write!(f, "{}", dv),
// Use the Ieee* wrappers here to maintain a consistent syntax.
DataValue::F32(dv) => write!(f, "{}", Ieee32::from(*dv)),
DataValue::F64(dv) => write!(f, "{}", Ieee64::from(*dv)),
// The Ieee* wrappers here print the expected syntax.
DataValue::F32(dv) => write!(f, "{}", dv),
DataValue::F64(dv) => write!(f, "{}", dv),
// Again, for syntax consistency, use ConstantData, which in this case displays as hex.
DataValue::V128(dv) => write!(f, "{}", ConstantData::from(&dv[..])),
}
Expand Down
9 changes: 5 additions & 4 deletions cranelift/filetests/src/function_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use core::{mem, ptr};
use cranelift_codegen::binemit::{NullRelocSink, NullStackMapSink, NullTrapSink};
use cranelift_codegen::data_value::DataValue;
use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
use cranelift_codegen::ir::{condcodes::IntCC, Function, InstBuilder, Signature, Type};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::{ir, settings, CodegenError, Context};
Expand Down Expand Up @@ -233,8 +234,8 @@ impl UnboxedValues {
DataValue::I16(i) => ptr::write(p as *mut i16, *i),
DataValue::I32(i) => ptr::write(p as *mut i32, *i),
DataValue::I64(i) => ptr::write(p as *mut i64, *i),
DataValue::F32(f) => ptr::write(p as *mut f32, *f),
DataValue::F64(f) => ptr::write(p as *mut f64, *f),
DataValue::F32(f) => ptr::write(p as *mut Ieee32, *f),
DataValue::F64(f) => ptr::write(p as *mut Ieee64, *f),
DataValue::V128(b) => ptr::write(p as *mut [u8; 16], *b),
}
}
Expand All @@ -246,8 +247,8 @@ impl UnboxedValues {
ir::types::I16 => DataValue::I16(ptr::read(p as *const i16)),
ir::types::I32 => DataValue::I32(ptr::read(p as *const i32)),
ir::types::I64 => DataValue::I64(ptr::read(p as *const i64)),
ir::types::F32 => DataValue::F32(ptr::read(p as *const f32)),
ir::types::F64 => DataValue::F64(ptr::read(p as *const f64)),
ir::types::F32 => DataValue::F32(ptr::read(p as *const Ieee32)),
ir::types::F64 => DataValue::F64(ptr::read(p as *const Ieee64)),
_ if ty.is_bool() => DataValue::B(ptr::read(p as *const bool)),
_ if ty.is_vector() && ty.bytes() == 16 => {
DataValue::V128(ptr::read(p as *const [u8; 16]))
Expand Down
11 changes: 6 additions & 5 deletions cranelift/interpreter/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use cranelift_codegen::ir::{
Value as ValueRef, ValueList,
};
use log::trace;
use std::ops::{Add, Div, Mul, Sub};
use std::ops::{Add, Mul, Sub};
use thiserror::Error;

/// The valid control flow states.
Expand Down Expand Up @@ -153,10 +153,11 @@ impl Interpreter {
Iadd => binary_op!(Add::add[arg1, arg2]; [I8, I16, I32, I64]; inst),
Isub => binary_op!(Sub::sub[arg1, arg2]; [I8, I16, I32, I64]; inst),
Imul => binary_op!(Mul::mul[arg1, arg2]; [I8, I16, I32, I64]; inst),
Fadd => binary_op!(Add::add[arg1, arg2]; [F32, F64]; inst),
Fsub => binary_op!(Sub::sub[arg1, arg2]; [F32, F64]; inst),
Fmul => binary_op!(Mul::mul[arg1, arg2]; [F32, F64]; inst),
Fdiv => binary_op!(Div::div[arg1, arg2]; [F32, F64]; inst),
// TODO re-enable by importing something like rustc_apfloat for correctness.
// Fadd => binary_op!(Add::add[arg1, arg2]; [F32, F64]; inst),
// Fsub => binary_op!(Sub::sub[arg1, arg2]; [F32, F64]; inst),
// Fmul => binary_op!(Mul::mul[arg1, arg2]; [F32, F64]; inst),
// Fdiv => binary_op!(Div::div[arg1, arg2]; [F32, F64]; inst),
_ => unimplemented!("interpreter does not support opcode yet: {}", opcode),
}?;
frame.set(first_result(frame.function, inst), result);
Expand Down
4 changes: 2 additions & 2 deletions cranelift/reader/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2700,8 +2700,8 @@ impl<'a> Parser<'a> {
I16 => DataValue::from(self.match_imm16("expected an i16")?),
I32 => DataValue::from(self.match_imm32("expected an i32")?),
I64 => DataValue::from(Into::<i64>::into(self.match_imm64("expected an i64")?)),
F32 => DataValue::from(f32::from_bits(self.match_ieee32("expected an f32")?.bits())),
F64 => DataValue::from(f64::from_bits(self.match_ieee64("expected an f64")?.bits())),
F32 => DataValue::from(self.match_ieee32("expected an f32")?),
F64 => DataValue::from(self.match_ieee64("expected an f64")?),
_ if ty.is_vector() => {
let as_vec = self.match_uimm128(ty)?.into_vec();
if as_vec.len() == 16 {
Expand Down

0 comments on commit c7aac34

Please sign in to comment.