From: Zoltan Varga Date: Tue, 1 Dec 2015 23:50:31 +0000 (-0500) Subject: [llvm] Zero extend array indexes when targeting llvm, this seems to work around a... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=9d6a8f62fc6d076691f4a48bf7ceca5a287aa860;p=mono.git [llvm] Zero extend array indexes when targeting llvm, this seems to work around a codegen problem on arm64. Fixes #36263. --- diff --git a/mono/mini/exceptions.cs b/mono/mini/exceptions.cs index 0148488dee3..e84abc68b01 100644 --- a/mono/mini/exceptions.cs +++ b/mono/mini/exceptions.cs @@ -2816,6 +2816,34 @@ class Tests } return finally_called ? 0 : 1; } + + static int array_len_1 = 1; + + public static int test_0_bounds_check_negative_constant () { + try { + byte[] arr = new byte [array_len_1]; + byte b = arr [-1]; + return 1; + } catch { + } + try { + byte[] arr = new byte [array_len_1]; + arr [-1] = 1; + return 2; + } catch { + } + return 0; + } + + public static int test_0_string_bounds_check_negative_constant () { + try { + string s = "A"; + char c = s [-1]; + return 1; + } catch { + } + return 0; + } } #if !__MOBILE__ diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 26536d45eff..1f7a6299738 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -5638,6 +5638,9 @@ emit_array_store (MonoCompile *cfg, MonoClass *klass, MonoInst **sp, gboolean sa int index_reg = sp [1]->dreg; int offset = (mono_class_array_element_size (klass) * sp [1]->inst_c0) + MONO_STRUCT_OFFSET (MonoArray, vector); + if (SIZEOF_REGISTER == 8 && COMPILE_LLVM (cfg)) + 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); EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset, sp [2]->dreg); @@ -5889,8 +5892,12 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign int add_reg = alloc_preg (cfg); #if SIZEOF_REGISTER == 8 - /* The array reg is 64 bits but the index reg is only 32 */ - MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index_reg, args [1]->dreg); + if (COMPILE_LLVM (cfg)) { + MONO_EMIT_NEW_UNALU (cfg, OP_ZEXT_I4, index_reg, args [1]->dreg); + } else { + /* The array reg is 64 bits but the index reg is only 32 */ + MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index_reg, args [1]->dreg); + } #else index_reg = args [1]->dreg; #endif @@ -11716,6 +11723,9 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b int index_reg = sp [1]->dreg; int offset = (mono_class_array_element_size (klass) * sp [1]->inst_c0) + MONO_STRUCT_OFFSET (MonoArray, vector); + 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); EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, array_reg, offset); } else {