From ebaf95e50735961530628825a4bf21f6722f033d Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Mon, 9 Mar 2020 11:16:05 -0700 Subject: [PATCH] Fix types of i8x16 and i16x8 replace_lane Because the smallest Wasm scalar type is i32, users of the `i8x16.replace_lane` and `i16x8.replace_lane` instructions will only be able to pass `i32` values as operands. These values must be reduced by dropping the upper bits (see https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#replace-lane-value) using Cranelift's `ireduce` instruction. --- cranelift/wasm/src/code_translator.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index 2c237e7404..06fc5126c3 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -1249,23 +1249,20 @@ pub fn translate_operator( let vector = pop1_with_bitcast(state, type_of(op), builder); state.push1(builder.ins().extractlane(vector, lane.clone())) } - Operator::I8x16ReplaceLane { lane } - | Operator::I16x8ReplaceLane { lane } - | Operator::I32x4ReplaceLane { lane } + Operator::I8x16ReplaceLane { lane } | Operator::I16x8ReplaceLane { lane } => { + let (vector, replacement) = state.pop2(); + let ty = type_of(op); + let reduced = builder.ins().ireduce(ty.lane_type(), replacement); + let vector = optionally_bitcast_vector(vector, ty, builder); + state.push1(builder.ins().insertlane(vector, *lane, reduced)) + } + Operator::I32x4ReplaceLane { lane } | Operator::I64x2ReplaceLane { lane } | Operator::F32x4ReplaceLane { lane } | Operator::F64x2ReplaceLane { lane } => { - let (vector, replacement_value) = state.pop2(); - let original_vector_type = builder.func.dfg.value_type(vector); + let (vector, replacement) = state.pop2(); let vector = optionally_bitcast_vector(vector, type_of(op), builder); - let replaced_vector = builder - .ins() - .insertlane(vector, lane.clone(), replacement_value); - state.push1(optionally_bitcast_vector( - replaced_vector, - original_vector_type, - builder, - )) + state.push1(builder.ins().insertlane(vector, *lane, replacement)) } Operator::V8x16Shuffle { lanes, .. } => { let (a, b) = pop2_with_bitcast(state, I8X16, builder);