-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Fix Valuenum:EvalFuncForConstantArgs #17506
Conversation
PTAL @briansull , @dotnet/jit-contrib . |
I am not intimately familiar with value numbering, but it seems surprising to me that we would effectively be considering a null VN to be a valid VN. It doesn't seem fundamentally that we couldn't fold |
While this fix is fine, we should also fix the problem where the optimization was performed because both VN were 0. After we find the matching value number we shoudl assert that the value isn't 0 and then if it is we should bail out and not perform the optimization (so the retail builds are also correct) |
Null is valid VN, look at Lines 917 to 930 in 7ae64f0
We have |
Yes, no diffs for System.Private.CoreLib (x64). |
Ah, so if Null is the VN for a zero constant value, why are these nodes getting the Null VN? |
if (typ == TYP_BYREF) | ||
{ | ||
// We don't want to fold expressions that produce TYP_BYREF | ||
return false; |
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.
Ah, so if Null is the VN for a zero constant value, why are these nodes getting the Null VN?
Because EvalFuncForConstantArgs
returns ValueNum
and return false;
was casted to ValueNum
(that is int), so this function returned 0(null)
for all byrefs with constant arguments.
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.
Looks Good
Thanks for clarifying that a null VN is currently a valid VN.
|
It looks like |
Picks up dotnet/coreclr#17506. Fixes dotnet#5661.
Picks up dotnet/coreclr#17506. Fixes #5661.
For such tree:
where
LCL_VAR ref V43
is known to be a constant RyuJit calculated Vn as Null:N010 [008526] ADD => $VN.Null
and merged it with other expressions with Null VN. Because constants were different in each case it caused bugs:
VN [008535] == VN [008526] == Null
, so all these constants were replaced with the first tree that hadVN == Null
:The original code was added in CS 946058 with other assert fixes and looks like we were lucky not to hit this issue for several years because CoreCLR doesn't produce constants with 'TYP_BYREF' (I think).
I do not see any reasons why we should not fold them, but right now this code:
https://github.com/dotnet/coreclr/blob/master/src/jit/valuenum.cpp#L1813-L1817
doesn't not expect LONG add that produces BYREF and because our VN is very fragile we do not want to change it before the release, do we want to have an issue to fix that later?
The change will fix (some text to prevent closing this issue right after the merge) dotnet/corert#5661 after RyuJit version update.