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);