diff --git a/cranelift/filetests/filetests/runtests/bextend.clif b/cranelift/filetests/filetests/runtests/bextend.clif new file mode 100644 index 0000000000..9f78fd9d2b --- /dev/null +++ b/cranelift/filetests/filetests/runtests/bextend.clif @@ -0,0 +1,84 @@ +test interpret + +function %bextend_b1_b8(b1) -> b8 { +block0(v0: b1): + v1 = bextend.b8 v0 + return v1 +} +; run: %bextend_b1_b8(true) == true +; run: %bextend_b1_b8(false) == false + +function %bextend_b1_b16(b1) -> b16 { +block0(v0: b1): + v1 = bextend.b16 v0 + return v1 +} +; run: %bextend_b1_b16(true) == true +; run: %bextend_b1_b16(false) == false + +function %bextend_b1_b32(b1) -> b32 { +block0(v0: b1): + v1 = bextend.b32 v0 + return v1 +} +; run: %bextend_b1_b32(true) == true +; run: %bextend_b1_b32(false) == false + +function %bextend_b1_b64(b1) -> b64 { +block0(v0: b1): + v1 = bextend.b64 v0 + return v1 +} +; run: %bextend_b1_b64(true) == true +; run: %bextend_b1_b64(false) == false + + +function %bextend_b8_b16(b8) -> b16 { +block0(v0: b8): + v1 = bextend.b16 v0 + return v1 +} +; run: %bextend_b8_b16(true) == true +; run: %bextend_b8_b16(false) == false + +function %bextend_b8_b32(b8) -> b32 { +block0(v0: b8): + v1 = bextend.b32 v0 + return v1 +} +; run: %bextend_b8_b32(true) == true +; run: %bextend_b8_b32(false) == false + +function %bextend_b8_b64(b8) -> b64 { +block0(v0: b8): + v1 = bextend.b64 v0 + return v1 +} +; run: %bextend_b8_b64(true) == true +; run: %bextend_b8_b64(false) == false + + +function %bextend_b16_b32(b16) -> b32 { +block0(v0: b16): + v1 = bextend.b32 v0 + return v1 +} +; run: %bextend_b16_b32(true) == true +; run: %bextend_b16_b32(false) == false + +function %bextend_b16_b64(b16) -> b64 { +block0(v0: b16): + v1 = bextend.b64 v0 + return v1 +} +; run: %bextend_b16_b64(true) == true +; run: %bextend_b16_b64(false) == false + + +function %bextend_b32_b64(b32) -> b64 { +block0(v0: b32): + v1 = bextend.b64 v0 + return v1 +} +; run: %bextend_b32_b64(true) == true +; run: %bextend_b32_b64(false) == false diff --git a/cranelift/filetests/filetests/runtests/bmask.clif b/cranelift/filetests/filetests/runtests/bmask.clif new file mode 100644 index 0000000000..d68e59ec00 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/bmask.clif @@ -0,0 +1,161 @@ +test interpret + +function %bmask_b64_i64(b64) -> i64 { +block0(v0: b64): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b64_i64(true) == -1 +; run: %bmask_b64_i64(false) == 0 + +function %bmask_b64_i32(b64) -> i32 { +block0(v0: b64): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b64_i32(true) == -1 +; run: %bmask_b64_i32(false) == 0 + +function %bmask_b64_i16(b64) -> i16 { +block0(v0: b64): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b64_i16(true) == -1 +; run: %bmask_b64_i16(false) == 0 + +function %bmask_b64_i8(b64) -> i8 { +block0(v0: b64): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b64_i8(true) == -1 +; run: %bmask_b64_i8(false) == 0 + +function %bmask_b32_i64(b32) -> i64 { +block0(v0: b32): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b32_i64(true) == -1 +; run: %bmask_b32_i64(false) == 0 + +function %bmask_b32_i32(b32) -> i32 { +block0(v0: b32): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b32_i32(true) == -1 +; run: %bmask_b32_i32(false) == 0 + +function %bmask_b32_i16(b32) -> i16 { +block0(v0: b32): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b32_i16(true) == -1 +; run: %bmask_b32_i16(false) == 0 + +function %bmask_b32_i8(b32) -> i8 { +block0(v0: b32): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b32_i8(true) == -1 +; run: %bmask_b32_i8(false) == 0 + +function %bmask_b16_i64(b16) -> i64 { +block0(v0: b16): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b16_i64(true) == -1 +; run: %bmask_b16_i64(false) == 0 + +function %bmask_b16_i32(b16) -> i32 { +block0(v0: b16): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b16_i32(true) == -1 +; run: %bmask_b16_i32(false) == 0 + +function %bmask_b16_i16(b16) -> i16 { +block0(v0: b16): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b16_i16(true) == -1 +; run: %bmask_b16_i16(false) == 0 + +function %bmask_b16_i8(b16) -> i8 { +block0(v0: b16): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b16_i8(true) == -1 +; run: %bmask_b16_i8(false) == 0 + +function %bmask_b8_i64(b8) -> i64 { +block0(v0: b8): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b8_i64(true) == -1 +; run: %bmask_b8_i64(false) == 0 + +function %bmask_b8_i32(b8) -> i32 { +block0(v0: b8): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b8_i32(true) == -1 +; run: %bmask_b8_i32(false) == 0 + +function %bmask_b8_i16(b8) -> i16 { +block0(v0: b8): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b8_i16(true) == -1 +; run: %bmask_b8_i16(false) == 0 + +function %bmask_b8_i8(b8) -> i8 { +block0(v0: b8): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b8_i8(true) == -1 +; run: %bmask_b8_i8(false) == 0 + +function %bmask_b1_i64(b1) -> i64 { +block0(v0: b1): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b1_i64(true) == -1 +; run: %bmask_b1_i64(false) == 0 + +function %bmask_b1_i32(b1) -> i32 { +block0(v0: b1): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b1_i32(true) == -1 +; run: %bmask_b1_i32(false) == 0 + +function %bmask_b1_i16(b1) -> i16 { +block0(v0: b1): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b1_i16(true) == -1 +; run: %bmask_b1_i16(false) == 0 + +function %bmask_b1_i8(b1) -> i8 { +block0(v0: b1): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b1_i8(true) == -1 +; run: %bmask_b1_i8(false) == 0 diff --git a/cranelift/filetests/filetests/runtests/breduce.clif b/cranelift/filetests/filetests/runtests/breduce.clif new file mode 100644 index 0000000000..e436b3f800 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/breduce.clif @@ -0,0 +1,85 @@ +test interpret + +function %breduce_b8_b1(b8) -> b1 { +block0(v0: b8): + v1 = breduce.b1 v0 + return v1 +} +; run: %breduce_b8_b1(true) == true +; run: %breduce_b8_b1(false) == false + + +function %breduce_b16_b1(b16) -> b1 { +block0(v0: b16): + v1 = breduce.b1 v0 + return v1 +} +; run: %breduce_b16_b1(true) == true +; run: %breduce_b16_b1(false) == false + +function %breduce_b16_b8(b16) -> b8 { +block0(v0: b16): + v1 = breduce.b8 v0 + return v1 +} +; run: %breduce_b16_b8(true) == true +; run: %breduce_b16_b8(false) == false + + +function %breduce_b32_b1(b32) -> b1 { +block0(v0: b32): + v1 = breduce.b1 v0 + return v1 +} +; run: %breduce_b32_b1(true) == true +; run: %breduce_b32_b1(false) == false + +function %breduce_b32_b8(b32) -> b8 { +block0(v0: b32): + v1 = breduce.b8 v0 + return v1 +} +; run: %breduce_b32_b8(true) == true +; run: %breduce_b32_b8(false) == false + +function %breduce_b32_b16(b32) -> b16 { +block0(v0: b32): + v1 = breduce.b16 v0 + return v1 +} +; run: %breduce_b32_b16(true) == true +; run: %breduce_b32_b16(false) == false + + + +function %breduce_b64_b1(b64) -> b1 { +block0(v0: b64): + v1 = breduce.b1 v0 + return v1 +} +; run: %breduce_b64_b1(true) == true +; run: %breduce_b64_b1(false) == false + +function %breduce_b64_b8(b64) -> b8 { +block0(v0: b64): + v1 = breduce.b8 v0 + return v1 +} +; run: %breduce_b64_b8(true) == true +; run: %breduce_b64_b8(false) == false + +function %breduce_b64_b16(b64) -> b16 { +block0(v0: b64): + v1 = breduce.b16 v0 + return v1 +} +; run: %breduce_b64_b16(true) == true +; run: %breduce_b64_b16(false) == false + +function %breduce_b64_b32(b64) -> b32 { +block0(v0: b64): + v1 = breduce.b32 v0 + return v1 +} +; run: %breduce_b64_b32(true) == true +; run: %breduce_b64_b32(false) == false diff --git a/cranelift/filetests/filetests/runtests/i128-bextend.clif b/cranelift/filetests/filetests/runtests/i128-bextend.clif new file mode 100644 index 0000000000..34372f98e4 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-bextend.clif @@ -0,0 +1,42 @@ +test interpret + +function %bextend_b1_b128(b1) -> b128 { +block0(v0: b1): + v1 = bextend.b128 v0 + return v1 +} +; run: %bextend_b1_b128(true) == true +; run: %bextend_b1_b128(false) == false + +function %bextend_b8_b128(b8) -> b128 { +block0(v0: b8): + v1 = bextend.b128 v0 + return v1 +} +; run: %bextend_b8_b128(true) == true +; run: %bextend_b8_b128(false) == false + +function %bextend_b16_b128(b16) -> b128 { +block0(v0: b16): + v1 = bextend.b128 v0 + return v1 +} +; run: %bextend_b16_b128(true) == true +; run: %bextend_b16_b128(false) == false + +function %bextend_b32_b128(b32) -> b128 { +block0(v0: b32): + v1 = bextend.b128 v0 + return v1 +} +; run: %bextend_b32_b128(true) == true +; run: %bextend_b32_b128(false) == false + + +function %bextend_b64_b128(b64) -> b128 { +block0(v0: b64): + v1 = bextend.b128 v0 + return v1 +} +; run: %bextend_b64_b128(true) == true +; run: %bextend_b64_b128(false) == false diff --git a/cranelift/filetests/filetests/runtests/i128-bmask.clif b/cranelift/filetests/filetests/runtests/i128-bmask.clif new file mode 100644 index 0000000000..f87df7f2ab --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-bmask.clif @@ -0,0 +1,82 @@ +test interpret + +function %bmask_b128_i128(b128) -> i128 { +block0(v0: b128): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b128_i128(true) == -1 +; run: %bmask_b128_i128(false) == 0 + +function %bmask_b128_i64(b128) -> i64 { +block0(v0: b128): + v1 = bmask.i64 v0 + return v1 +} +; run: %bmask_b128_i64(true) == -1 +; run: %bmask_b128_i64(false) == 0 + +function %bmask_b128_i32(b128) -> i32 { +block0(v0: b128): + v1 = bmask.i32 v0 + return v1 +} +; run: %bmask_b128_i32(true) == -1 +; run: %bmask_b128_i32(false) == 0 + +function %bmask_b128_i16(b128) -> i16 { +block0(v0: b128): + v1 = bmask.i16 v0 + return v1 +} +; run: %bmask_b128_i16(true) == -1 +; run: %bmask_b128_i16(false) == 0 + +function %bmask_b128_i8(b128) -> i8 { +block0(v0: b128): + v1 = bmask.i8 v0 + return v1 +} +; run: %bmask_b128_i8(true) == -1 +; run: %bmask_b128_i8(false) == 0 + + +function %bmask_b64_i128(b64) -> i128 { +block0(v0: b64): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b64_i128(true) == -1 +; run: %bmask_b64_i128(false) == 0 + +function %bmask_b32_i128(b32) -> i128 { +block0(v0: b32): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b32_i128(true) == -1 +; run: %bmask_b32_i128(false) == 0 + +function %bmask_b16_i128(b16) -> i128 { +block0(v0: b16): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b16_i128(true) == -1 +; run: %bmask_b16_i128(false) == 0 + +function %bmask_b8_i128(b8) -> i128 { +block0(v0: b8): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b8_i128(true) == -1 +; run: %bmask_b8_i128(false) == 0 + +function %bmask_b1_i128(b1) -> i128 { +block0(v0: b1): + v1 = bmask.i128 v0 + return v1 +} +; run: %bmask_b1_i128(true) == -1 +; run: %bmask_b1_i128(false) == 0 diff --git a/cranelift/filetests/filetests/runtests/i128-breduce.clif b/cranelift/filetests/filetests/runtests/i128-breduce.clif new file mode 100644 index 0000000000..93efa6c7a6 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-breduce.clif @@ -0,0 +1,41 @@ +test interpret + +function %breduce_b128_b1(b128) -> b1 { +block0(v0: b128): + v1 = breduce.b1 v0 + return v1 +} +; run: %breduce_b128_b1(true) == true +; run: %breduce_b128_b1(false) == false + +function %breduce_b128_b8(b128) -> b8 { +block0(v0: b128): + v1 = breduce.b8 v0 + return v1 +} +; run: %breduce_b128_b8(true) == true +; run: %breduce_b128_b8(false) == false + +function %breduce_b128_b16(b128) -> b16 { +block0(v0: b128): + v1 = breduce.b16 v0 + return v1 +} +; run: %breduce_b128_b16(true) == true +; run: %breduce_b128_b16(false) == false + +function %breduce_b128_b32(b128) -> b32 { +block0(v0: b128): + v1 = breduce.b32 v0 + return v1 +} +; run: %breduce_b128_b32(true) == true +; run: %breduce_b128_b32(false) == false + +function %breduce_b128_b64(b128) -> b64 { +block0(v0: b128): + v1 = breduce.b64 v0 + return v1 +} +; run: %breduce_b128_b64(true) == true +; run: %breduce_b128_b64(false) == false diff --git a/cranelift/filetests/filetests/runtests/simd-bmask.clif b/cranelift/filetests/filetests/runtests/simd-bmask.clif new file mode 100644 index 0000000000..ba504f7868 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-bmask.clif @@ -0,0 +1,30 @@ +test interpret + + +function %bmask_i8x16(b8x16) -> i8x16 { +block0(v0: b8x16): + v1 = bmask.i8x16 v0 + return v1 +} +; run: %bmask_i8x16([true false true false true false true false true false true false true false true false]) == [-1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0] + +function %bmask_i16x8(b16x8) -> i16x8 { +block0(v0: b16x8): + v1 = bmask.i16x8 v0 + return v1 +} +; run: %bmask_i16x8([true false true false true false true false]) == [-1 0 -1 0 -1 0 -1 0] + +function %bmask_i32x4(b32x4) -> i32x4 { +block0(v0: b32x4): + v1 = bmask.i32x4 v0 + return v1 +} +; run: %bmask_i32x4([true false true false]) == [-1 0 -1 0] + +function %bmask_i64x2(b64x2) -> i64x2 { +block0(v0: b64x2): + v1 = bmask.i64x2 v0 + return v1 +} +; run: %bmask_i64x2([true false]) == [-1 0] diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 7fc16b06f7..a64adccdb0 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -767,7 +767,6 @@ where | Opcode::Breduce | Opcode::Bextend | Opcode::Bint - | Opcode::Bmask | Opcode::Ireduce => assign(Value::convert( arg(0)?, ValueConversionKind::Exact(ctrl_ty), @@ -802,6 +801,19 @@ where .collect::>>()?; assign(vectorizelanes(&new_vec, new_type)?) } + Opcode::Bmask => assign({ + let bool = arg(0)?; + let bool_ty = ctrl_ty.as_bool_pedantic(); + if ctrl_ty.is_vector() { + let lanes = extractlanes(&bool, bool_ty.lane_type())? + .into_iter() + .map(|lane| lane.convert(ValueConversionKind::Exact(ctrl_ty.lane_type()))) + .collect::>>()?; + vectorizelanes(&lanes, ctrl_ty)? + } else { + bool.convert(ValueConversionKind::Exact(ctrl_ty))? + } + }), Opcode::Sextend => assign(Value::convert( arg(0)?, ValueConversionKind::SignExtend(ctrl_ty), diff --git a/cranelift/interpreter/src/value.rs b/cranelift/interpreter/src/value.rs index c5727892cc..70f6ac78d6 100644 --- a/cranelift/interpreter/src/value.rs +++ b/cranelift/interpreter/src/value.rs @@ -277,11 +277,11 @@ impl Value for DataValue { (DataValue::I64(n), types::I128) => DataValue::I128(n as i128), (DataValue::B(b), t) if t.is_bool() => DataValue::B(b), (DataValue::B(b), t) if t.is_int() => { - let val = if b { - // Bools are represented in memory as all 1's - (1i128 << t.bits()) - 1 - } else { - 0 + // Bools are represented in memory as all 1's + let val = match (b, t) { + (true, types::I128) => -1, + (true, t) => (1i128 << t.bits()) - 1, + _ => 0, }; DataValue::int(val, t)? }