Skip to content

Commit 86bc37f

Browse files
authored
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
1 parent 03a3a59 commit 86bc37f

2 files changed

Lines changed: 93 additions & 2 deletions

File tree

cranelift/wasm/src/code_translator.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,8 +2407,16 @@ fn translate_store<FE: FuncEnvironment + ?Sized>(
24072407
state: &mut FuncTranslationState,
24082408
environ: &mut FE,
24092409
) -> WasmResult<()> {
2410-
let val = state.pop1();
2411-
let val_ty = builder.func.dfg.value_type(val);
2410+
let mut val = state.pop1();
2411+
let mut val_ty = builder.func.dfg.value_type(val);
2412+
2413+
// Boolean-vector types don't validate with a `store` instruction, so
2414+
// bitcast them to a vector type which is compatible with the store
2415+
// instruction.
2416+
if val_ty.is_vector() && val_ty.lane_type().is_bool() {
2417+
val = builder.ins().raw_bitcast(I8X16, val);
2418+
val_ty = I8X16;
2419+
}
24122420

24132421
let (flags, base, offset) =
24142422
prepare_addr(memarg, mem_op_size(opcode, val_ty), builder, state, environ)?;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
(module
2+
(func (param v128)
3+
(v128.store (i32.const 0) (i8x16.eq (local.get 0) (local.get 0))))
4+
(func (param v128)
5+
(v128.store (i32.const 0) (i16x8.eq (local.get 0) (local.get 0))))
6+
(func (param v128)
7+
(v128.store (i32.const 0) (i32x4.eq (local.get 0) (local.get 0))))
8+
(func (param v128)
9+
(v128.store (i32.const 0) (i64x2.eq (local.get 0) (local.get 0))))
10+
11+
(func (param v128)
12+
(v128.store (i32.const 0) (i8x16.ne (local.get 0) (local.get 0))))
13+
(func (param v128)
14+
(v128.store (i32.const 0) (i16x8.ne (local.get 0) (local.get 0))))
15+
(func (param v128)
16+
(v128.store (i32.const 0) (i32x4.ne (local.get 0) (local.get 0))))
17+
(func (param v128)
18+
(v128.store (i32.const 0) (i64x2.ne (local.get 0) (local.get 0))))
19+
20+
(func (param v128)
21+
(v128.store (i32.const 0) (i8x16.lt_s (local.get 0) (local.get 0))))
22+
(func (param v128)
23+
(v128.store (i32.const 0) (i16x8.lt_s (local.get 0) (local.get 0))))
24+
(func (param v128)
25+
(v128.store (i32.const 0) (i32x4.lt_s (local.get 0) (local.get 0))))
26+
(func (param v128)
27+
(v128.store (i32.const 0) (i64x2.lt_s (local.get 0) (local.get 0))))
28+
29+
(func (param v128)
30+
(v128.store (i32.const 0) (i8x16.lt_u (local.get 0) (local.get 0))))
31+
(func (param v128)
32+
(v128.store (i32.const 0) (i16x8.lt_u (local.get 0) (local.get 0))))
33+
(func (param v128)
34+
(v128.store (i32.const 0) (i32x4.lt_u (local.get 0) (local.get 0))))
35+
36+
(func (param v128)
37+
(v128.store (i32.const 0) (i8x16.gt_s (local.get 0) (local.get 0))))
38+
(func (param v128)
39+
(v128.store (i32.const 0) (i16x8.gt_s (local.get 0) (local.get 0))))
40+
(func (param v128)
41+
(v128.store (i32.const 0) (i32x4.gt_s (local.get 0) (local.get 0))))
42+
(func (param v128)
43+
(v128.store (i32.const 0) (i64x2.gt_s (local.get 0) (local.get 0))))
44+
45+
(func (param v128)
46+
(v128.store (i32.const 0) (i8x16.gt_u (local.get 0) (local.get 0))))
47+
(func (param v128)
48+
(v128.store (i32.const 0) (i16x8.gt_u (local.get 0) (local.get 0))))
49+
(func (param v128)
50+
(v128.store (i32.const 0) (i32x4.gt_u (local.get 0) (local.get 0))))
51+
52+
(func (param v128)
53+
(v128.store (i32.const 0) (f32x4.eq (local.get 0) (local.get 0))))
54+
(func (param v128)
55+
(v128.store (i32.const 0) (f64x2.eq (local.get 0) (local.get 0))))
56+
57+
(func (param v128)
58+
(v128.store (i32.const 0) (f32x4.ne (local.get 0) (local.get 0))))
59+
(func (param v128)
60+
(v128.store (i32.const 0) (f64x2.ne (local.get 0) (local.get 0))))
61+
62+
(func (param v128)
63+
(v128.store (i32.const 0) (f32x4.lt (local.get 0) (local.get 0))))
64+
(func (param v128)
65+
(v128.store (i32.const 0) (f64x2.lt (local.get 0) (local.get 0))))
66+
67+
(func (param v128)
68+
(v128.store (i32.const 0) (f32x4.le (local.get 0) (local.get 0))))
69+
(func (param v128)
70+
(v128.store (i32.const 0) (f64x2.le (local.get 0) (local.get 0))))
71+
72+
(func (param v128)
73+
(v128.store (i32.const 0) (f32x4.gt (local.get 0) (local.get 0))))
74+
(func (param v128)
75+
(v128.store (i32.const 0) (f64x2.gt (local.get 0) (local.get 0))))
76+
77+
(func (param v128)
78+
(v128.store (i32.const 0) (f32x4.ge (local.get 0) (local.get 0))))
79+
(func (param v128)
80+
(v128.store (i32.const 0) (f64x2.ge (local.get 0) (local.get 0))))
81+
82+
(memory 0)
83+
)

0 commit comments

Comments
 (0)