Skip to content

Commit

Permalink
Use byte-aligned LLVM loads and stores for unaligned mini IR loads an…
Browse files Browse the repository at this point in the history
…d stores. (mono/mono#18296)

Should fix mono/mono#18221.

Commit migrated from mono/mono@9719635
  • Loading branch information
imhameed authored and lambdageek committed Dec 26, 2019
1 parent 4be967c commit 89495d5
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5761,6 +5761,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
gboolean sext = FALSE, zext = FALSE;
gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
gboolean is_unaligned = (ins->flags & MONO_INST_UNALIGNED) != 0;

t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);

Expand Down Expand Up @@ -5793,7 +5794,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)

addr = convert (ctx, addr, LLVMPointerType (t, 0));

values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, base, dname, is_faulting, is_volatile, LLVM_BARRIER_NONE);
if (is_unaligned)
values [ins->dreg] = mono_llvm_build_aligned_load (builder, addr, dname, is_volatile, 1);
else
values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, base, dname, is_faulting, is_volatile, LLVM_BARRIER_NONE);

if (!(is_faulting || is_volatile) && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
/*
Expand All @@ -5811,7 +5815,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
break;
}

case OP_STOREI1_MEMBASE_REG:
case OP_STOREI2_MEMBASE_REG:
case OP_STOREI4_MEMBASE_REG:
Expand All @@ -5825,6 +5829,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
gboolean sext = FALSE, zext = FALSE;
gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
gboolean is_unaligned = (ins->flags & MONO_INST_UNALIGNED) != 0;

if (!values [ins->inst_destbasereg]) {
set_failure (ctx, "inst_destbasereg");
Expand All @@ -5842,13 +5847,19 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
} else {
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
}
if (is_volatile && LLVMGetInstructionOpcode (base) == LLVMAlloca && !(ins->flags & MONO_INST_VOLATILE))
/* Storing to an alloca cannot fail */
is_volatile = FALSE;
emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_faulting, is_volatile);
LLVMValueRef srcval = convert (ctx, values [ins->sreg1], t);
LLVMValueRef ptrdst = convert (ctx, addr, LLVMPointerType (t, 0));

if (is_unaligned)
mono_llvm_build_aligned_store (builder, srcval, ptrdst, is_volatile, 1);
else
emit_store (ctx, bb, &builder, size, srcval, ptrdst, base, is_faulting, is_volatile);
break;
}

Expand All @@ -5863,6 +5874,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
gboolean sext = FALSE, zext = FALSE;
gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
gboolean is_unaligned = (ins->flags & MONO_INST_UNALIGNED) != 0;

t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);

Expand All @@ -5875,10 +5887,15 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
} else {
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
}
emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_faulting, is_volatile);
LLVMValueRef srcval = convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t);
LLVMValueRef ptrdst = convert (ctx, addr, LLVMPointerType (t, 0));
if (is_unaligned)
mono_llvm_build_aligned_store (builder, srcval, ptrdst, is_volatile, 1);
else
emit_store (ctx, bb, &builder, size, srcval, ptrdst, base, is_faulting, is_volatile);
break;
}

Expand Down

0 comments on commit 89495d5

Please sign in to comment.