diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 7dc5be57f58078..ebf55095e25c94 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -1335,72 +1335,6 @@ needs triage - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - needs triage - - - https://github.com/dotnet/runtime/issues/34068 - - - needs triage - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - needs triage - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - - needs triage - https://github.com/dotnet/runtime/issues/34196 @@ -1419,20 +1353,11 @@ needs triage - - https://github.com/dotnet/runtime/issues/34068 - https://github.com/dotnet/runtime/issues/34196 - - https://github.com/dotnet/runtime/issues/34068 - - - https://github.com/dotnet/runtime/issues/34068 - - https://github.com/dotnet/runtime/issues/34068 + needs triage needs triage diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 445da6d4e786fd..7cf93b0a5c4fb6 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -1152,12 +1152,12 @@ ves_array_calculate_index (MonoArray *ao, stackval *sp, gboolean safe) guint32 pos = 0; if (ao->bounds) { for (gint32 i = 0; i < m_class_get_rank (ac); i++) { - guint32 idx = sp [i].data.i; - guint32 lower = ao->bounds [i].lower_bound; + gint32 idx = sp [i].data.i; + gint32 lower = ao->bounds [i].lower_bound; guint32 len = ao->bounds [i].length; - if (safe && (idx < lower || (idx - lower) >= len)) + if (safe && (idx < lower || (guint32)(idx - lower) >= len)) return -1; - pos = (pos * len) + idx - lower; + pos = (pos * len) + (guint32)(idx - lower); } } else { pos = sp [0].data.i; @@ -6101,12 +6101,12 @@ interp_exec_method (InterpFrame *frame, ThreadContext *context, FrameClauseArgs g_assert (ao->bounds); guint32 pos = 0; for (int i = 0; i < rank; i++) { - guint32 idx = sp [i].data.i; - guint32 lower = ao->bounds [i].lower_bound; + gint32 idx = sp [i].data.i; + gint32 lower = ao->bounds [i].lower_bound; guint32 len = ao->bounds [i].length; - if (idx < lower || (idx - lower) >= len) + if (idx < lower || (guint32)(idx - lower) >= len) THROW_EX (mono_get_exception_index_out_of_range (), ip); - pos = (pos * len) + idx - lower; + pos = (pos * len) + (guint32)(idx - lower); } sp [-1].data.p = mono_array_addr_with_size_fast (ao, esize, pos); diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index a0fd6c0b068989..7cca6322b0f0a2 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -1200,9 +1200,11 @@ interp_emit_ldelema (TransformData *td, MonoClass *array_class, MonoClass *check int rank = m_class_get_rank (array_class); int size = mono_class_array_element_size (element_class); + gboolean bounded = m_class_get_byval_arg (array_class) ? m_class_get_byval_arg (array_class)->type == MONO_TYPE_ARRAY : FALSE; + // We only need type checks when writing to array of references if (!check_class || m_class_is_valuetype (element_class)) { - if (rank == 1) { + if (rank == 1 && !bounded) { interp_add_ins (td, MINT_LDELEMA1); WRITE32_INS (td->last_ins, 0, &size); } else { diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index cf8bcc936aaa8d..912e12e427d648 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -31,7 +31,7 @@ emit_array_generic_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst MonoClass *eklass = mono_class_from_mono_type_internal (fsig->params [1]); /* the bounds check is already done by the callers */ - addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE); + addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE, FALSE); MonoType *etype = m_class_get_byval_arg (eklass); if (is_set) { EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, etype, args [2]->dreg, 0); @@ -2005,7 +2005,7 @@ emit_array_unsafe_access (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst if (is_set) { return mini_emit_array_store (cfg, eklass, args, FALSE); } else { - MonoInst *ins, *addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE); + MonoInst *ins, *addr = mini_emit_ldelema_1_ins (cfg, eklass, args [0], args [1], FALSE, FALSE); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (eklass), addr->dreg, 0); return ins; } diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index 9b7fc50f440ca5..05d202181686f5 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -4078,11 +4078,11 @@ mini_emit_sext_index_reg (MonoCompile *cfg, MonoInst *index) } MonoInst* -mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck) +mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck, gboolean bounded) { MonoInst *ins; guint32 size; - int mult_reg, add_reg, array_reg, index2_reg; + int mult_reg, add_reg, array_reg, index2_reg, bounds_reg, lower_bound_reg, realidx2_reg; int context_used; if (mini_is_gsharedvt_variable_klass (klass)) { @@ -4095,16 +4095,37 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono mult_reg = alloc_preg (cfg); array_reg = arr->dreg; - index2_reg = mini_emit_sext_index_reg (cfg, index); + realidx2_reg = index2_reg = mini_emit_sext_index_reg (cfg, index); + + if (bounded) { + bounds_reg = alloc_preg (cfg); + lower_bound_reg = alloc_preg (cfg); + realidx2_reg = alloc_preg (cfg); + + MonoBasicBlock *is_null_bb = NULL; + NEW_BBLOCK (cfg, is_null_bb); + + // gint32 lower_bound = 0; + // if (arr->bounds) + // lower_bound = arr->bounds.lower_bound; + // realidx2 = index2 - lower_bound; + MONO_EMIT_NEW_PCONST (cfg, lower_bound_reg, NULL); + MONO_EMIT_NEW_LOAD_MEMBASE (cfg, bounds_reg, arr->dreg, MONO_STRUCT_OFFSET (MonoArray, bounds)); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, bounds_reg, 0); + MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_PBEQ, is_null_bb); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, lower_bound_reg, bounds_reg, MONO_STRUCT_OFFSET (MonoArrayBounds, lower_bound)); + MONO_START_BB (cfg, is_null_bb); + MONO_EMIT_NEW_BIALU (cfg, OP_PSUB, realidx2_reg, index2_reg, lower_bound_reg); + } if (bcheck) - MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index2_reg); + MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, realidx2_reg); #if defined(TARGET_X86) || defined(TARGET_AMD64) if (size == 1 || size == 2 || size == 4 || size == 8) { static const int fast_log2 [] = { 1, 0, 1, -1, 2, -1, -1, -1, 3 }; - EMIT_NEW_X86_LEA (cfg, ins, array_reg, index2_reg, fast_log2 [size], MONO_STRUCT_OFFSET (MonoArray, vector)); + EMIT_NEW_X86_LEA (cfg, ins, array_reg, realidx2_reg, fast_log2 [size], MONO_STRUCT_OFFSET (MonoArray, vector)); ins->klass = klass; ins->type = STACK_MP; @@ -4122,9 +4143,9 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono context_used = mini_class_check_context_used (cfg, klass); g_assert (context_used); rgctx_ins = mini_emit_get_gsharedvt_info_klass (cfg, klass, MONO_RGCTX_INFO_ARRAY_ELEMENT_SIZE); - MONO_EMIT_NEW_BIALU (cfg, OP_IMUL, mult_reg, index2_reg, rgctx_ins->dreg); + MONO_EMIT_NEW_BIALU (cfg, OP_IMUL, mult_reg, realidx2_reg, rgctx_ins->dreg); } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_MUL_IMM, mult_reg, index2_reg, size); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_MUL_IMM, mult_reg, realidx2_reg, size); } MONO_EMIT_NEW_BIALU (cfg, OP_PADD, add_reg, array_reg, mult_reg); NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, add_reg, add_reg, MONO_STRUCT_OFFSET (MonoArray, vector)); @@ -4217,10 +4238,12 @@ mini_emit_ldelema_ins (MonoCompile *cfg, MonoMethod *cmethod, MonoInst **sp, guc int element_size; MonoClass *eclass = m_class_get_element_class (cmethod->klass); + gboolean bounded = m_class_get_byval_arg (cmethod->klass) ? m_class_get_byval_arg (cmethod->klass)->type == MONO_TYPE_ARRAY : FALSE; + rank = mono_method_signature_internal (cmethod)->param_count - (is_set? 1: 0); if (rank == 1) - return mini_emit_ldelema_1_ins (cfg, eclass, sp [0], sp [1], TRUE); + return mini_emit_ldelema_1_ins (cfg, eclass, sp [0], sp [1], TRUE, bounded); /* emit_ldelema_2 depends on OP_LMUL */ if (!cfg->backend->emulate_mul_div && rank == 2 && (cfg->opt & MONO_OPT_INTRINS) && !mini_is_gsharedvt_variable_klass (eclass)) { @@ -4273,7 +4296,7 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole MonoInst *addr; // FIXME-VT: OP_ICONST optimization - addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE); + addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE, FALSE); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), addr->dreg, 0, sp [2]->dreg); ins->opcode = OP_STOREV_MEMBASE; } else if (sp [1]->opcode == OP_ICONST) { @@ -4288,7 +4311,7 @@ mini_emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboole MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), array_reg, offset, sp [2]->dreg); } else { - MonoInst *addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], safety_checks); + MonoInst *addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], safety_checks, FALSE); if (!mini_debug_options.weak_memory_model && mini_class_is_reference (klass)) mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_REL); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), addr->dreg, 0, sp [2]->dreg); @@ -10047,7 +10070,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } readonly = FALSE; - ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE); + ins = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE, FALSE); *sp++ = ins; break; case MONO_CEE_LDELEM: @@ -10081,7 +10104,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b if (mini_is_gsharedvt_variable_klass (klass)) { // FIXME-VT: OP_ICONST optimization - addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE); + addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE, FALSE); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), addr->dreg, 0); ins->opcode = OP_LOADV_MEMBASE; } else if (sp [1]->opcode == OP_ICONST) { @@ -10095,7 +10118,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b MONO_EMIT_BOUNDS_CHECK (cfg, array_reg, MonoArray, max_length, index_reg); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), array_reg, offset); } else { - addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE); + addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], TRUE, FALSE); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, m_class_get_byval_arg (klass), addr->dreg, 0); } *sp++ = ins; diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 30992b6cd8818d..317390249d674c 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -4198,6 +4198,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) arm_uxthw (code, dreg, dreg); break; case OP_FCONV_TO_I4: + case OP_FCONV_TO_I: arm_fcvtzs_dx (code, dreg, sreg1); arm_sxtwx (code, dreg, dreg); break; diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 27e8313e3c7eee..b242d1223d8a13 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -2261,7 +2261,7 @@ void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *s 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); -MonoInst* mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, MonoInst *index, gboolean bcheck); +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, MonoMethod *cmethod, MonoRgctxInfoType rgctx_type); diff --git a/src/mono/mono/mini/simd-intrinsics-netcore.c b/src/mono/mono/mini/simd-intrinsics-netcore.c index f98bd48b074e69..ab9b3c6b290333 100644 --- a/src/mono/mono/mini/simd-intrinsics-netcore.c +++ b/src/mono/mono/mini/simd-intrinsics-netcore.c @@ -534,7 +534,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig MONO_EMIT_BOUNDS_CHECK (cfg, array_ins->dreg, MonoArray, max_length, end_index_reg); /* 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, TRUE); + ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, TRUE, FALSE); g_assert (args [0]->opcode == OP_LDADDR); var = (MonoInst*)args [0]->inst_p0; EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOADX_MEMBASE, var->dreg, ldelema_ins->dreg, 0); @@ -569,7 +569,7 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig MONO_EMIT_NEW_COND_EXC (cfg, LT, "ArgumentException"); /* 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); + ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, FALSE, FALSE); EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STOREX_MEMBASE, ldelema_ins->dreg, 0, val_vreg); ins->klass = cmethod->klass; return ins; diff --git a/src/mono/mono/mini/simd-intrinsics.c b/src/mono/mono/mini/simd-intrinsics.c index 95367010fe36ec..cd1aa96c40dd21 100644 --- a/src/mono/mono/mini/simd-intrinsics.c +++ b/src/mono/mono/mini/simd-intrinsics.c @@ -2410,7 +2410,7 @@ emit_vector_t_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSigna MONO_EMIT_BOUNDS_CHECK (cfg, array_ins->dreg, MonoArray, max_length, end_index_reg); /* 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, TRUE); + ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, TRUE, FALSE); g_assert (args [0]->opcode == OP_LDADDR); var = (MonoInst*)args [0]->inst_p0; EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOADX_MEMBASE, var->dreg, ldelema_ins->dreg, 0); @@ -2554,7 +2554,7 @@ emit_vector_t_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSigna MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "ArgumentException"); /* Load the simd reg into the array slice */ - ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, TRUE); + ldelema_ins = mini_emit_ldelema_1_ins (cfg, mono_class_from_mono_type_internal (etype), array_ins, index_ins, TRUE, FALSE); g_assert (args [0]->opcode == OP_LDADDR); var = (MonoInst*)args [0]->inst_p0; EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STOREX_MEMBASE, ldelema_ins->dreg, 0, var->dreg);