[llvm] Add sign extensions for the index register used during bounds checks and array...
authorZoltan Varga <vargaz@gmail.com>
Mon, 3 Apr 2017 21:23:26 +0000 (17:23 -0400)
committerGitHub <noreply@github.com>
Mon, 3 Apr 2017 21:23:26 +0000 (17:23 -0400)
mono/mini/decompose.c
mono/mini/method-to-ir.c
mono/mini/mini-llvm.c

index 23e576f0ea9046e20cc10366332ac0527ec40f64..1c3060f162477cc8db01fbc0c64c6eb2c6f3ebbb 100644 (file)
@@ -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) {
index 0f35640120924a613771086ece5de5eb7865b8f5..99a0b10e2d75162342e00f2b53bf713c4ab076e7 100644 (file)
@@ -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);
index 0500f102a5729388457926e6b6554c9ab7ca574c..b53dafd323ea81108323fcb26d7cda53573525ae 100644 (file)
@@ -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);