From: Zoltan Varga Date: Mon, 3 Apr 2017 21:23:26 +0000 (-0400) Subject: [llvm] Add sign extensions for the index register used during bounds checks and array... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=3a37fbaa0b4f409225eea59f1cb2d52c5969e60e;p=mono.git [llvm] Add sign extensions for the index register used during bounds checks and array address calculations. (#4636) --- diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index 23e576f0ea9..1c3060f1624 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -1508,10 +1508,13 @@ mono_decompose_array_access_opts (MonoCompile *cfg) break; case OP_BOUNDS_CHECK: MONO_EMIT_NULL_CHECK (cfg, ins->sreg1); - if (COMPILE_LLVM (cfg)) - MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->flags & MONO_INST_FAULT); - else + if (COMPILE_LLVM (cfg)) { + int index2_reg = alloc_preg (cfg); + MONO_EMIT_NEW_UNALU (cfg, OP_SEXT_I4, index2_reg, ins->sreg2); + MONO_EMIT_DEFAULT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, index2_reg, ins->flags & MONO_INST_FAULT); + } else { MONO_ARCH_EMIT_BOUNDS_CHECK (cfg, ins->sreg1, ins->inst_imm, ins->sreg2); + } break; case OP_NEWARR: if (cfg->opt & MONO_OPT_SHARED) { diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 0f356401209..99a0b10e2d7 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -4740,7 +4740,11 @@ mini_emit_ldelema_1_ins (MonoCompile *cfg, MonoClass *klass, MonoInst *arr, Mono #if SIZEOF_REGISTER == 8 /* The array reg is 64 bits but the index reg is only 32 */ if (COMPILE_LLVM (cfg)) { - /* Not needed */ + /* + * 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; } else { index2_reg = alloc_preg (cfg); diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index 0500f102a57..b53dafd323e 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -4985,6 +4985,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb) case OP_X86_LEA: { LLVMValueRef v1, v2; + rhs = LLVMBuildSExt (builder, convert (ctx, rhs, LLVMInt32Type ()), LLVMInt64Type (), ""); + v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), ""); v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, ""); values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);