Refactor to avoid too strict assertion. Fix for 3160 and 3161.
Assertion was intended for SIMD lowering of F64x2ConvertLowI32x4U
This commit is contained in:
@@ -4528,8 +4528,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
Opcode::FcvtFromUint => {
|
Opcode::FcvtFromUint => {
|
||||||
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||||
let ty = ty.unwrap();
|
let ty = ty.unwrap();
|
||||||
|
|
||||||
let input_ty = ctx.input_ty(insn, 0);
|
let input_ty = ctx.input_ty(insn, 0);
|
||||||
|
let output_ty = ctx.output_ty(insn, 0);
|
||||||
|
|
||||||
if !ty.is_vector() {
|
if !ty.is_vector() {
|
||||||
match input_ty {
|
match input_ty {
|
||||||
types::I8 | types::I16 | types::I32 => {
|
types::I8 | types::I16 | types::I32 => {
|
||||||
@@ -4572,7 +4573,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
}
|
}
|
||||||
_ => panic!("unexpected input type for FcvtFromUint: {:?}", input_ty),
|
_ => panic!("unexpected input type for FcvtFromUint: {:?}", input_ty),
|
||||||
};
|
};
|
||||||
} else if let Some(uwiden) = matches_input(ctx, inputs[0], Opcode::UwidenLow) {
|
} else if output_ty == types::F64X2 {
|
||||||
|
if let Some(uwiden) = matches_input(ctx, inputs[0], Opcode::UwidenLow) {
|
||||||
let uwiden_input = InsnInput {
|
let uwiden_input = InsnInput {
|
||||||
insn: uwiden,
|
insn: uwiden,
|
||||||
input: 0,
|
input: 0,
|
||||||
@@ -4580,11 +4582,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
let src = put_input_in_reg(ctx, uwiden_input);
|
let src = put_input_in_reg(ctx, uwiden_input);
|
||||||
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
let dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||||
let input_ty = ctx.input_ty(uwiden, 0);
|
let input_ty = ctx.input_ty(uwiden, 0);
|
||||||
let output_ty = ctx.output_ty(insn, 0);
|
|
||||||
|
|
||||||
// Matches_input further obfuscates which Wasm instruction this is ultimately
|
// Matches_input further obfuscates which Wasm instruction this is ultimately
|
||||||
// lowering. Check here that the types are as expected for F64x2ConvertLowI32x4U.
|
// lowering. Check here that the types are as expected for F64x2ConvertLowI32x4U.
|
||||||
debug_assert!(input_ty == types::I32X4 || output_ty == types::F64X2);
|
debug_assert!(input_ty == types::I32X4);
|
||||||
|
|
||||||
// Algorithm uses unpcklps to help create a float that is equivalent
|
// Algorithm uses unpcklps to help create a float that is equivalent
|
||||||
// 0x1.0p52 + double(src). 0x1.0p52 is unique because at this exponent
|
// 0x1.0p52 + double(src). 0x1.0p52 is unique because at this exponent
|
||||||
@@ -4594,11 +4595,12 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
ctx.emit(Inst::gen_move(dst, src, types::I32X4));
|
ctx.emit(Inst::gen_move(dst, src, types::I32X4));
|
||||||
|
|
||||||
static UINT_MASK: [u8; 16] = [
|
static UINT_MASK: [u8; 16] = [
|
||||||
0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let uint_mask_const = ctx.use_constant(VCodeConstantData::WellKnown(&UINT_MASK));
|
let uint_mask_const =
|
||||||
|
ctx.use_constant(VCodeConstantData::WellKnown(&UINT_MASK));
|
||||||
|
|
||||||
ctx.emit(Inst::xmm_load_const(
|
ctx.emit(Inst::xmm_load_const(
|
||||||
uint_mask_const,
|
uint_mask_const,
|
||||||
@@ -4614,8 +4616,8 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
));
|
));
|
||||||
|
|
||||||
static UINT_MASK_HIGH: [u8; 16] = [
|
static UINT_MASK_HIGH: [u8; 16] = [
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x30, 0x43,
|
0x00, 0x00, 0x30, 0x43,
|
||||||
];
|
];
|
||||||
|
|
||||||
let uint_mask_high_const =
|
let uint_mask_high_const =
|
||||||
@@ -4633,6 +4635,9 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
RegMem::from(uint_mask_high),
|
RegMem::from(uint_mask_high),
|
||||||
dst,
|
dst,
|
||||||
));
|
));
|
||||||
|
} else {
|
||||||
|
panic!("Unsupported FcvtFromUint conversion types: {}", ty);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(ctx.input_ty(insn, 0), types::I32X4);
|
assert_eq!(ctx.input_ty(insn, 0), types::I32X4);
|
||||||
let src = put_input_in_reg(ctx, inputs[0]);
|
let src = put_input_in_reg(ctx, inputs[0]);
|
||||||
|
|||||||
48
tests/misc_testsuite/simd/cvt-from-uint.wast
Normal file
48
tests/misc_testsuite/simd/cvt-from-uint.wast
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
;; Tests inspired by https://github.com/bytecodealliance/wasmtime/issues/3161
|
||||||
|
;; which found issue in lowering Opcode::FcvtFromUint where valid instruction
|
||||||
|
;; patterns were rejected
|
||||||
|
(module
|
||||||
|
(func (export "i16x8.extend_low_i8x16_s") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i16x8.extend_low_i8x16_s
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
(func (export "i16x8.extend_low_i8x16_u") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i16x8.extend_low_i8x16_u
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
(func (export "i32x4.extend_low_i16x8_s") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i32x4.extend_low_i16x8_s
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
(func (export "i32x4.extend_low_i16x8_u") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i32x4.extend_low_i16x8_u
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
(func (export "i64x2.extend_low_i32x4_s") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i64x2.extend_low_i32x4_s
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
(func (export "i64x2.extend_low_i32x4_u") (param v128) (result v128)
|
||||||
|
local.get 0
|
||||||
|
i64x2.extend_low_i32x4_u
|
||||||
|
f32x4.convert_i32x4_u)
|
||||||
|
)
|
||||||
|
|
||||||
|
(assert_return (invoke "i16x8.extend_low_i8x16_s" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
|
|
||||||
|
(assert_return (invoke "i16x8.extend_low_i8x16_u" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
|
|
||||||
|
(assert_return (invoke "i32x4.extend_low_i16x8_s" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
|
|
||||||
|
(assert_return (invoke "i32x4.extend_low_i16x8_u" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
|
|
||||||
|
(assert_return (invoke "i64x2.extend_low_i32x4_s" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
|
|
||||||
|
(assert_return (invoke "i64x2.extend_low_i32x4_u" (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000))
|
||||||
|
(v128.const f32x4 0 0 0 0))
|
||||||
Reference in New Issue
Block a user