You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Observed on PR branch emsdk-upgrade / #129299: runtime-llvm linux-x64 FullAOT runtime tests regress under LLVM 23 (e.g. nullabletypes returns Expected 100, Actual 666). Each affected test is disabled via [ActiveIssue("https://github.com/dotnet/runtime/issues/129508", ...)] on the emsdk-upgrade branch. The failures have multiple distinct root causes (see below).
nullabletypes → [mono][amd64] Pass small straddling vtypes in registers in both backends #129702 — [mono][amd64] Pass small straddling vtypes in registers in the LLVM backend.
Root cause: a ≤16-byte all-integer value type whose nested field straddles the 8-byte SysV eightbyte boundary (e.g. Nullable<T> with an 8-byte T) was passed byval by the partially-shared caller — which LLVM 18+ lowers onto the stack — while the concrete callee reads it from two integer registers, corrupting the value. Fixed by passing such vtypes in registers in the amd64 LLVM call-info. amd64-only.
call05_large / call05_small → [mono] AOT-compile methods that use the IL jmp opcode #129708 — [mono] AOT-compile methods that use the IL jmp opcode.
Root cause: these tests jmp to another method from a method that also uses localloc. The non-llvm_onlyCEE_JMP path emitted an OP_TAILCALL and called DISABLE_AOT(), so the method was excluded from the AOT image; under full-AOT (aot-only) the call then tried to JIT it and failed. Fixed by emitting jmp as a plain call + return for AOT, keeping the method in the image. Pre-existing; newly exposed by the x64 Mono full-AOT leg.
WPF_3226 → [mono] AOT-compile marshalling wrappers for layout classes with class-typed fields #129710 — [mono] AOT-compile marshalling wrappers for layout classes with class-typed fields.
Root cause: can_marshal_struct() in the AOT compiler did not handle MONO_TYPE_CLASS fields, so a [StructLayout] class whose fields are themselves marshalable layout classes (e.g. MINMAXINFO with two POINT fields) was treated as non-marshalable and its StructureToPtr/PtrToStructure wrappers were not emitted into the AOT image; the call then failed to JIT under aot-only. Fixed by recursing into can_marshal_struct() for class-typed fields. Pre-existing; newly exposed by the x64 Mono full-AOT leg.
b143840 → [mono] Keep in-flight exception alive across LLVM resume unwind #129713 — [mono] Keep in-flight exception alive across LLVM resume unwind.
Root cause: when unwinding through an LLVM-compiled finally/fault handler, the in-flight exception object was stored as a raw pointer in ResumeState.ex_obj (marked /* FIXME: GC */) across the managed handler (e.g. the Monitor.Exit of a synchronized wrapper). That handler can reach a GC safepoint, and a moving GC relocates the exception, leaving the pointer stale; mono_resume_unwind then passes it to mono_object_isinst_checked during the catch search and dereferences a garbage MonoClass → intermittent SIGSEGV under load. Fixed by keeping the exception alive in a pinned GC handle across the resume window (as the llvmonly path already does). Pre-existing; newly exposed by the x64 Mono full-AOT leg.
UnitTest_GVM_TypeLoadException → [mono] Defer NEWOBJ type-load failures to runtime in AOT mode #129715 — [mono] Defer NEWOBJ type-load failures to runtime in AOT mode.
Root cause: each of the four RunInvalidTestN helpers does newobj of a type with an invalid covariant-return override. Resolving the constructor fails with a type-load error during AOT compilation, so the AOT compiler aborted and excluded the whole method from the image; under full-AOT (aot-only) the call then attempted a JIT compile and threw ExecutionEngineException instead of the expected TypeLoadException, which the test's catch did not handle. Fixed by deferring the type-load failure to a runtime throw in AOT (turning the method into one that throws TypeLoadException, as the ldfld path already does), matching the JIT behavior. The IsNativeAot annotation is kept (NativeAOT has the same limitation). Pre-existing; newly exposed by the x64 Mono full-AOT leg.
Note
This issue description was updated with the assistance of GitHub Copilot.
Summary
Observed on PR branch emsdk-upgrade / #129299: runtime-llvm linux-x64 FullAOT runtime tests regress under LLVM 23 (e.g.
nullabletypesreturns Expected 100, Actual 666). Each affected test is disabled via[ActiveIssue("https://github.com/dotnet/runtime/issues/129508", ...)]on theemsdk-upgradebranch. The failures have multiple distinct root causes (see below).All scenarios now have fixes in flight.
Failing scenarios
JIT/Directed/nullabletypes/castclassvaluetype,JIT/Directed/nullabletypes/Desktop/boxunboxvaluetype(Expected 100, Actual 666) — fixed by [mono][amd64] Pass small straddling vtypes in registers in both backends #129702JIT/Regression/JitBlue/Runtime_105619— collectible-ALC load + reflection invoke (not codegen) — covered by [mono] Fix re-entrant AssemblyLoadContext resolution stack overflow under full-AOT #129693JIT/jit64/localloc/call/call05_large(localloc +jmp) — fixed by [mono] AOT-compile methods that use the IL jmp opcode #129708JIT/jit64/localloc/call/call05_small(localloc +jmp) — fixed by [mono] AOT-compile methods that use the IL jmp opcode #129708JIT/Regression/JitBlue/WPF_3226(Marshal.StructureToPtr/Marshal.PtrToStructuremarshalling) — fixed by [mono] AOT-compile marshalling wrappers for layout classes with class-typed fields #129710JIT/Regression/CLR-x86-JIT/V1.1-M1-Beta1/b143840(synchronizedmethods / exception throw) — fixed by [mono] Keep in-flight exception alive across LLVM resume unwind #129713Loader/classloader/MethodImpl/CovariantReturns/UnitTest(GVM covariant returns +TypeLoadException) — fixed by [mono] Defer NEWOBJ type-load failures to runtime in AOT mode #129715Fixes
nullabletypes → [mono][amd64] Pass small straddling vtypes in registers in both backends #129702 — [mono][amd64] Pass small straddling vtypes in registers in the LLVM backend.
Root cause: a
≤16-byte all-integer value type whose nested field straddles the 8-byte SysV eightbyte boundary (e.g.Nullable<T>with an 8-byteT) was passedbyvalby the partially-shared caller — which LLVM 18+ lowers onto the stack — while the concrete callee reads it from two integer registers, corrupting the value. Fixed by passing such vtypes in registers in the amd64 LLVM call-info. amd64-only.Runtime_105619 → [mono] Fix re-entrant AssemblyLoadContext resolution stack overflow under full-AOT #129693 — [mono] Fix re-entrant AssemblyLoadContext resolution stack overflow under full-AOT.
This test is not a codegen failure: its
TestEntryPointloads the assembly into a collectibleAssemblyLoadContextand invokes a method via reflection (the Fuzzlyn payload itself NREs on uninitialized statics and is swallowed bytry {} catch {}), so the only failure mode is a process crash during the ALC load/invoke — the re-entrant ALC resolution stack overflow that [mono] Fix re-entrant AssemblyLoadContext resolution stack overflow under full-AOT #129693 fixes. (Structural match; merged-harness confirmation pending.)call05_large / call05_small → [mono] AOT-compile methods that use the IL jmp opcode #129708 — [mono] AOT-compile methods that use the IL
jmpopcode.Root cause: these tests
jmpto another method from a method that also useslocalloc. The non-llvm_onlyCEE_JMPpath emitted anOP_TAILCALLand calledDISABLE_AOT(), so the method was excluded from the AOT image; under full-AOT (aot-only) the call then tried to JIT it and failed. Fixed by emittingjmpas a plain call + return for AOT, keeping the method in the image. Pre-existing; newly exposed by the x64 Mono full-AOT leg.WPF_3226 → [mono] AOT-compile marshalling wrappers for layout classes with class-typed fields #129710 — [mono] AOT-compile marshalling wrappers for layout classes with class-typed fields.
Root cause:
can_marshal_struct()in the AOT compiler did not handleMONO_TYPE_CLASSfields, so a[StructLayout]class whose fields are themselves marshalable layout classes (e.g.MINMAXINFOwith twoPOINTfields) was treated as non-marshalable and itsStructureToPtr/PtrToStructurewrappers were not emitted into the AOT image; the call then failed to JIT under aot-only. Fixed by recursing intocan_marshal_struct()for class-typed fields. Pre-existing; newly exposed by the x64 Mono full-AOT leg.b143840 → [mono] Keep in-flight exception alive across LLVM resume unwind #129713 — [mono] Keep in-flight exception alive across LLVM resume unwind.
Root cause: when unwinding through an LLVM-compiled
finally/faulthandler, the in-flight exception object was stored as a raw pointer inResumeState.ex_obj(marked/* FIXME: GC */) across the managed handler (e.g. theMonitor.Exitof asynchronizedwrapper). That handler can reach a GC safepoint, and a moving GC relocates the exception, leaving the pointer stale;mono_resume_unwindthen passes it tomono_object_isinst_checkedduring the catch search and dereferences a garbageMonoClass→ intermittentSIGSEGVunder load. Fixed by keeping the exception alive in a pinned GC handle across the resume window (as thellvmonlypath already does). Pre-existing; newly exposed by the x64 Mono full-AOT leg.UnitTest_GVM_TypeLoadException → [mono] Defer NEWOBJ type-load failures to runtime in AOT mode #129715 — [mono] Defer NEWOBJ type-load failures to runtime in AOT mode.
Root cause: each of the four
RunInvalidTestNhelpers doesnewobjof a type with an invalid covariant-return override. Resolving the constructor fails with a type-load error during AOT compilation, so the AOT compiler aborted and excluded the whole method from the image; under full-AOT (aot-only) the call then attempted a JIT compile and threwExecutionEngineExceptioninstead of the expectedTypeLoadException, which the test'scatchdid not handle. Fixed by deferring the type-load failure to a runtime throw in AOT (turning the method into one that throwsTypeLoadException, as theldfldpath already does), matching the JIT behavior. TheIsNativeAotannotation is kept (NativeAOT has the same limitation). Pre-existing; newly exposed by the x64 Mono full-AOT leg.Note
This issue description was updated with the assistance of GitHub Copilot.