-
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] Fixed improper peephole zero-extension removal when cdq/cwde instructions are involved #82733
Conversation
…tructions are involved
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak |
src/coreclr/jit/emitxarch.cpp
Outdated
@@ -526,6 +526,16 @@ bool emitter::AreUpper32BitsZero(regNumber reg) | |||
} | |||
} | |||
|
|||
// This is a special case for cdq/cdqe/cwde. | |||
// They always write to and sign-extend RAX. |
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.
notably: cwd
is AX -> DX:AX
cdq
is EAX -> EDX:EAX
cqo
is RAX -> RDX:RAX
There are also a few other instructions that implicitly write specific outputs (typically edx
and eax
) or which take implicit inputs (often edx
, eax
, ecx
, esi
, or edi
)
Wonder if they should be more generally modeled or tracked?
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.
They probably should be.
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.
Will need to check cdq
for EDX.
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.
cmpxchg16b
also can write RDX:RAX
(and reads RCX:RBX
)
div
, idiv
, imul
, and mul
writes RDX:RAX
(and generally, but not always, reads the same)
Might be others that I'm forgetting.
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 think we emit cmpxchg16b
or even cmpxchg8b
AFAIK. But I did need to check for cmpxchg
.
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 am wondering if there is a good way to track such instructions or generalize the process with adequate asserts so we can catch the issues earlier? Tracking these issues with bad code gen are really hard to investigate.
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.
All I can think of is to make it more table-driven, otherwise a function that asks the question should be adequate.
Given we are only doing these checks here, we probably could create a function that simply asks "Did the instruction write to this register?" and the result is either 'true' or 'false', and if 'true' we can also provide if it zero-extended or not.
I think I'm going to have to do this anyway for #82733 because I need to re-use the checks of whether or not a register was written to.
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 am more worried if we miss an entry of one of the instructions that we support, we might have similar bug. Is there a manual that we can refer and put all those instructions in the table or whatever data structure we have and also post the link of the manual so someone looking at the code in future can know where it is coming from?
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 Intel and AMD architecture manuals are the relevant resource.
The ones I listed are the ones that write two registers. There are others, like cmpxchg
, which may write a single dedicated register.
It's likely just going to require someone going through the instructions and checking for cases that use a fixed/non-specified register (for input and/or output)
@dotnet/jit-contrib @kunalspathak this is ready |
@dotnet/jit-contrib This is ready again. I introduced a function, |
Resolves #82685