-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[JIT] ARM64 - Fix Assertion failed 'node->OperIs(GT_DIV, GT_UDIV, GT_MOD)' during 'Lowering nodeinfo' #85664
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
Changes from 2 commits
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 |
---|---|---|
|
@@ -6596,14 +6596,16 @@ bool Lowering::LowerUnsignedDivOrMod(GenTreeOp* divMod) | |
// | ||
// Arguments: | ||
// node - pointer to the DIV or MOD node | ||
// nextNode - out parameter for the next node in the transformed node sequence that needs to be lowered | ||
// | ||
// Returns: | ||
// nullptr if no transformation is done, or the next node in the transformed node sequence that | ||
// needs to be lowered. | ||
// false if no transformation is done, true if a transformation is done | ||
// | ||
GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | ||
bool Lowering::TryLowerConstIntDivOrMod(GenTree* node, GenTree** nextNode) | ||
{ | ||
assert((node->OperGet() == GT_DIV) || (node->OperGet() == GT_MOD)); | ||
assert(nextNode != nullptr); | ||
|
||
GenTree* divMod = node; | ||
GenTree* dividend = divMod->gtGetOp1(); | ||
GenTree* divisor = divMod->gtGetOp2(); | ||
|
@@ -6618,22 +6620,23 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
if (divMod->OperIs(GT_MOD) && divisor->IsIntegralConstPow2()) | ||
{ | ||
LowerModPow2(node); | ||
return node->gtNext; | ||
*nextNode = node->gtNext; | ||
return true; | ||
} | ||
assert(node->OperGet() != GT_MOD); | ||
#endif // TARGET_ARM64 | ||
|
||
if (!divisor->IsCnsIntOrI()) | ||
{ | ||
return nullptr; // no transformations to make | ||
return false; // no transformations to make | ||
} | ||
|
||
if (dividend->IsCnsIntOrI()) | ||
{ | ||
// We shouldn't see a divmod with constant operands here but if we do then it's likely | ||
// because optimizations are disabled or it's a case that's supposed to throw an exception. | ||
// Don't optimize this. | ||
return nullptr; | ||
return false; | ||
} | ||
|
||
ssize_t divisorValue = divisor->AsIntCon()->IconValue(); | ||
|
@@ -6649,7 +6652,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
// case so optimizing this case would break C# code. | ||
|
||
// A runtime check could be used to handle this case but it's probably too rare to matter. | ||
return nullptr; | ||
return false; | ||
} | ||
|
||
bool isDiv = divMod->OperGet() == GT_DIV; | ||
|
@@ -6661,7 +6664,8 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
// If the divisor is the minimum representable integer value then we can use a compare, | ||
// the result is 1 iff the dividend equals divisor. | ||
divMod->SetOper(GT_EQ); | ||
return node; | ||
*nextNode = node; | ||
return true; | ||
} | ||
} | ||
|
||
|
@@ -6672,7 +6676,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
{ | ||
if (comp->opts.MinOpts()) | ||
{ | ||
return nullptr; | ||
return false; | ||
} | ||
|
||
#if defined(TARGET_XARCH) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) | ||
|
@@ -6774,13 +6778,14 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
divMod->AsOp()->gtOp2 = mul; | ||
} | ||
|
||
return mulhi; | ||
*nextNode = mulhi; | ||
return true; | ||
#elif defined(TARGET_ARM) | ||
// Currently there's no GT_MULHI for ARM32 | ||
return nullptr; | ||
return false; | ||
#elif defined(TARGET_RISCV64) | ||
NYI_RISCV64("-----unimplemented on RISCV64 yet----"); | ||
return nullptr; | ||
return false; | ||
#else | ||
#error Unsupported or unset target architecture | ||
#endif | ||
|
@@ -6790,7 +6795,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
LIR::Use use; | ||
if (!BlockRange().TryGetUse(node, &use)) | ||
{ | ||
return nullptr; | ||
return false; | ||
} | ||
|
||
// We need to use the dividend node multiple times so its value needs to be | ||
|
@@ -6856,7 +6861,8 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
// replace the original divmod node with the new divmod tree | ||
use.ReplaceWith(newDivMod); | ||
|
||
return newDivMod->gtNext; | ||
*nextNode = newDivMod->gtNext; | ||
return true; | ||
} | ||
//------------------------------------------------------------------------ | ||
// LowerSignedDivOrMod: transform integer GT_DIV/GT_MOD nodes with a power of 2 | ||
|
@@ -6871,20 +6877,18 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) | |
GenTree* Lowering::LowerSignedDivOrMod(GenTree* node) | ||
{ | ||
assert((node->OperGet() == GT_DIV) || (node->OperGet() == GT_MOD)); | ||
GenTree* next = node->gtNext; | ||
|
||
if (varTypeIsIntegral(node->TypeGet())) | ||
{ | ||
// LowerConstIntDivOrMod will return nullptr if it doesn't transform the node. | ||
GenTree* newNode = LowerConstIntDivOrMod(node); | ||
if (newNode != nullptr) | ||
GenTree* nextNode = nullptr; | ||
if (TryLowerConstIntDivOrMod(node, &nextNode)) | ||
{ | ||
return newNode; | ||
return nextNode; | ||
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.
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. The issue is that But, we could add an assert |
||
} | ||
} | ||
ContainCheckDivOrMod(node->AsOp()); | ||
|
||
return next; | ||
return node->gtNext; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
|
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.
Should this be initialized
*nextNode = nullptr
which should be the case if this method returnsfalse
?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.
We have a similar
TryLowerAndNegativeOne
with an out parameternextNode
and we do not set that tonullptr
or when we returnfalse
.