-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JIT] Fix - Do not remove CAST
nodes on store if the LCL_VAR
is address exposed
#85734
Merged
Merged
Changes from 1 commit
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
004b61a
Do not remove CAST nodes on assignment if the LCL_VAR is a parameter.
TIHan 56570b7
Added NormalizeOnLoad rules from SingleAccretion. Added description o…
TIHan e68875b
Remove morph optimization for NormalizeOnLoad in fgMorphLocalVar. Upd…
TIHan 861bebf
Merging
TIHan 8de354e
Merge remote-tracking branch 'upstream/main' into 85382-fix-2
TIHan b111627
Do not OptimizeCastOnStore for params and struct fields
TIHan d6417d5
Update src/coreclr/jit/morph.cpp
TIHan 0b728de
Formatting
TIHan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
This file contains 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
51 changes: 51 additions & 0 deletions
51
src/tests/JIT/Regression/JitBlue/Runtime_85382/Runtime_85382.cs
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.Runtime.CompilerServices; | ||
using Xunit; | ||
|
||
public class Test | ||
{ | ||
// This is trying to verify that we properly zero-extend on all platforms. | ||
public class Program | ||
{ | ||
public static long s_15; | ||
public static sbyte s_17; | ||
public static ushort s_21 = 36659; | ||
public static int Test() | ||
{ | ||
s_15 = ~1; | ||
return M40(0); | ||
} | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static void Consume(ushort x) { } | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
public static int M40(ushort arg0) | ||
{ | ||
for (int var0 = 0; var0 < 2; var0++) | ||
{ | ||
arg0 = 65535; | ||
arg0 &= (ushort)(s_15++ >> s_17); | ||
arg0 %= s_21; | ||
} | ||
|
||
Consume(arg0); | ||
|
||
if (arg0 != 28876) | ||
{ | ||
return 0; | ||
} | ||
return 100; | ||
} | ||
} | ||
|
||
[Fact] | ||
public static int TestEntryPoint() { | ||
return Test.Program.Test(); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/tests/JIT/Regression/JitBlue/Runtime_85382/Runtime_85382.csproj
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<Optimize>True</Optimize> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="$(MSBuildProjectName).cs" /> | ||
</ItemGroup> | ||
</Project> |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should mention the "why" - i. e. that this is a quirk/workaround for VN's handling of NOL and that we know this is in fact not a complete fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't that these issues are with VN's handling of NOLs; I could be wrong - it's very hard to determine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this issue isn't with VN's handling, then what is it with? We should understand the problem before we work around it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well - we don't know about other bugs related to this, but if there are, surely we would want to find out what they are about as well.
FWIW, example from #85382 looks very much like the VN issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to describe the issue in the description regarding the
mov
elision.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems likely that a peephole in the emitter would be able to get a large portion of the benefit of that subrange assertion check without having to complicate the NOL semantics with how stores are handled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did experiment with adding a peephole to look at redundant
movzx
instructions that would help certain cases.@jakobbotsch so that opt, I disabled it and #85382 did pass, but not #85081.
Here is what I am using to test:
A successful run will print:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I too took a look at the dump for #85382 and the problem (in my interpretation) is that remorphing invalidates previous assumption as made by and acted on in assertion prop (@jakobbotsch - did you mean this too?):
NOL = CAST<short>(...)
.CAST<int>
one).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, except I think the optimization made by local assertion prop makes the model of NOL locals much more complex than it should be (i.e. it means your explanation of NOL locals above is really not the fully story).
Local assertion prop here does not only rely on what it proves by seeing the subrange assertion. It also relies on normalization done by
genUnspillRegIfNeeded
,GT_LCL_VAR
codegen and args homing to make this work.In other words: the assertion only meaningfully describes the upper bits if it just so happens that the local ended up being in a 4-byte home for the time between the assignment that created it and the use.
It's very subtle and hard to reason about this in the face of interacting optimizations like this one (another issue I dug up with an interacting optimization: #66624). So if we could get most of the benefits of this optimization through an emitter peephole, and simplify morph to always normalize, then I think that would be much preferable to the current state of things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, restricting the fix to parameters is not enough, it also needs to pessimize struct fields. The following example fails in the same way: