Skip to content

Commit

Permalink
[interp] Constant fold also checked conversion opcodes (#33981)
Browse files Browse the repository at this point in the history
Co-authored-by: BrzVlad <BrzVlad@users.noreply.github.com>
  • Loading branch information
monojenkins and BrzVlad committed Mar 27, 2020
1 parent 6c709ca commit dd9233b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
8 changes: 1 addition & 7 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5745,12 +5745,6 @@ call:;
sp [-1].data.l = (gint64)sp [-1].data.f;
++ip;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CONV_OVF_I4_UN_I8)
if ((guint64)sp [-1].data.l > G_MAXINT32)
goto overflow_label;
sp [-1].data.i = (gint32)sp [-1].data.l;
++ip;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_BOX) {
mono_interp_box (frame, ip, sp);
ip += 3;
Expand Down Expand Up @@ -6016,7 +6010,7 @@ call:;
++ip;
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CONV_OVF_I4_U8)
if (sp [-1].data.l < 0 || sp [-1].data.l > G_MAXINT32)
if ((guint64)sp [-1].data.l > G_MAXINT32)
goto overflow_label;
sp [-1].data.i = (gint32) sp [-1].data.l;
++ip;
Expand Down
1 change: 0 additions & 1 deletion src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ OPDEF(MINT_CONV_OVF_I4_U8, "conv.ovf.i4.u8", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_CONV_OVF_I4_R4, "conv.ovf.i4.r4", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 1, Pop1, Push1, MintOpNoArgs)

OPDEF(MINT_CONV_OVF_I4_UN_I8, "conv.ovf.i4.un.i8", 1, Pop1, Push1, MintOpNoArgs)
OPDEF(MINT_CONV_OVF_I4_UN_R8, "conv.ovf.i4.un.r8", 1, Pop1, Push1, MintOpNoArgs)

OPDEF(MINT_CONV_OVF_U4_I4, "conv.ovf.u4.i4", 1, Pop1, Push1, MintOpNoArgs)
Expand Down
34 changes: 33 additions & 1 deletion src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -5059,7 +5059,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
break;
case STACK_TYPE_I8:
#if SIZEOF_VOID_P == 4
interp_add_ins (td, MINT_CONV_OVF_I4_UN_I8);
interp_add_ins (td, MINT_CONV_OVF_I4_U8);
#endif
break;
case STACK_TYPE_I4:
Expand Down Expand Up @@ -6783,6 +6783,14 @@ interp_local_deadce (TransformData *td, int *local_ref_count)
result.field_dst = (cast_type)sp->val.field_src; \
break;

#define INTERP_FOLD_CONV_FULL(opcode,stack_type_dst,field_dst,stack_type_src,field_src,cast_type,cond) \
case opcode: \
g_assert (sp->val.type == stack_type_src); \
if (!(cond)) goto cfold_failed; \
result.type = stack_type_dst; \
result.field_dst = (cast_type)sp->val.field_src; \
break;

static InterpInst*
interp_fold_unop (TransformData *td, StackContentInfo *sp, InterpInst *ins)
{
Expand Down Expand Up @@ -6835,6 +6843,30 @@ interp_fold_unop (TransformData *td, StackContentInfo *sp, InterpInst *ins)
INTERP_FOLD_CONV (MINT_CONV_I8_I4, STACK_VALUE_I8, l, STACK_VALUE_I4, i, gint32);
INTERP_FOLD_CONV (MINT_CONV_I8_U4, STACK_VALUE_I8, l, STACK_VALUE_I4, i, guint32);

INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I1_I4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, gint8, sp [0].val.i >= G_MININT8 && sp [0].val.i <= G_MAXINT8);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I1_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, gint8, sp [0].val.l >= G_MININT8 && sp [0].val.l <= G_MAXINT8);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I1_U4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, gint8, sp [0].val.i >= 0 && sp [0].val.i <= G_MAXINT8);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I1_U8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, gint8, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXINT8);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U1_I4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, guint8, sp [0].val.i >= 0 && sp [0].val.i <= G_MAXUINT8);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U1_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, guint8, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXUINT8);

INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I2_I4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, gint16, sp [0].val.i >= G_MININT16 && sp [0].val.i <= G_MAXINT16);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I2_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, i, gint16, sp [0].val.l >= G_MININT16 && sp [0].val.l <= G_MAXINT16);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I2_U4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, gint16, sp [0].val.i >= 0 && sp [0].val.i <= G_MAXINT16);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I2_U8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, gint16, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXINT16);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U2_I4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, guint16, sp [0].val.i >= 0 && sp [0].val.i <= G_MAXUINT16);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U2_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, guint16, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXUINT16);

INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I4_U4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, gint32, sp [0].val.i >= 0);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I4_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, gint32, sp [0].val.l >= G_MININT32 && sp [0].val.l <= G_MAXINT32);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I4_U8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, gint32, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXINT32);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U4_I4, STACK_VALUE_I4, i, STACK_VALUE_I4, i, guint32, sp [0].val.i >= 0);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U4_I8, STACK_VALUE_I4, i, STACK_VALUE_I8, l, guint32, sp [0].val.l >= 0 && sp [0].val.l <= G_MAXINT32);

INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_I8_U8, STACK_VALUE_I8, l, STACK_VALUE_I8, l, gint64, sp [0].val.l >= 0);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U8_I4, STACK_VALUE_I8, l, STACK_VALUE_I4, i, guint64, sp [0].val.i >= 0);
INTERP_FOLD_CONV_FULL (MINT_CONV_OVF_U8_I8, STACK_VALUE_I8, l, STACK_VALUE_I8, l, guint64, sp [0].val.l >= 0);

default:
goto cfold_failed;
}
Expand Down

0 comments on commit dd9233b

Please sign in to comment.