Uh oh!
There was an error while loading. Please reload this page.
[RuntimeAsync] Enable runtime async in Libraries partition - #119432
[RuntimeAsync] Enable runtime async in Libraries partition#119432VSadov wants to merge 2 commits into
Conversation
VSadov
commented
Sep 6, 2025
A lot of tests actually run and pass when I run this locally. More than I expected. :-) |
Some JIT asserts: |
Something odd is going on with sync context in a few cases: |
I have a fix for the following assert: looking at others. |
| // TODO: (async) we do not need to save ByRef-containing locals | ||
| // as by the spec an await turns them into zero-inited state. | ||
| // For now just store/restore as if there are no gc refs. | ||
| // This is mostly to handle the "fake" live-across-await byrefs | ||
| // in min-opts, since C#-compiled code by itself does not let | ||
| // byrefs be live across awaits. | ||
| unsigned objCount = layout->HasGCByRef() ? 0 : layout->GetGCPtrCount(); |
There was a problem hiding this comment.
We will need to figure out what is creating these LIR edges that are live across the await and stop doing that. This fix will replace assert with bad codegen instead.
There was a problem hiding this comment.
I typically see the assert when compiling Debug code for Task-returning methods with ref-like parameters.
Ex:
publicstaticTaskWhenAll(paramsReadOnlySpan<Task>tasks){async
This method is not async, but it's thunk will be async and will also have a byref-like parameter.
The part that the edge lives across the await is likely a result of Debug not tracking liveness precisely.
Once we have zeroing of byrefs that live across await, we may not need this.
This is not a fix. It is a workaround. - my goal is to get all Libraries tests pass or find something truly blocking.
There was a problem hiding this comment.
Assuming that it is a result of Debug emit, perhaps forcing thunks to always compile optimized might be an alternative workaround, if there is an easy way to force.
I just thought of this workaround first and it seems working well enough.
There was a problem hiding this comment.
The part that the edge lives across the await is likely a result of Debug not tracking liveness precisely.
There are two sources of live state across async calls in JIT IR:
- Locals. These behave like IL locals and can be multiply defined and multiply used. They are what liveness analysis treat. They are added by
AsyncLiveness::GetLiveLocals. - LIR edges. These are single-def single-use (SDSU) values that are defined in one place in a basic block and consumed later in the same basic block. When they overlap an async call (defined before, used after) they must also be preserved on heap. Liveness analysis does not treat these; they are known to be live when they overlap the call. They are added by
AsyncTransformation::LiftLIREdges.
The liveness imprecision only comes into play for (1). However, we already ignore byref locals for these. It happens here:
runtime/src/coreclr/jit/async.cpp
Lines 507 to 515 in b0b30e7
That just leaves (2). But since these are known to be live, it is (almost?) always going to be a bug that resulted in these.
There was a problem hiding this comment.
Good point! I will log an issue on this - to follow up with real fix.
VSadov
commented
Sep 11, 2025
I see only 26 failed tests now in Chk/Ret configuration on win-x64. There are 23 cases of There are also 8 cases of Also fixing one thing sometimes exposes another, but so far with every fix/workaround I see more tests passing. |
The AVs in Logged an issue on that - #119796 and pushed a possible fix here. Now my local run is down to:
|
MichalStrehovsky
commented
Dec 11, 2025
Would it make sense to start testing with runtime async enabled in CoreLib too? |
503a3d4 to
997d50eComparee4bad2a to
4c67325CompareThere was a problem hiding this comment.
Pull request overview
This PR attempts to enable the “runtime async” compiler feature for the Libraries build by setting MSBuild properties at the src/libraries level.
Changes:
- Enable
runtime-async=onvia$(Features)under a runtime/arch/build-mode condition. - Globally suppress
SYSLIB5007warnings undersrc/libraries. - Enable preview features for all libraries builds.
Uh oh!
There was an error while loading. Please reload this page.
| <PropertyGroup> | ||
| <Features Condition="'$(RuntimeFlavor)' != 'mono' and '$(TestBuildMode)' != 'nativeaot' and '$(TargetArchitecture)' != 'wasm'">$(Features);runtime-async=on</Features> | ||
| <NoWarn>$(NoWarn);SYSLIB5007</NoWarn> | ||
| <EnablePreviewFeatures>true</EnablePreviewFeatures> |
There was a problem hiding this comment.
EnablePreviewFeatures is being set unconditionally for all libraries builds (even when the runtime-async feature flag condition is false). That’s a very broad behavioral change; it should be conditioned the same way as runtime-async (or otherwise scoped to the intended partition) to avoid enabling preview language/features across the entire libraries build.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
VSadov
commented
Feb 17, 2026
This PR has lots of now outdated comments. I will open another one |
Mostly to see what happens and how far we can get with this.