-
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: Support containing compares in GT_SELECT for xarch (i.e. start emitting cmov instructions) #81267
JIT: Support containing compares in GT_SELECT for xarch (i.e. start emitting cmov instructions) #81267
Changes from 15 commits
2963b54
2137d36
b25d4b0
2f2942c
4da299f
4ca94e2
dfa5617
b6b1f41
640e59a
a91e977
9499a66
ac1c27b
934f719
3fb62ea
5a95fd4
292f5fa
6f59c5e
1f5fe5a
5a7a569
3f56930
3845b74
9da5486
93ae093
44a89aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1064,7 +1064,7 @@ regMaskTP GenTree::gtGetContainedRegMask() | |
{ | ||
if (!isContained()) | ||
{ | ||
return gtGetRegMask(); | ||
return isUsedFromReg() ? gtGetRegMask() : RBM_NONE; | ||
} | ||
|
||
regMaskTP mask = 0; | ||
|
@@ -18720,6 +18720,41 @@ bool GenTree::IsArrayAddr(GenTreeArrAddr** pArrAddr) | |
return false; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
// CanSetZeroFlag: Returns true if this is an arithmetic operation that can | ||
// set the "zero flag" as part of its operation. | ||
// | ||
// Return Value: | ||
// True if so. | ||
// | ||
// Remarks: | ||
// For example, for EQ (AND x y) 0, both xarch and arm64 can emit instructions | ||
// that directly set the flags after the 'AND' and thus no comparison is needed. | ||
// | ||
bool GenTree::CanSetZeroFlag() | ||
{ | ||
#if defined(TARGET_XARCH) | ||
if (OperIs(GT_AND, GT_OR, GT_XOR, GT_ADD, GT_SUB, GT_NEG)) | ||
{ | ||
return true; | ||
} | ||
|
||
#ifdef FEATURE_HW_INTRINSICS | ||
if (OperIs(GT_HWINTRINSIC) && emitter::DoesWriteZeroFlag(HWIntrinsicInfo::lookupIns(AsHWIntrinsic()))) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth noting that this isn't necessarily "correct".
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. I added another check to the heuristic in if-conversion for the rest of the hw intrinsic cases that this PR doesn't handle yet, so that we don't regress those. |
||
{ | ||
return true; | ||
} | ||
#endif | ||
#elif defined(TARGET_ARM64) | ||
if (OperIs(GT_AND, GT_ADD, GT_SUB)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this going to be problematic on Arm64 since we have two different instructions for each of these? That is one that sets the flags ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I think codegen just handles this via |
||
{ | ||
return true; | ||
} | ||
#endif | ||
|
||
return false; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
// Create: Create or retrieve a field sequence for the given field handle. | ||
// | ||
|
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 is missing many different cases, particularly those that leave
ZF
in an undefined state such asimul
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 is just factoring the code that was already there. I can add a TODO if you want.
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 was factored out of
Lowering::OptimizeConstCompare
)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, I see. I wonder if its going to cause any problematic behavior if we're depending on this to be accurate.
I could easily see someone checking
!CanSetZeroFlag()
and then assuming the zero flag can't be overrwritten. Inversely I could see someone checkingCanSetZeroFlag()
and assuming that it will write some 0/1 value and that it is strictly tied to the computed result.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.
Hmm, I can rename this. The specific meaning I was intending was that this is a node that supports setting the zero flag if
GTF_SET_FLAGS
is set. MaybeSupportsSettingZeroFlag()
is 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.
Not sure
Supports
fixes the main concern around people thinking!Supports
means "does not support" (and therefore will not modify zf).I don't have a good suggestion for a different name, however.
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 might just be something we'll have to cover with docs and code review.
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 renamed it to
SupportsSettingZeroFlag
and added some more docs on it