diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index 901c48748e..5057ea3251 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -718,6 +718,12 @@ pub(crate) fn define( .build(), ); + let ScalarBool = &TypeVar::new( + "ScalarBool", + "A scalar boolean type", + TypeSetBuilder::new().bools(Interval::All).build(), + ); + let iB = &TypeVar::new( "iB", "A scalar integer type", @@ -3331,13 +3337,10 @@ pub(crate) fn define( let IntTo = &TypeVar::new( "IntTo", - "An integer type with the same number of lanes", - TypeSetBuilder::new() - .ints(Interval::All) - .simd_lanes(Interval::All) - .build(), + "A scalar integer type", + TypeSetBuilder::new().ints(Interval::All).build(), ); - let x = &Operand::new("x", Bool); + let x = &Operand::new("x", ScalarBool); let a = &Operand::new("a", IntTo); ig.push( @@ -3346,8 +3349,7 @@ pub(crate) fn define( r#" Convert `x` to an integer. - True maps to 1 and false maps to 0. The result type must have the same - number of vector lanes as the input. + True maps to 1 and false maps to 0. "#, &formats.unary, ) @@ -3355,6 +3357,17 @@ pub(crate) fn define( .operands_out(vec![a]), ); + let IntTo = &TypeVar::new( + "IntTo", + "An integer type with the same number of lanes", + TypeSetBuilder::new() + .ints(Interval::All) + .simd_lanes(Interval::All) + .build(), + ); + let x = &Operand::new("x", Bool); + let a = &Operand::new("a", IntTo); + ig.push( Inst::new( "bmask", diff --git a/cranelift/filetests/filetests/runtests/bint.clif b/cranelift/filetests/filetests/runtests/bint.clif index cce35d1c7f..f107d12648 100644 --- a/cranelift/filetests/filetests/runtests/bint.clif +++ b/cranelift/filetests/filetests/runtests/bint.clif @@ -1,7 +1,91 @@ +test interpret test run target aarch64 target x86_64 +function %bint_b1_i8_true() -> i8 { +block0: + v0 = bconst.b1 true + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b1_i8_true() == 1 + +function %bint_b1_i8_false() -> i8 { +block0: + v0 = bconst.b1 false + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b1_i8_false() == 0 + +function %bint_b1_i16_true() -> i16 { +block0: + v0 = bconst.b1 true + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b1_i16_true() == 1 + +function %bint_b1_i16_false() -> i16 { +block0: + v0 = bconst.b1 false + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b1_i16_fals() == 0 + +function %bint_b1_i32_true() -> i32 { +block0: + v0 = bconst.b1 true + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b1_i32_true() == 1 + +function %bint_b1_i32_false() -> i32 { +block0: + v0 = bconst.b1 false + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b1_i32_fals() == 0 + +function %bint_b1_i64_true() -> i64 { +block0: + v0 = bconst.b1 true + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b1_i64_true() == 1 + +function %bint_b1_i64_false() -> i64 { +block0: + v0 = bconst.b1 false + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b1_i64_fals() == 0 + + + + +function %bint_b8_i8_true() -> i8 { +block0: + v0 = bconst.b8 true + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b8_i8_true() == 1 + +function %bint_b8_i8_false() -> i8 { +block0: + v0 = bconst.b8 false + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b8_i8_false() == 0 + function %bint_b8_i16_true() -> i16 { block0: v0 = bconst.b8 true @@ -10,6 +94,65 @@ block0: } ; run: %bint_b8_i16_true() == 1 +function %bint_b8_i16_false() -> i16 { +block0: + v0 = bconst.b8 false + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b8_i16_fals() == 0 + +function %bint_b8_i32_true() -> i32 { +block0: + v0 = bconst.b8 true + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b8_i32_true() == 1 + +function %bint_b8_i32_false() -> i32 { +block0: + v0 = bconst.b8 false + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b8_i32_fals() == 0 + +function %bint_b8_i64_true() -> i64 { +block0: + v0 = bconst.b8 true + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b8_i64_true() == 1 + +function %bint_b8_i64_false() -> i64 { +block0: + v0 = bconst.b8 false + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b8_i64_fals() == 0 + + + + + +function %bint_b16_i8_true() -> i8 { +block0: + v0 = bconst.b16 true + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b16_i8_true() == 1 + +function %bint_b16_i8_false() -> i8 { +block0: + v0 = bconst.b16 false + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b16_i8_fals() == 0 function %bint_b16_i16_true() -> i16 { block0: @@ -17,16 +160,7 @@ block0: v1 = bint.i16 v0 return v1 } -; run: %bint_b16_i16_true() == 1 - -function %bint_b8_i16_false() -> i16 { -block0: - v0 = bconst.b8 false - v1 = bint.i16 v0 - return v1 -} -; run: %bint_b8_i16_false() == 0 - +; run: %bint_b16_i16_tru() == 1 function %bint_b16_i16_false() -> i16 { block0: @@ -34,4 +168,172 @@ block0: v1 = bint.i16 v0 return v1 } -; run: %bint_b16_i16_false() == 0 +; run: %bint_b16_i16_fal() == 0 + +function %bint_b16_i32_true() -> i32 { +block0: + v0 = bconst.b16 true + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b16_i32_tru() == 1 + +function %bint_b16_i32_false() -> i32 { +block0: + v0 = bconst.b16 false + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b16_i32_fal() == 0 + +function %bint_b16_i64_true() -> i64 { +block0: + v0 = bconst.b16 true + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b16_i64_tru() == 1 + +function %bint_b16_i64_false() -> i64 { +block0: + v0 = bconst.b16 false + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b16_i64_fal() == 0 + + + + +function %bint_b32_i8_true() -> i8 { +block0: + v0 = bconst.b32 true + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b32_i8_true() == 1 + +function %bint_b32_i8_false() -> i8 { +block0: + v0 = bconst.b32 false + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b32_i8_fals() == 0 + +function %bint_b32_i16_true() -> i16 { +block0: + v0 = bconst.b32 true + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b32_i16_tru() == 1 + +function %bint_b32_i16_false() -> i16 { +block0: + v0 = bconst.b32 false + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b32_i16_fal() == 0 + +function %bint_b32_i32_true() -> i32 { +block0: + v0 = bconst.b32 true + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b32_i32_tru() == 1 + +function %bint_b32_i32_false() -> i32 { +block0: + v0 = bconst.b32 false + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b32_i32_fal() == 0 + +function %bint_b32_i64_true() -> i64 { +block0: + v0 = bconst.b32 true + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b32_i64_tru() == 1 + +function %bint_b32_i64_false() -> i64 { +block0: + v0 = bconst.b32 false + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b32_i64_fal() == 0 + + + + + + +function %bint_b64_i8_true() -> i8 { +block0: + v0 = bconst.b64 true + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b64_i8_true() == 1 + +function %bint_b64_i8_false() -> i8 { +block0: + v0 = bconst.b64 false + v1 = bint.i8 v0 + return v1 +} +; run: %bint_b64_i8_fals() == 0 + +function %bint_b64_i16_true() -> i16 { +block0: + v0 = bconst.b64 true + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b64_i16_tru() == 1 + +function %bint_b64_i16_false() -> i16 { +block0: + v0 = bconst.b64 false + v1 = bint.i16 v0 + return v1 +} +; run: %bint_b64_i16_fal() == 0 + +function %bint_b64_i32_true() -> i32 { +block0: + v0 = bconst.b64 true + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b64_i32_tru() == 1 + +function %bint_b64_i32_false() -> i32 { +block0: + v0 = bconst.b64 false + v1 = bint.i32 v0 + return v1 +} +; run: %bint_b64_i32_fal() == 0 + +function %bint_b64_i64_true() -> i64 { +block0: + v0 = bconst.b64 true + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b64_i64_tru() == 1 + +function %bint_b64_i64_false() -> i64 { +block0: + v0 = bconst.b64 false + v1 = bint.i64 v0 + return v1 +} +; run: %bint_b64_i64_fal() == 0 diff --git a/cranelift/filetests/filetests/runtests/i128-bint.clif b/cranelift/filetests/filetests/runtests/i128-bint.clif index 83c9152d51..e7114dbbc4 100644 --- a/cranelift/filetests/filetests/runtests/i128-bint.clif +++ b/cranelift/filetests/filetests/runtests/i128-bint.clif @@ -1,12 +1,85 @@ +test interpret test run set enable_llvm_abi_extensions=true target aarch64 target x86_64 -function %bint_b8_i128() -> i128 { +function %bint_b1_i128_true() -> i128 { +block0: + v0 = bconst.b1 true + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b1_i128_tru() == 1 + +function %bint_b1_i128_false() -> i128 { +block0: + v0 = bconst.b1 false + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b1_i128_fal() == 0 + +function %bint_b8_i128_true() -> i128 { block0: v0 = bconst.b8 true v1 = bint.i128 v0 return v1 } -; run: %bint_b8_i128() == 1 +; run: %bint_b8_i128_tru() == 1 + +function %bint_b8_i128_false() -> i128 { +block0: + v0 = bconst.b8 false + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b8_i128_fal() == 0 + +function %bint_b16_i128_true() -> i128 { +block0: + v0 = bconst.b16 true + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b16_i128_tr() == 1 + +function %bint_b16_i128_false() -> i128 { +block0: + v0 = bconst.b16 false + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b16_i128_fa() == 0 + +function %bint_b32_i128_true() -> i128 { +block0: + v0 = bconst.b32 true + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b32_i128_tr() == 1 + +function %bint_b32_i128_false() -> i128 { +block0: + v0 = bconst.b32 false + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b32_i128_fa() == 0 + +function %bint_b64_i128_true() -> i128 { +block0: + v0 = bconst.b64 true + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b64_i128_tr() == 1 + +function %bint_b64_i128_false() -> i128 { +block0: + v0 = bconst.b64 false + v1 = bint.i128 v0 + return v1 +} +; run: %bint_b64_i128_fa() == 0 diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 1e9d7c5369..1b9f21ad52 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -716,11 +716,15 @@ where | Opcode::ScalarToVector | Opcode::Breduce | Opcode::Bextend - | Opcode::Bint | Opcode::Ireduce => assign(Value::convert( arg(0)?, ValueConversionKind::Exact(ctrl_ty), )?), + Opcode::Bint => { + let bool = arg(0)?.into_bool()?; + let int = if bool { 1 } else { 0 }; + assign(Value::int(int, ctrl_ty)?) + } Opcode::Snarrow | Opcode::Unarrow | Opcode::Uunarrow => { let arg0 = extractlanes(&arg(0)?, ctrl_ty.lane_type())?; let arg1 = extractlanes(&arg(1)?, ctrl_ty.lane_type())?;