From aaab7dffaa1366ce6d9893bedbf31910baf85b1e Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Fri, 14 Jul 2023 11:29:45 +0300 Subject: [PATCH 1/5] [mono][interp] Remove dead code --- src/mono/mono/mini/interp/interp.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 1b832de431db0c..2baf668181952f 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1211,27 +1211,6 @@ ves_array_calculate_index (MonoArray *ao, stackval *sp, gboolean safe) return pos; } -static MonoException* -ves_array_get (InterpFrame *frame, stackval *sp, stackval *retval, MonoMethodSignature *sig, gboolean safe) -{ - MonoObject *o = sp->data.o; - MonoArray *ao = (MonoArray *) o; - MonoClass *ac = o->vtable->klass; - - g_assert (m_class_get_rank (ac) >= 1); - - gint32 pos = ves_array_calculate_index (ao, sp + 1, safe); - if (pos == -1) - return mono_get_exception_index_out_of_range (); - - gint32 esize = mono_array_element_size (ac); - gconstpointer ea = mono_array_addr_with_size_fast (ao, esize, pos); - - MonoType *mt = sig->ret; - stackval_from_data (mt, retval, ea, FALSE); - return NULL; -} - static MonoException* ves_array_element_address (InterpFrame *frame, MonoClass *required_type, MonoArray *ao, gpointer *ret, stackval *sp, gboolean needs_typecheck) { From f5031cf74ff5cfb29b58850aefd547300eb9475a Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Mon, 17 Jul 2023 11:48:17 +0300 Subject: [PATCH 2/5] [tests] Move issue to interp only --- src/tests/issues.targets | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 09e50e73c7dd39..71f5b5fab57c00 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1203,9 +1203,6 @@ https://github.com/dotnet/runtime/issues/74223 - - https://github.com/dotnet/runtime/issues/71656 - https://github.com/dotnet/runtime/issues/54176 @@ -2233,6 +2230,9 @@ https://github.com/dotnet/runtime/issues/74687 + + https://github.com/dotnet/runtime/issues/71656 + From cad4e2ef65f90bbc2a7d6a3576c943418bc64f91 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Fri, 14 Jul 2023 11:17:09 +0300 Subject: [PATCH 3/5] [mono][jit] Fix bounds check when index is nint Previous code was assuming index is i4. Remove MONO_ARCH_EMIT_BOUNDS_CHECK on amd64 since it was doing a I4 comparison, while the index reg is i8. Use MONO_EMIT_DEFAULT_BOUNDS_CHECK instead also on amd64. On llvm we might not be able to insert the sign extending because it apparently interferes with abcrem optimization. We therefore split OP_BOUNDS_CHECK into two separate opcodes, so, after abcrem, we know whether we have to insert the sext or not. --- src/mono/mono/mini/abcremoval.c | 3 ++- src/mono/mono/mini/decompose.c | 13 +++++++++++-- src/mono/mono/mini/intrinsics.c | 7 ++++--- src/mono/mono/mini/ir-emit.h | 12 ++++++++---- src/mono/mono/mini/method-to-ir.c | 21 +++++++++++++++------ src/mono/mono/mini/mini-amd64.h | 10 ---------- src/mono/mono/mini/mini-ops.h | 1 + src/mono/mono/mini/mini.h | 2 +- src/mono/mono/mini/simd-intrinsics.c | 6 +++--- 9 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/mono/mono/mini/abcremoval.c b/src/mono/mono/mini/abcremoval.c index 5dd747341c7fad..39c2ed5c1ea21c 100644 --- a/src/mono/mono/mini/abcremoval.c +++ b/src/mono/mono/mini/abcremoval.c @@ -1144,7 +1144,7 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua if (TRACE_ABC_REMOVAL) mono_print_ins (ins); - if (ins->opcode == OP_BOUNDS_CHECK) { /* Handle OP_LDELEMA2D, too */ + if (ins->opcode == OP_BOUNDS_CHECK || ins->opcode == OP_BOUNDS_CHECK_SEXT) { /* Handle OP_LDELEMA2D, too */ array_var = ins->sreg1; index_var = ins->sreg2; @@ -1204,6 +1204,7 @@ MONO_DISABLE_WARNING(4127) /* conditional expression is constant */ */ if (COMPILE_LLVM (cfg) && (ins->opcode == OP_LDLEN || ins->opcode == OP_BOUNDS_CHECK || + ins->opcode == OP_BOUNDS_CHECK_SEXT || ins->opcode == OP_STRLEN || (MONO_IS_LOAD_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)) || (MONO_IS_STORE_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)))) { diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index b4570cc0c7429d..4e23618b9d86e2 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -1546,15 +1546,24 @@ mono_decompose_array_access_opts (MonoCompile *cfg) MONO_ADD_INS (cfg->cbb, dest); break; case OP_BOUNDS_CHECK: + case OP_BOUNDS_CHECK_SEXT: { + gboolean need_sext = ins->opcode == OP_BOUNDS_CHECK_SEXT; MONO_EMIT_NULL_CHECK (cfg, ins->sreg1, FALSE); if (COMPILE_LLVM (cfg)) { - int index2_reg = alloc_preg (cfg); - MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2); + int index2_reg; + if (need_sext) { + index2_reg = alloc_preg (cfg); + MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2); + } else { + index2_reg = ins->sreg2; + } MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, GINT32_TO_UINT32(ins->inst_imm), index2_reg, ins->flags & MONO_INST_FAULT, ins->inst_p0); } else { + g_assert (!need_sext); MONO_ARCH_EMIT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->inst_p0); } break; + } case OP_NEWARR: { ERROR_DECL (vt_error); MonoClass *array_class = mono_class_create_array (ins->inst_newa_class, 1); diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index b1e5e767231470..d57dd90337ae16 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -356,9 +356,10 @@ emit_span_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature /* Similar to mini_emit_ldelema_1_ins () */ int size = mono_class_array_element_size (param_class); - int index_reg = mini_emit_sext_index_reg (cfg, args [1]); + gboolean need_sext; + int index_reg = mini_emit_sext_index_reg (cfg, args [1], &need_sext); - mini_emit_bounds_check_offset (cfg, span_reg, length_field->offset - MONO_ABI_SIZEOF (MonoObject), index_reg, NULL); + mini_emit_bounds_check_offset (cfg, span_reg, length_field->offset - MONO_ABI_SIZEOF (MonoObject), index_reg, NULL, need_sext); // FIXME: Sign extend index ? @@ -849,7 +850,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign #else index_reg = args [1]->dreg; #endif - MONO_EMIT_BOUNDS_CHECK (cfg, args [0]->dreg, MonoString, length, index_reg); + MONO_EMIT_BOUNDS_CHECK (cfg, args [0]->dreg, MonoString, length, index_reg, FALSE); #if defined(TARGET_X86) || defined(TARGET_AMD64) EMIT_NEW_X86_LEA (cfg, ins, args [0]->dreg, index_reg, 1, MONO_STRUCT_OFFSET (MonoString, chars)); diff --git a/src/mono/mono/mini/ir-emit.h b/src/mono/mono/mini/ir-emit.h index 6b88e959e3852f..23dc146078b159 100644 --- a/src/mono/mono/mini/ir-emit.h +++ b/src/mono/mono/mini/ir-emit.h @@ -971,11 +971,12 @@ static int ccount = 0; #endif static inline void -mini_emit_bounds_check_offset (MonoCompile *cfg, int array_reg, int array_length_offset, int index_reg, const char *ex_name) +mini_emit_bounds_check_offset (MonoCompile *cfg, int array_reg, int array_length_offset, int index_reg, const char *ex_name, gboolean need_sext) { if (!(cfg->opt & MONO_OPT_UNSAFE)) { ex_name = ex_name ? ex_name : "IndexOutOfRangeException"; if (!(cfg->opt & MONO_OPT_ABCREM)) { + g_assert (!need_sext); MONO_EMIT_NULL_CHECK (cfg, array_reg, FALSE); if (COMPILE_LLVM (cfg)) MONO_EMIT_DEFAULT_BOUNDS_CHECK ((cfg), (array_reg), GINT_TO_UINT(array_length_offset), (index_reg), TRUE, ex_name); @@ -983,7 +984,10 @@ mini_emit_bounds_check_offset (MonoCompile *cfg, int array_reg, int array_length MONO_ARCH_EMIT_BOUNDS_CHECK ((cfg), (array_reg), GINT_TO_UINT(array_length_offset), (index_reg), ex_name); } else { MonoInst *ins; - MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK); + if (need_sext) + MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK_SEXT); + else + MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK); ins->sreg1 = array_reg; ins->sreg2 = index_reg; ins->inst_p0 = (gpointer)ex_name; @@ -1002,8 +1006,8 @@ mini_emit_bounds_check_offset (MonoCompile *cfg, int array_reg, int array_length * array_length_field is the field in the previous struct with the length * index_reg is the vreg holding the index */ -#define MONO_EMIT_BOUNDS_CHECK(cfg, array_reg, array_type, array_length_field, index_reg) do { \ - mini_emit_bounds_check_offset ((cfg), (array_reg), MONO_STRUCT_OFFSET (array_type, array_length_field), (index_reg), NULL); \ +#define MONO_EMIT_BOUNDS_CHECK(cfg, array_reg, array_type, array_length_field, index_reg, need_sext) do { \ + mini_emit_bounds_check_offset ((cfg), (array_reg), MONO_STRUCT_OFFSET (array_type, array_length_field), (index_reg), NULL, need_sext); \ } while (0) #endif diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index b5f75ea1c3133d..f5202871af775b 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4211,20 +4211,27 @@ mini_field_access_needs_cctor_run (MonoCompile *cfg, MonoMethod *method, MonoCla } int -mini_emit_sext_index_reg (MonoCompile *cfg, MonoInst *index) +mini_emit_sext_index_reg (MonoCompile *cfg, MonoInst *index, gboolean *need_sext) { int index_reg = index->dreg; int index2_reg; + *need_sext = FALSE; + #if SIZEOF_REGISTER == 8 + // If index is not I4 don't sign extend otherwise we lose high word + if (index->type != STACK_I4) + return index_reg; + /* The array reg is 64 bits but the index reg is only 32 */ - if (COMPILE_LLVM (cfg)) { + if (cfg->opt & MONO_OPT_ABCREM) { /* * abcrem can't handle the OP_SEXT_I4, so add this after abcrem, * during OP_BOUNDS_CHECK decomposition, and in the implementation * of OP_X86_LEA for llvm. */ index2_reg = index_reg; + *need_sext = TRUE; } else { index2_reg = alloc_preg (cfg); MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, index_reg); @@ -4259,7 +4266,9 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono mult_reg = alloc_preg (cfg); array_reg = arr->dreg; - realidx2_reg = index2_reg = mini_emit_sext_index_reg (cfg, index); + gboolean need_sext; + + realidx2_reg = index2_reg = mini_emit_sext_index_reg (cfg, index, &need_sext); if (bounded) { bounds_reg = alloc_preg (cfg); @@ -4283,7 +4292,7 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono } if (bcheck) - MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, realidx2_reg); + MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, realidx2_reg, need_sext); #if defined(TARGET_X86) || defined(TARGET_AMD64) if (size == 1 || size == 2 || size == 4 || size == 8) { @@ -4483,7 +4492,7 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole MONO_EMIT_NEW_UNALU (cfg, OP_ZEXT_I4, index_reg, index_reg); if (safety_checks) - MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg); + MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg, FALSE); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), array_reg, (target_mgreg_t)offset, sp [2]->dreg); } else { MonoInst *addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], safety_checks, FALSE); @@ -10588,7 +10597,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (SIZEOF_REGISTER == 8 && COMPILE_LLVM (cfg)) MONO_EMIT_NEW_UNALU (cfg, OP_ZEXT_I4, index_reg, index_reg); - MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg); + MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg, FALSE); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), array_reg, (target_mgreg_t)offset); } else { addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE, FALSE); diff --git a/src/mono/mono/mini/mini-amd64.h b/src/mono/mono/mini/mini-amd64.h index 80c570e58f5bea..2c775c1585545b 100644 --- a/src/mono/mono/mini/mini-amd64.h +++ b/src/mono/mono/mini/mini-amd64.h @@ -480,16 +480,6 @@ typedef struct { /* Used for optimization, not complete */ #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE) -#define MONO_ARCH_EMIT_BOUNDS_CHECK(cfg, array_reg, offset, index_reg, ex_name) do { \ - MonoInst *inst; \ - MONO_INST_NEW ((cfg), inst, OP_AMD64_ICOMPARE_MEMBASE_REG); \ - inst->inst_basereg = array_reg; \ - inst->inst_offset = offset; \ - inst->sreg2 = index_reg; \ - MONO_ADD_INS ((cfg)->cbb, inst); \ - MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, ex_name); \ - } while (0) - // Does the ABI have a volatile non-parameter register, so tailcall // can pass context to generics or interfaces? #define MONO_ARCH_HAVE_VOLATILE_NON_PARAM_REGISTER 1 diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index d95f0948073402..cb5176e3848587 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -763,6 +763,7 @@ MINI_OP(OP_NEWARR, "newarr", IREG, IREG, NONE) MINI_OP(OP_LDLEN, "ldlen", IREG, IREG, NONE) /* inst_p0 is the exception name to throw or NULL */ MINI_OP(OP_BOUNDS_CHECK, "bounds_check", NONE, IREG, IREG) +MINI_OP(OP_BOUNDS_CHECK_SEXT, "bounds_check_sext", NONE, IREG, IREG) /* type checks */ MINI_OP(OP_ISINST, "isinst", IREG, IREG, NONE) MINI_OP(OP_CASTCLASS, "castclass", IREG, IREG, NONE) diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index eee8fd39bd5a59..288baf7ca9ef9e 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -2316,7 +2316,7 @@ void mini_emit_memset (MonoCompile *cfg, int destreg, int offset, i void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native); void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass *klass); void mini_emit_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype); -int mini_emit_sext_index_reg (MonoCompile *cfg, MonoInst *index); +int mini_emit_sext_index_reg (MonoCompile *cfg, MonoInst *index, gboolean *need_sext); MonoInst* mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck, gboolean bounded); MonoInst* mini_emit_get_gsharedvt_info_klass (MonoCompile *cfg, MonoClass *klass, MonoRgctxInfoType rgctx_type); MonoInst* mini_emit_get_rgctx_method (MonoCompile *cfg, int context_used, diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 1b6fe4d2447b5f..3e3c2eb26feb35 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -3240,12 +3240,12 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig } /* Emit bounds check for the index (index >= 0) */ - mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), index_ins->dreg, "ArgumentOutOfRangeException"); + mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), index_ins->dreg, "ArgumentOutOfRangeException", FALSE); /* Emit bounds check for the end (index + len - 1 < array length) */ end_index_reg = alloc_ireg (cfg); EMIT_NEW_BIALU_IMM (cfg, ins, OP_IADD_IMM, end_index_reg, index_ins->dreg, len - 1); - mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), end_index_reg, "ArgumentOutOfRangeException"); + mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), end_index_reg, "ArgumentOutOfRangeException", FALSE); /* Load the array slice into the simd reg */ ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, FALSE, FALSE); @@ -3274,7 +3274,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig } /* CopyTo () does complicated argument checks */ - mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), index_ins->dreg, "ArgumentOutOfRangeException"); + mini_emit_bounds_check_offset (cfg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), index_ins->dreg, "ArgumentOutOfRangeException", FALSE); end_index_reg = alloc_ireg (cfg); int len_reg = alloc_ireg (cfg); MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, len_reg, array_ins->dreg, MONO_STRUCT_OFFSET (MonoArray, max_length), MONO_INST_INVARIANT_LOAD); From caf60c0e9034340627124b4b7eb858ca771e9861 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 19 Jul 2023 12:24:22 +0300 Subject: [PATCH 4/5] [mono][interp] Add missing sign extend Fix passing of i4 to wrapper accepting native int. The wrapper no longer does the sign extend in order to not lose high bits of native int. --- src/mono/mono/mini/method-to-ir.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index f5202871af775b..99f2ec28ff214d 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4453,8 +4453,18 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole if (sp [2]->type != STACK_OBJ) return NULL; + MonoInst *index_ins = sp [1]; +#if SIZEOF_REGISTER == 8 + if (sp [1]->type == STACK_I4) { + // stelemref wrapper recevies index as native int, sign extend it + guint32 dreg = alloc_preg (cfg); + guint32 sreg = index_ins->dreg; + EMIT_NEW_UNALU (cfg, index_ins, OP_SEXT_I4, dreg, sreg); + } +#endif + iargs [2] = sp [2]; - iargs [1] = sp [1]; + iargs [1] = index_ins; iargs [0] = sp [0]; MonoClass *array_class = sp [0]->klass; From 1c5819fcdf486ce9b3e32218a3c0f0a248f958a6 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Thu, 7 Sep 2023 11:42:06 +0300 Subject: [PATCH 5/5] feedback --- src/mono/mono/mini/abcremoval.c | 3 +-- src/mono/mono/mini/decompose.c | 5 ++--- src/mono/mono/mini/ir-emit.h | 6 ++---- src/mono/mono/mini/method-to-ir.c | 2 +- src/mono/mono/mini/mini-ops.h | 1 - src/mono/mono/mini/mini.h | 1 + 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/mono/mono/mini/abcremoval.c b/src/mono/mono/mini/abcremoval.c index 39c2ed5c1ea21c..5dd747341c7fad 100644 --- a/src/mono/mono/mini/abcremoval.c +++ b/src/mono/mono/mini/abcremoval.c @@ -1144,7 +1144,7 @@ process_block (MonoCompile *cfg, MonoBasicBlock *bb, MonoVariableRelationsEvalua if (TRACE_ABC_REMOVAL) mono_print_ins (ins); - if (ins->opcode == OP_BOUNDS_CHECK || ins->opcode == OP_BOUNDS_CHECK_SEXT) { /* Handle OP_LDELEMA2D, too */ + if (ins->opcode == OP_BOUNDS_CHECK) { /* Handle OP_LDELEMA2D, too */ array_var = ins->sreg1; index_var = ins->sreg2; @@ -1204,7 +1204,6 @@ MONO_DISABLE_WARNING(4127) /* conditional expression is constant */ */ if (COMPILE_LLVM (cfg) && (ins->opcode == OP_LDLEN || ins->opcode == OP_BOUNDS_CHECK || - ins->opcode == OP_BOUNDS_CHECK_SEXT || ins->opcode == OP_STRLEN || (MONO_IS_LOAD_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)) || (MONO_IS_STORE_MEMBASE (ins) && (ins->flags & MONO_INST_FAULT)))) { diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index 4e23618b9d86e2..55ed38e29d50cc 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -1545,9 +1545,8 @@ mono_decompose_array_access_opts (MonoCompile *cfg) ins->inst_imm, ins->flags); MONO_ADD_INS (cfg->cbb, dest); break; - case OP_BOUNDS_CHECK: - case OP_BOUNDS_CHECK_SEXT: { - gboolean need_sext = ins->opcode == OP_BOUNDS_CHECK_SEXT; + case OP_BOUNDS_CHECK: { + gboolean need_sext = ins->backend.need_sext; MONO_EMIT_NULL_CHECK (cfg, ins->sreg1, FALSE); if (COMPILE_LLVM (cfg)) { int index2_reg; diff --git a/src/mono/mono/mini/ir-emit.h b/src/mono/mono/mini/ir-emit.h index 23dc146078b159..0889a79efb9564 100644 --- a/src/mono/mono/mini/ir-emit.h +++ b/src/mono/mono/mini/ir-emit.h @@ -984,14 +984,12 @@ mini_emit_bounds_check_offset (MonoCompile *cfg, int array_reg, int array_length MONO_ARCH_EMIT_BOUNDS_CHECK ((cfg), (array_reg), GINT_TO_UINT(array_length_offset), (index_reg), ex_name); } else { MonoInst *ins; - if (need_sext) - MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK_SEXT); - else - MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK); + MONO_INST_NEW ((cfg), ins, OP_BOUNDS_CHECK); ins->sreg1 = array_reg; ins->sreg2 = index_reg; ins->inst_p0 = (gpointer)ex_name; ins->inst_imm = (array_length_offset); + ins->backend.need_sext = need_sext; ins->flags |= MONO_INST_FAULT; MONO_ADD_INS ((cfg)->cbb, ins); (cfg)->flags |= MONO_CFG_NEEDS_DECOMPOSE; diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 99f2ec28ff214d..3633ee1abdb888 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4456,7 +4456,7 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole MonoInst *index_ins = sp [1]; #if SIZEOF_REGISTER == 8 if (sp [1]->type == STACK_I4) { - // stelemref wrapper recevies index as native int, sign extend it + // stelemref wrapper receives index as native int, sign extend it guint32 dreg = alloc_preg (cfg); guint32 sreg = index_ins->dreg; EMIT_NEW_UNALU (cfg, index_ins, OP_SEXT_I4, dreg, sreg); diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index cb5176e3848587..d95f0948073402 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -763,7 +763,6 @@ MINI_OP(OP_NEWARR, "newarr", IREG, IREG, NONE) MINI_OP(OP_LDLEN, "ldlen", IREG, IREG, NONE) /* inst_p0 is the exception name to throw or NULL */ MINI_OP(OP_BOUNDS_CHECK, "bounds_check", NONE, IREG, IREG) -MINI_OP(OP_BOUNDS_CHECK_SEXT, "bounds_check_sext", NONE, IREG, IREG) /* type checks */ MINI_OP(OP_ISINST, "isinst", IREG, IREG, NONE) MINI_OP(OP_CASTCLASS, "castclass", IREG, IREG, NONE) diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 288baf7ca9ef9e..5629513af92832 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -753,6 +753,7 @@ struct MonoInst { gpointer data; gint shift_amount; gboolean is_pinvoke; /* for variables in the unmanaged marshal format */ + gboolean need_sext; /* for OP_BOUNDS_CHECK */ gboolean record_cast_details; /* For CEE_CASTCLASS */ MonoInst *spill_var; /* for OP_MOVE_I4_TO_F/F_TO_I4 and OP_FCONV_TO_R8_X */ guint16 source_opcode; /*OP_XCONV_R8_TO_I4 needs to know which op was used to do proper widening*/