Description
After migrating some projects to .NET 8 we observe some behaviour differences in certain methods in release builds, which only occur once those methods have been optimised by the JIT.
Disabling tiered PGO changes the method that fails, but does not fix the problem.
Examining the disassembly suggests a parameter value is being accidentally overwritten.
Reproduction Steps
Note that running using debug configuration does not exhibit the problem.
Expected behavior
Should complete with no output.
Actual behavior
Prints exception (thrown because a range-check fails).
Regression?
The program behaves as expected in .NET 6 (6.0.27) and .NET 7 (7.0.14).
Known Workarounds
No response
Configuration
- .NET SDK 8.0.201
- Windows 10 Enterprise, 10.0.19045
- x64
Originally observed via some test failures in CI, running on Windows Server 2016 v10.0 with .NET SDK 8.0.101.
Other information
I have included a README in the repo (https://github.com/chris-white-wtw/JitIssue) with the information I've found so far.
Essentially, in each of the two variants of the bug (with and without tiered PGO), the disassembly of an optimised method includes a vmovq instruction that prematurely moves r8 to a xmm register that's still holding one of the other parameter values.
Description
After migrating some projects to .NET 8 we observe some behaviour differences in certain methods in release builds, which only occur once those methods have been optimised by the JIT.
Disabling tiered PGO changes the method that fails, but does not fix the problem.
Examining the disassembly suggests a parameter value is being accidentally overwritten.
Reproduction Steps
dotnet run -c releaseNote that running using debug configuration does not exhibit the problem.
Expected behavior
Should complete with no output.
Actual behavior
Prints exception (thrown because a range-check fails).
Regression?
The program behaves as expected in .NET 6 (6.0.27) and .NET 7 (7.0.14).
Known Workarounds
No response
Configuration
Originally observed via some test failures in CI, running on Windows Server 2016 v10.0 with .NET SDK 8.0.101.
Other information
I have included a README in the repo (https://github.com/chris-white-wtw/JitIssue) with the information I've found so far.
Essentially, in each of the two variants of the bug (with and without tiered PGO), the disassembly of an optimised method includes a
vmovqinstruction that prematurely movesr8to axmmregister that's still holding one of the other parameter values.