Fix validating wasm stores of boolean vector results (#3202)

Previously cranelift's wasm code generator would emit a raw `store`
instruction for all wasm types, regardless of what the cranelift operand
type was. Cranelift's `store` instruction, however, isn't valid for
boolean vector types. This commit fixes this issue by inserting a
bitcast specifically for the store instruction if a boolean vector type
is being stored, continuing to avoid the bitcast for all other vector types.

Closes #3099
This commit is contained in:
Alex Crichton
2021-08-18 12:16:50 -05:00
committed by GitHub
parent 03a3a5939a
commit 86bc37f26e
2 changed files with 93 additions and 2 deletions

View File

@@ -2407,8 +2407,16 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
state: &mut FuncTranslationState, state: &mut FuncTranslationState,
environ: &mut FE, environ: &mut FE,
) -> WasmResult<()> { ) -> WasmResult<()> {
let val = state.pop1(); let mut val = state.pop1();
let val_ty = builder.func.dfg.value_type(val); let mut val_ty = builder.func.dfg.value_type(val);
// Boolean-vector types don't validate with a `store` instruction, so
// bitcast them to a vector type which is compatible with the store
// instruction.
if val_ty.is_vector() && val_ty.lane_type().is_bool() {
val = builder.ins().raw_bitcast(I8X16, val);
val_ty = I8X16;
}
let (flags, base, offset) = let (flags, base, offset) =
prepare_addr(memarg, mem_op_size(opcode, val_ty), builder, state, environ)?; prepare_addr(memarg, mem_op_size(opcode, val_ty), builder, state, environ)?;

View File

@@ -0,0 +1,83 @@
(module
(func (param v128)
(v128.store (i32.const 0) (i8x16.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i64x2.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i8x16.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i64x2.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i8x16.lt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.lt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.lt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i64x2.lt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i8x16.lt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.lt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.lt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i8x16.gt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.gt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.gt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i64x2.gt_s (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i8x16.gt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i16x8.gt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (i32x4.gt_u (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.eq (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.ne (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.lt (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.lt (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.le (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.le (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.gt (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.gt (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f32x4.ge (local.get 0) (local.get 0))))
(func (param v128)
(v128.store (i32.const 0) (f64x2.ge (local.get 0) (local.get 0))))
(memory 0)
)