镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Keep volatile indirections of promoted struct fields - #136940

Merged
jakobbotsch merged 1 commit into
dotnet:mainfrom
NinoFloris:jit/volatile-struct-fields
Nov 6, 2026
Merged

jakobbotsch merged 1 commit into
dotnet:mainfrom
NinoFloris:jit/volatile-struct-fields

Conversation

@NinoFloris

Copy link
Copy Markdown
Contributor

Fixes #136936, a longstanding bug that was kept around as a quirk for zero-diffs at the time. Disasm tests here are a bit fragile, though arm has stabilized its instructions around this now, but I'd rather have them than not.

@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 3, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
10 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Nov 3, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jakobbotsch

jakobbotsch commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Disasm tests here are a bit fragile, though arm has stabilized its instructions around this now, but I'd rather have them than not.

I don't agree. These tests are much too fragile, relying on exact promotion heuristics that are going to be changing in this release. I don't think the test is needed.

I would be ok with outerloop test that validates that a volatile load was not dropped by testing for a race.

@jakobbotsch

Copy link
Copy Markdown
Member

a longstanding bug that was kept around as a quirk for zero-diffs at the time

FWIW, this used to have quite significant diffs around structs that were later proved to be not exposed. Looks like something changed since the diffs are very minimal now, however.

@NinoFloris

Copy link
Copy Markdown
Contributor Author

Disasm tests here are a bit fragile, though arm has stabilized its instructions around this now, but I'd rather have them than not.

I don't agree. These tests are much too fragile, relying on exact promotion heuristics that are going to be changing in this release. I don't think the test is needed.

I would be ok with outerloop test that validates that a volatile load was not dropped by testing for a race.

The checks count loads and pass whether or not the struct is promoted. The only fragility I see here is the acquire instruction regex. Which heuristic do you think will break it?

I have also added an outerloop race test next to the volatile class field tests.

@jakobbotsch

Copy link
Copy Markdown
Member

The checks count loads and pass whether or not the struct is promoted. The only fragility I see here is the acquire instruction regex. Which heuristic do you think will break it?

We do not have good experiences with disassembly tests for anything but validating the absence of instructions or exact expected instruction foldings. A few things that can go wrong in your patterns:

  1. Registers that don't match your pattern (like r8d or any APX register)
  2. The JIT emitting any load not covered by your pattern (e.g. movsxd or movzx if we widened the arithmetic)
  3. Future IPA can prove facts about Publish whether or not it is marked NoInlining. I don't think it is likely we will get there, but actually native compilers do this.

I would rather see the behavior validated, whenever possible.

I have also added an outerloop race test next to the volatile class field tests.

Is it possible to write this test in a way where we can have a signal that we would have expected to see differing values?
The shape of this test does not look very appealing to me either.

I would personally suggest just not adding a test.

@NinoFloris
NinoFloris force-pushed the jit/volatile-struct-fields branch from f56e07b to 975f0c9 Compare November 4, 2026 15:14
@NinoFloris

Copy link
Copy Markdown
Contributor Author

Dropped the tests, under mild protest ;)

@jakobbotsch

Copy link
Copy Markdown
Member

Would a test doing

int first = shared.Value;
int changed = shared.Changed;
int second = shared.Value;
if (changed > first && second < changed)
  Assert.Fail(...);

from one thread, and

for (int i = 0; i < int.MaxValue; i++)
{
  shared->Value = i;
  shared->Changed = i;
}

from another be able to show the failure? That is the kind of test I would be ok with adding.

@NinoFloris

Copy link
Copy Markdown
Contributor Author

That shape does not catch the issue. Without the volatile flag the JIT hoists or reorders the reads around Changed, so all three variants I tried pass on main. The disagreement test I had earlier fails on main by timeout and passes with the fix in milliseconds.

@NinoFloris
NinoFloris marked this pull request as draft November 4, 2026 18:48
@NinoFloris
NinoFloris marked this pull request as ready for review November 4, 2026 18:48

@jakobbotsch jakobbotsch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@jakobbotsch

Copy link
Copy Markdown
Member

/ba-g Failure is #136758

@jakobbotsch
jakobbotsch merged commit bcd163f into dotnet:main Nov 6, 2026
127 of 129 checks passed
@NinoFloris
NinoFloris deleted the jit/volatile-struct-fields branch November 6, 2026 14:00
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Volatile reads of a promoted struct's field lose volatile semantics when the struct is address-exposed

2 participants