Skip to content

Commit c7aadc0

Browse files
authored
[mono][wasm][aot] Prevent llvm from optimizing away stack stores of valuetypes containing object references when they are returned from a method as a scalar. (#85152)
Fixes #85012.
1 parent af07521 commit c7aadc0

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

src/libraries/System.Collections.Immutable/tests/ImmutableListTestBase.cs

-1
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ public void BinarySearch()
419419
}
420420

421421
[Fact]
422-
[ActiveIssue("https://github.com/dotnet/runtime/issues/85012", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
423422
public void BinarySearchPartialSortedList()
424423
{
425424
ImmutableArray<int> reverseSorted = ImmutableArray.CreateRange(Enumerable.Range(1, 150).Select(n => n * 2).Reverse());

src/mono/mono/mini/mini-llvm.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -4756,7 +4756,8 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
47564756
mono_llvm_add_instr_byval_attr (lcall, 1 + ainfo->pindex, LLVMGetElementType (param_types [ainfo->pindex]));
47574757
}
47584758

4759-
gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type_internal (sig->ret));
4759+
MonoClass *retclass = mono_class_from_mono_type_internal (sig->ret);
4760+
gboolean is_simd = MONO_CLASS_IS_SIMD (ctx->cfg, retclass);
47604761
gboolean should_promote_to_value = FALSE;
47614762
const char *load_name = NULL;
47624763
/*
@@ -4821,11 +4822,17 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
48214822
case LLVMArgGsharedvtFixedVtype:
48224823
values [ins->dreg] = LLVMBuildLoad2 (builder, rtype, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (rtype), FALSE), "");
48234824
break;
4824-
case LLVMArgWasmVtypeAsScalar:
4825+
case LLVMArgWasmVtypeAsScalar: {
4826+
/*
4827+
* If the vtype contains references, making the store volatile ensures there is a reference
4828+
* on the stack.
4829+
*/
4830+
gboolean is_volatile = m_class_has_references (retclass);
48254831
if (!addresses [call->inst.dreg])
48264832
addresses [call->inst.dreg] = build_alloca_address (ctx, sig->ret);
4827-
LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE));
4833+
emit_store (builder, lcall, convert_full (ctx, addresses [call->inst.dreg]->value, pointer_type (LLVMTypeOf (lcall)), FALSE), is_volatile);
48284834
break;
4835+
}
48294836
default:
48304837
if (sig->ret->type != MONO_TYPE_VOID)
48314838
/* If the method returns an unsigned value, need to zext it */

0 commit comments

Comments
 (0)