Fix fast jit int rem_s and const shl issues (#1213)

int rem_s -1 should return 0
int32 lhs << int32 rhs may cause sanitizer check failure
fix codegen I8TOI64, I16TOI64, I64TOI8, I64TOI16
implement codegen neg operations
This commit is contained in:
Wenyong Huang 2022-06-09 08:54:14 +08:00 committed by GitHub
parent ab2e959616
commit d11bfdf0e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 14 deletions

View File

@ -2081,7 +2081,9 @@ convert_r_f64_to_r_u32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src)
static bool static bool
neg_imm_to_r_i32(x86::Assembler &a, int32 reg_no, int32 data) neg_imm_to_r_i32(x86::Assembler &a, int32 reg_no, int32 data)
{ {
return false; Imm imm(-data);
a.mov(regs_i32[reg_no], imm);
return true;
} }
/** /**
@ -2096,7 +2098,9 @@ neg_imm_to_r_i32(x86::Assembler &a, int32 reg_no, int32 data)
static bool static bool
neg_r_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) neg_r_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src)
{ {
return false; mov_r_to_r_i32(a, reg_no_dst, reg_no_src);
a.neg(regs_i32[reg_no_dst]);
return true;
} }
/** /**
@ -2111,7 +2115,9 @@ neg_r_to_r_i32(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src)
static bool static bool
neg_imm_to_r_i64(x86::Assembler &a, int32 reg_no, int64 data) neg_imm_to_r_i64(x86::Assembler &a, int32 reg_no, int64 data)
{ {
return false; Imm imm(-data);
a.mov(regs_i64[reg_no], imm);
return true;
} }
/** /**
@ -2126,7 +2132,9 @@ neg_imm_to_r_i64(x86::Assembler &a, int32 reg_no, int64 data)
static bool static bool
neg_r_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src) neg_r_to_r_i64(x86::Assembler &a, int32 reg_no_dst, int32 reg_no_src)
{ {
return false; mov_r_to_r_i64(a, reg_no_dst, reg_no_src);
a.neg(regs_i64[reg_no_dst]);
return true;
} }
/** /**
@ -5923,7 +5931,7 @@ jit_codegen_gen_native(JitCompContext *cc)
case JIT_OP_I8TOI64: case JIT_OP_I8TOI64:
LOAD_2ARGS(); LOAD_2ARGS();
CONVERT_R_R(I64, I64, i64, i8, int8); CONVERT_R_R(I64, I32, i64, i8, int8);
break; break;
case JIT_OP_I16TOI32: case JIT_OP_I16TOI32:
@ -5933,7 +5941,7 @@ jit_codegen_gen_native(JitCompContext *cc)
case JIT_OP_I16TOI64: case JIT_OP_I16TOI64:
LOAD_2ARGS(); LOAD_2ARGS();
CONVERT_R_R(I64, I64, i64, i16, int16); CONVERT_R_R(I64, I32, i64, i16, int16);
break; break;
case JIT_OP_I32TOI8: case JIT_OP_I32TOI8:
@ -5988,12 +5996,12 @@ jit_codegen_gen_native(JitCompContext *cc)
case JIT_OP_I64TOI8: case JIT_OP_I64TOI8:
LOAD_2ARGS(); LOAD_2ARGS();
CONVERT_R_R(I64, I64, i8, i64, int64); CONVERT_R_R(I32, I64, i8, i64, int64);
break; break;
case JIT_OP_I64TOI16: case JIT_OP_I64TOI16:
LOAD_2ARGS(); LOAD_2ARGS();
CONVERT_R_R(I64, I64, i16, i64, int64); CONVERT_R_R(I32, I64, i16, i64, int64);
break; break;
case JIT_OP_I64TOI32: case JIT_OP_I64TOI32:

View File

@ -185,7 +185,7 @@ jit_compile_op_i64_extend_i64(JitCompContext *cc, int8 bitwidth)
POP_I64(value); POP_I64(value);
tmp = jit_cc_new_reg_I64(cc); tmp = jit_cc_new_reg_I32(cc);
res = jit_cc_new_reg_I64(cc); res = jit_cc_new_reg_I64(cc);
switch (bitwidth) { switch (bitwidth) {

View File

@ -701,7 +701,7 @@ compile_int_div(JitCompContext *cc, IntArithmetic arith_op, bool is_i32,
switch (arith_op) { switch (arith_op) {
case INT_DIV_S: case INT_DIV_S:
case INT_REM_S: {
/* Check integer overflow */ /* Check integer overflow */
GEN_INSN(CMP, cc->cmp_reg, left, GEN_INSN(CMP, cc->cmp_reg, left,
is_i32 ? NEW_CONST(I32, INT32_MIN) is_i32 ? NEW_CONST(I32, INT32_MIN)
@ -723,11 +723,27 @@ compile_int_div(JitCompContext *cc, IntArithmetic arith_op, bool is_i32,
/* Build default div and rem */ /* Build default div and rem */
return compile_int_div_no_check(cc, arith_op, is_i32, left, return compile_int_div_no_check(cc, arith_op, is_i32, left,
right, res); right, res);
return true; }
default: case INT_REM_S:
{
GEN_INSN(CMP, cc->cmp_reg, right,
is_i32 ? NEW_CONST(I32, -1) : NEW_CONST(I64, -1LL));
if (is_i32)
GEN_INSN(SELECTEQ, left, cc->cmp_reg, NEW_CONST(I32, 0),
left);
else
GEN_INSN(SELECTEQ, left, cc->cmp_reg, NEW_CONST(I64, 0),
left);
/* Build default div and rem */ /* Build default div and rem */
return compile_int_div_no_check(cc, arith_op, is_i32, left, return compile_int_div_no_check(cc, arith_op, is_i32, left,
right, res); right, res);
}
default:
{
/* Build default div and rem */
return compile_int_div_no_check(cc, arith_op, is_i32, left,
right, res);
}
} }
} }
@ -990,7 +1006,17 @@ DEF_UNI_INT_CONST_OPS(shru)
return 0; return 0;
} }
DEF_BI_INT_CONST_OPS(shl, <<) static int32
do_i32_const_shl(int32 lhs, int32 rhs)
{
return (int32)((uint32)lhs << (uint32)rhs);
}
static int64
do_i64_const_shl(int64 lhs, int64 rhs)
{
return (int32)((uint64)lhs << (uint64)rhs);
}
DEF_BI_INT_CONST_OPS(shrs, >>) DEF_BI_INT_CONST_OPS(shrs, >>)
@ -1505,7 +1531,6 @@ compile_op_float_arithmetic(JitCompContext *cc, FloatArithmetic arith_op,
} }
case FLOAT_DIV: case FLOAT_DIV:
{ {
/*TODO: add divided by zero interception */
GEN_INSN(DIV_S, res, lhs, rhs); GEN_INSN(DIV_S, res, lhs, rhs);
break; break;
} }