Skip to content

Commit

Permalink
[mono][wasm][aot] Prevent llvm from optimizing away stack stores of v…
Browse files Browse the repository at this point in the history
…aluetypes containing object references when they are returned from a method as a scalar. (#85152)

Fixes #85012.
  • Loading branch information
vargaz authored Apr 22, 2023
1 parent af07521 commit c7aadc0
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,6 @@ public void BinarySearch()
}

[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/85012", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
public void BinarySearchPartialSortedList()
{
ImmutableArray<int> reverseSorted = ImmutableArray.CreateRange(Enumerable.Range(1, 150).Select(n => n * 2).Reverse());
Expand Down
13 changes: 10 additions & 3 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -4756,7 +4756,8 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
mono_llvm_add_instr_byval_attr (lcall, 1 + ainfo->pindex, LLVMGetElementType (param_types [ainfo->pindex]));
}

gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (sig->ret));
MonoClass *retclass = mono_class_from_mono_type_internal (sig->ret);
gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, retclass);
gboolean should_promote_to_value = FALSE;
const char *load_name = NULL;
/*
Expand Down Expand Up @@ -4821,11 +4822,17 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
case LLVMArgGsharedvtFixedVtype:
values [ins->dreg] = LLVMBuildLoad2 (builder, rtype, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (rtype), FALSE), "");
break;
case LLVMArgWasmVtypeAsScalar:
case LLVMArgWasmVtypeAsScalar: {
/*
* If the vtype contains references, making the store volatile ensures there is a reference
* on the stack.
*/
gboolean is_volatile = m_class_has_references (retclass);
if (!addresses [call->inst.dreg])
addresses [call->inst.dreg] = build_alloca_address (ctx, sig->ret);
LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE));
emit_store (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE), is_volatile);
break;
}
default:
if (sig->ret->type != MONO_TYPE_VOID)
/* If the method returns an unsigned value, need to zext it */
Expand Down

0 comments on commit c7aadc0

Please sign in to comment.