Upgrade Emscripten to 5.0.6 & LLVM to 23#129299
Draft
akoeplinger wants to merge 120 commits into
Draft
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Mono WASM/Browser toolchain to Emscripten (emsdk) 5.0.6, and refreshes several repo toolset dependency versions (Arcade/Helix/SDK pins) plus related engineering scripts/templates.
Changes:
- Bump Emscripten version from 3.1.56 → 5.0.6 and update the Windows Python package path used for Browser/WASI builds.
- Refresh dependency/version pins in
global.json,eng/Versions.props, andeng/Version.Details.*. - Update engineering infrastructure (NuGet feed setup scripts, ADO templates, OpenBSD rootfs behavior, Helix monitor timeout), and add an opt-in native compiler detection target.
Reviewed changes
Copilot reviewed 8 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mono/mono.proj | Updates Browser/WASI Windows Python path property to match the new Emscripten package ID/version. |
| src/mono/browser/emscripten-version.txt | Updates tracked Emscripten version to 5.0.6. |
| global.json | Updates Arcade/Helix/SharedFramework SDK pins and IL SDK version. |
| eng/Versions.props | Updates EmsdkVersion to 5.0.6. |
| eng/Version.Details.xml | Updates dependency versions/SHAs to the newer dotnet/dotnet toolset flow. |
| eng/Version.Details.props | Updates derived toolset version properties to match Version.Details.xml. |
| eng/native/tryrun.browser.cmake | Updates the version marker for the browser-wasm try_run cache to 5.0.6. |
| eng/common/templates/vmr-build-pr.yml | Switches VMR GitHub endpoint to public. |
| eng/common/templates/job/job.yml | Removes public-only CG skip step (logic moved elsewhere). |
| eng/common/SetupNugetSources.sh | Avoids triggering repo toolset setup as a side effect of feed configuration. |
| eng/common/SetupNugetSources.ps1 | Same as above for PowerShell. |
| eng/common/native/LocateNativeCompiler.targets | Adds an opt-in target to infer linker flags via init-compiler.sh output. |
| eng/common/cross/build-rootfs.sh | Adjusts OpenBSD rootfs package extraction, symlink logic, and cleanup. |
| eng/common/core-templates/steps/enable-internal-sources.yml | Adds non-Windows feed setup path (Bash) alongside Windows (PowerShell). |
| eng/common/core-templates/job/job.yml | Sets public-project variables to skip CG detection / CodeQL auto-injection. |
| eng/common/core-templates/job/helix-job-monitor.yml | Gives Helix monitor tool more buffer time vs. ADO job timeout. |
This comment has been minimized.
This comment has been minimized.
Member
Author
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
41540c2 to
ea8bd08
Compare
This comment has been minimized.
This comment has been minimized.
This was referenced Jun 11, 2026
This comment has been minimized.
This comment has been minimized.
This was referenced Jun 12, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 58 out of 61 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/mono/browser/runtime/assets.ts:30
instantiate_assetno longer recognizes the legacy"js-module-threads"behavior and will now throw in the default case if a custom/older boot config still includes it. Even though the dedicated worker module is being removed, it’s safer to keep accepting this behavior as a no-op for backward compatibility (same asdotnetwasm/symbols).
switch (asset.behavior) {
case "dotnetwasm":
case "js-module-diagnostics":
case "symbols":
// do nothing
break;
Member
|
/azp run runtime-wasm |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Member
|
/azp run runtime-extra-platforms |
|
Azure Pipelines successfully started running 1 pipeline(s). |
This was referenced Jun 21, 2026
Comment on lines
451
to
455
| prepareAssetsWorker(); | ||
| const promises = importModules(); | ||
| const es6Modules = await Promise.all(promises); | ||
| (globalThis as any).name = "em-pthread"; | ||
| await initializeModules(es6Modules as any); |
Comment on lines
7032
to
7036
| values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), ""); | ||
| break; | ||
| case OP_FCONV_TO_R4: | ||
| values [ins->dreg] = emit_fpnarrow (ctx, lhs, LLVMFloatType ()); | ||
| values [ins->dreg] = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""); | ||
| break; |
Comment on lines
+30
to
36
| <!-- TEMPORARY: pinned to the staged emsdk 5.0.6 SDK build on the ci.dot.net/dev feed (only 11.0.100-preview.6.26314.102 is staged there). | ||
| WorkloadTesting.Core.targets installs the SDK at this version from ci.dot.net/dev; do NOT follow | ||
| $(MicrosoftNETWorkloadEmscriptenCurrentManifest110100TransportVersion): merges from main bump it past the staged build, | ||
| and that SDK exists on neither ci.dot.net/dev nor production (dotnet-install fails, MSB3073). | ||
| Repin to the production .NET 11 emsdk 5.0.6 manifest transport (and drop the ci.dot.net/dev wiring) before merge. See dotnet/runtime#113786. --> | ||
| <_DotnetSdkVersion>11.0.100-preview.6.26314.102</_DotnetSdkVersion> | ||
| <SdkVersionForWorkloadTesting Condition="$([System.String]::Compare('$(_GlobalJsonSdkVersion)', '$(_DotnetSdkVersion)')) <= 0">$(_DotnetSdkVersion)</SdkVersionForWorkloadTesting> |
Comment on lines
+87
to
+98
| <!-- Replace ci.dot.net/public with ci.dot.net/dev in the script using the platform's native tools. | ||
| This avoids MSBuild's string/item-list parsing pitfalls (e.g. ';' splitting in WriteLinesToFile, | ||
| line-ending and escaping issues) when round-tripping an entire shell/PowerShell script through | ||
| MSBuild properties. We're already invoking these shells right after, so leverage them directly. --> | ||
| <Message Text="** Replacing ci.dot.net/public with ci.dot.net/dev in $(_DotNetInstallScriptPath)" Importance="High" /> | ||
|
|
||
| <Exec Condition="!$([MSBuild]::IsOSPlatform('windows'))" | ||
| IgnoreStandardErrorWarningFormat="true" | ||
| Command="sed -i.bak 's|ci\.dot\.net/public|ci.dot.net/dev|g' "$(_DotNetInstallScriptPath)" && rm -f "$(_DotNetInstallScriptPath).bak"" /> | ||
| <Exec Condition="$([MSBuild]::IsOSPlatform('windows'))" | ||
| IgnoreStandardErrorWarningFormat="true" | ||
| Command='powershell -ExecutionPolicy ByPass -NoProfile -Command "(Get-Content -Raw -LiteralPath '$(_DotNetInstallScriptPath)').Replace('ci.dot.net/public', 'ci.dot.net/dev') | Set-Content -NoNewline -LiteralPath '$(_DotNetInstallScriptPath)'"' /> |
Comment on lines
22
to
26
| <add key="dotnet11" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/index.json" /> | ||
| <add key="dotnet11-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11-transport/nuget/v3/index.json" /> | ||
| <add key="dotnet-diagnostics-tests" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-diagnostics-tests/nuget/v3/index.json" /> | ||
| <add key="general-testing" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/general-testing/nuget/v3/index.json" /> | ||
| </packageSources> |
lewing
added a commit
to lewing/runtime
that referenced
this pull request
Jun 22, 2026
…umber as intrinsics
Mono's LLVM backend has end-to-end plumbing for OP_FMA, OP_FCOPYSIGN,
OP_SQRTF, etc., but a handful of obvious BCL entry points fall through
to the C# implementations:
* `MathF.Abs(float)` and `MathF.Log(float)` are not recognized in the
MathF block of intrinsics.c, even though MathF.Sqrt/Sin/Cos/Exp/Log2/
Log10/Floor/Ceiling/Truncate all are. (Math.Abs(float) is recognized
via the Math (float) fallback, but Math.Log(float) doesn't exist —
only MathF.Log does.) Adding INTRINS_LOGF + OP_LOGF closes the
gap; MathF.Abs reuses the existing OP_ABSF / INTRINS_ABSF.
* `Single.MinNumber/MaxNumber` and `Double.MinNumber/MaxNumber`
(forwarders for INumber<TSelf>.{Min,Max}Number) are IEEE 754-2008
numNum semantics: when exactly one argument is NaN, return the
non-NaN; when both are NaN, return NaN. These map exactly to
llvm.minnum / llvm.maxnum, which on AArch64 lower to a single
fminnm/fmaxnm instruction. Without recognition the C# bodies inline
to a fcmp+select chain — semantically correct, but several
instructions on every target.
Mono had no recognition for the Single/Double primitive classes
previously; this adds a focused block that only handles MinNumber and
MaxNumber. (Min/Max forward to Math/MathF and are caught by the
existing recognition there.)
Adds:
* OP_LOGF / OP_FMINNUM / OP_FMAXNUM / OP_RMINNUM / OP_RMAXNUM in
mini-ops.h.
* INTRINS_LOGF / INTRINS_MINNUM / INTRINS_MINNUMF / INTRINS_MAXNUM /
INTRINS_MAXNUMF in llvm-intrinsics.h.
* Case handlers in mini-llvm.c (OP_LOGF reuses the existing
scalar-1-arg pattern; the four num/numF ops share a single block
that selects the correct intrinsic by opcode).
* Recognition in intrinsics.c — MathF.Abs/MathF.Log added to the
existing MathF (float) block; MinNumber/MaxNumber added in a new
Single/Double block placed after the Math block.
Validation: on the PR dotnet#129299 branch (emsdk 5.0.6 / LLVM 23) stacked
with the Min/Max NaN fix from PR dotnet#129593, full AOT + LLVM run of
System.Runtime.Tests on iossimulator-arm64:
HalfTests 1442/1442 pass
HalfTests_GenericMath 356/356 pass
SingleTests 1334/1334 pass
DoubleTests 1559/1559 pass
(no regression vs the dotnet#129593-only baseline; covers MinNumber/
MaxNumber on Single/Double)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 22, 2026
Re-link the disabled Mono full-AOT tests from the #129508 tracking issue to the individual PRs that fix them (nullabletypes -> #129702, call05_large/small -> #129708, WPF_3226 -> #129710, b143840 -> #129713, UnitTest_GVM_TypeLoadException -> #129715). The tests stay disabled; Runtime_105619 keeps the #129508 link.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This change upgrades the Emscripten SDK used by the WebAssembly (
browser/wasi)build from 3.1.56 to 5.0.6, which also brings the bundled LLVM from
version 19 (API 1900) to version 23 (API 2300). It updates the native build
flags, the Mono LLVM backend to compile and behave correctly against the new
LLVM, reworks the browser JS loader to drop the separate worker module
(
dotnet.native.worker.mjs), and adjusts/annotates tests affected by the newtoolchain. Arcade SDK and
dotnet-installrelated packaging is also refreshed.Motivation
Staying on a current Emscripten/LLVM toolchain keeps the WASM target aligned with
upstream fixes and modern WebAssembly features. The newer Emscripten reuses the
main module as the pthread worker (removing the need for a dedicated worker JS
file), provides better
futimens/timestamp support in the browser file system,and ships LLVM 23, which required a number of Mono backend adaptations.
Changes by area
Toolchain / version bumps
src/mono/browser/emscripten-version.txt,eng/native/tryrun.browser.cmake:Emscripten
3.1.56→5.0.6.eng/Versions.props:EmsdkVersion3.1.56→5.0.6.src/mono/mono.proj: python package path updated to theMicrosoft.NET.Runtime.Emscripten.5.0.6.Python.win-x64package.eng/Version.Details.xml,eng/Version.Details.props: refreshed Emscripten /Node transport package versions to match the new SDK.
global.json: Arcade / Helix / SharedFramework /Microsoft.NET.Sdk.ILSDKsbumped to
11.0.0-beta.26314.102/11.0.0-preview.6.26314.102.NuGet.config,src/mono/wasm/Wasm.Build.Tests/data/nuget.config: added thegeneral-testingpackage source.Native build flags
eng/native/configureplatform.cmake(CoreCLR browser): add-sWASM_LEGACY_EXCEPTIONS=1to compile and link options, drop-lbulkmemory(bulk memory is now enabled via
-mbulk-memorycompile option).src/mono/browser/browser.proj,src/mono/browser/build/BrowserWasmApp.targets,src/mono/mono/mini/CMakeLists.txt: pass-sWASM_LEGACY_EXCEPTIONS=1alongside-fwasm-exceptions, and select the EH static lib variant via a newCONFIGURATION_EH_LIB(eh-wasmvseh-js) instead of hard-codingeh-js.src/mono/browser/runtime/CMakeLists.txt,src/mono/wasm/build/WasmApp.Common.targets: add--enable-multivalueto thewasm-optinvocation and link the selectedlibmono-wasm-${CONFIGURATION_EH_LIB}.a.Mono LLVM backend (LLVM 23 compatibility) —
src/mono/mono/minimini-llvm-cpp.cpp/mini-llvm-cpp.h: thread an explicitLLVMContextRefthrough
mono_llvm_create_constant_data_arrayandmono_llvm_get_ptr_type,and derive the context from the relevant value/module/function instead of
LLVMGetGlobalContext(). UseIntrinsic::getOrInsertDeclarationforLLVM_API_VERSION >= 2100.mini-llvm.c:-Wdeprecated-declarations/ MSVC 4996 for the pervasive globalLLVM-C type accessors.
const_int8/const_int32(and the 32-bitOP_STORE_*_IMMimmediate path) so a negative
intis not retained as upper bits — LLVM 23no longer truncates when
SignExtend == FALSE, which previously corruptedsubsequent
ZExtconstant folding.emit_fpnarrow/quiet_nan_for_fptypethat detect a NaN input and select a canonical quiet NaN, used by
OP_FCONV_TO_R4and byconvert_fullfor float/double → half (scalar andvector). This guards against LLVM 23 lowering the software Half conversion to
a hardware
fptruncthat drops the NaN mantissa (turning NaN into ±Inf).LLVMConstInt(..., -1, FALSE)withLLVMConstAllOnes(...)where anall-ones value is intended, and pass
SignExtend = TRUEfor the signedOP_ICOMPARE_IMMimmediate.Browser JS loader — drop the separate pthread worker module
Newer Emscripten reuses the main script as the worker, so the dedicated
dotnet.native.worker.mjs/js-module-threadsasset is removed end to end:src/mono/browser/runtime/loader/run.ts: workers now bootstrap via the mainmodule;
createEmscriptenWorkersets up handlers and dispatches theloadmessage, and is invoked when running in a worker.
loaderHelpers.scriptUrlinstead of resolving thejs-module-threadsasset.jsModuleWorkerresource andjs-module-threadsbehavior.dotnet.native.worker.mjs.BootJsonData.cs,BootJsonBuilderHelper.csdrop thejsModuleWorkerboot-resource group.File system timestamps (browser nanosecond support)
src/libraries/System.Private.CoreLib/src/System/IO/FileStatus.Unix.cs: removethe
TARGET_BROWSER/TARGET_WASIspecial case that wrote both access and writetimes together; the new Emscripten honors per-field
futimens/utimensat.System.IO.FileSystem.Tests: refactor the temporal-resolution model inBaseGetSetTimestoSecondTemporalResolution/MilliSecondTemporalResolution/NanoSecondTemporalResolution(and theNot*variants), and remove now-obsolete Browser carve-outs/ActiveIssues inFile/Copy.cs,File/GetSetTimes.cs, andFileInfo/GetSetTimes.cs.Test annotations for the new toolchain
System.Runtime.TestsHalfTests.cs/HalfTests.GenericMath.cs: addActiveIssue(MonoAOT: LLVM 23 regressions in Half NaN handling #129507) for iOS on the Half NaN/conversion math tests.Wasm.Build.Tests:EventPipeDiagnosticsTestsannotated withActiveIssue([wasm] Wasm.Build.Tests EventPipeDiagnosticsTests CPU-sampling tests fail after emsdk 5.0.6 / LLVM 23 legacy-EH change #129584);
BuildEnvironment/ProjectProviderBase/WasmSdkBasedProjectProviderupdated to stop expecting
dotnet.native.worker.mjs.ActiveIssue(MonoInterp/Minijit win-x64: COM interop (SafeArray/Variant/struct reverse-pinvoke) test failures #129581 / MonoAOT: LLVM 23 regressions in FullAOT JIT test outcomes #129508) for Mono onCOM/VARIANT/struct-marshalling and several nullable/localloc/GVM tests
(including IL
.customActiveIssueAttributeentries).Active issues caused by this upgrade
Followup #129396