-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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] X64/ARM64 - CAST
removals for small types on ADD
, SUB
, MUL
, AND
, OR
, XOR
, NOT
, NEG
#77874
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue Detailsnull
|
not
/ neg
/azp run Fuzzlyn |
Azure Pipelines successfully started running 1 pipeline(s). |
…ation if the op is a local
/azp run Fuzzlyn |
Azure Pipelines successfully started running 1 pipeline(s). |
There is a minor issue that we think is not caused by this caused, but the change is allowing the issue to manifest itself. Here is a dump of some potential wrong IR for value number:
|
CC @markples for code review.
|
[edit - added one more to keep them together] General comments on the tests:
|
|
||
if ((byte)(x & y) == 0) | ||
{ | ||
SideEffect(); |
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.
What is SideEffect
doing here? Do we get different code generation if we are only producing 1/0 vs needing control flow?
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 need to have some sort of side effect to happen. Because if I do this example:
if ((byte)(x & y) == 0)
{
return true;
}
return false;
I'm not going to get a branch.
I need a branch in order to see the and
op using 16-bit or 8-bit operations. We only use 16-bit/8-bit operations for 'and','or','xor' if it involves a branch.
} | ||
|
||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
static bool Test_UInt32_UInt32_CastByte_And(uint x, uint y) |
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.
Do you need a CastByte
variant for the RHS of the operation to make sure that both tree shapes work?
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.
Not sure what you mean here. What is the RHS in this case?
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 ((byte)(x & (byte)y) == 0)
Sorry, RHS was inaccurate.. "right operand of the &" would have been better
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 see, I think it's fine and we don't need to add another test case. In this test case, if the second op of and
is an 8-bit register, I can feel pretty confident that casting the byte will still result in using an 8-bit register.
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.
The next test case below this one casts both ops and still gives an 8-bit register.
public static sbyte[] M75() | ||
{ | ||
return default(sbyte[]); | ||
} | ||
} | ||
|
||
public interface IRuntime | ||
{ | ||
void WriteLine<T>(T value); | ||
} | ||
|
||
public class Runtime : IRuntime | ||
{ | ||
public void WriteLine<T>(T value) { } | ||
} |
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 really follow what this test is doing. There's a bit of short arithmetic - do the try, M75 call, WriteLines, etc., all contribute to some codegen impact?
I'll have similar questions for the other tests like this, so I'll wait to hear what this is before trying to understand them.
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 see your comment above about the test being brittle (failing to repro with changes). It seems like it is likely that a future JIT change will impact the IR so that this test won't be useful anymore. I'm not sure what to do about that, though if there's nothing productive to do, perhaps having the conditions in the JIT that led to incorrect behavior listed in the test would be helpful?
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 test was generated by Fuzzlyn that caught an assertion/wrong value in the early implementation of this change. So I kept this test to make sure that it doesn't happen again. It's not checking for any disassembly, it is just to make sure it gives the correct result.
Thank you for the feedback @markples |
Because these are tests, I'm not committed to only use a certain style. If the test does what it is supposed to do and looks readable enough, then it's fine to me.
It's as it sounds, it is just a
For the right answers, I run the test in different versions of .NET to see if I get the same results - if I do, then it's very highly likely that it's correct. I feel confident about this because in the early implementation of this change, some of those tests started failing, so I know that it is covering it. For FileCheck lines, I use @EgorBo 's awesome tool |
Hey @EgorBo , just pinging again. I fixed the merge conflicts and turned off the optimization if optimizations are disabled; I figure that is the right call. |
Description
Should address most of: #44849
The transformation here is straight-forward, consider the example IR:
can be safely transformed in lowering into:
This removes the
CAST
for the inputs on the operationsADD
,SUB
,MUL
,AND
,OR
,XOR
,NOT
, andNEG
. Removing theCAST
gets rid ofmovzx
/movsx
instructions on X64, anduxtb
/sxtb
instructions on ARM64. This is safe to do because it doesn't matter if the inputs are zero/sign-extended as the result of the operations are zero/signed-extended anyway and the operations of the upper bits do not affect the lower bits.Acceptance Criteria
AND
,OR
,XOR
#79126