Skip to content

Commit

Permalink
Added IsContainableMemoryOpSize (#79126)
Browse files Browse the repository at this point in the history
  • Loading branch information
TIHan authored Dec 7, 2022
1 parent 83b7b53 commit b858484
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 19 deletions.
14 changes: 3 additions & 11 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2939,17 +2939,9 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp)

if (castOp->OperIs(GT_OR, GT_XOR, GT_AND))
{
GenTree* op1 = castOp->gtGetOp1();
if ((op1 != nullptr) && !op1->IsCnsIntOrI())
{
op1->ClearContained();
}

GenTree* op2 = castOp->gtGetOp2();
if ((op2 != nullptr) && !op2->IsCnsIntOrI())
{
op2->ClearContained();
}
castOp->gtGetOp1()->ClearContained();
castOp->gtGetOp2()->ClearContained();
ContainCheckBinary(castOp->AsOp());
}

cmp->AsOp()->gtOp1 = castOp;
Expand Down
31 changes: 26 additions & 5 deletions src/coreclr/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,8 @@ class Lowering final : public Phase
GenTree* const op1 = tree->gtGetOp1();
GenTree* const op2 = tree->gtGetOp2();

const unsigned operatorSize = genTypeSize(tree->TypeGet());

const bool op1Legal =
isSafeToMarkOp1 && tree->OperIsCommutative() && (operatorSize == genTypeSize(op1->TypeGet()));
const bool op2Legal = isSafeToMarkOp2 && (operatorSize == genTypeSize(op2->TypeGet()));
const bool op1Legal = isSafeToMarkOp1 && tree->OperIsCommutative() && IsContainableMemoryOpSize(tree, op1);
const bool op2Legal = isSafeToMarkOp2 && IsContainableMemoryOpSize(tree, op2);

GenTree* regOptionalOperand = nullptr;

Expand Down Expand Up @@ -452,6 +449,30 @@ class Lowering final : public Phase
return m_lsra->isContainableMemoryOp(node);
}

// Return true if 'childNode' is a containable memory op by its size relative to the 'parentNode'.
// Currently very conservative.
bool IsContainableMemoryOpSize(GenTree* parentNode, GenTree* childNode) const
{
if (parentNode->OperIsBinary())
{
const unsigned operatorSize = genTypeSize(parentNode->TypeGet());

#ifdef TARGET_XARCH

// Conservative - only do this for AND, OR, XOR.
if (parentNode->OperIs(GT_AND, GT_OR, GT_XOR))
{
return genTypeSize(childNode->TypeGet()) >= operatorSize;
}

#endif // TARGET_XARCH

return genTypeSize(childNode->TypeGet()) == operatorSize;
}

return false;
}

#ifdef TARGET_ARM64
bool IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) const;
#endif // TARGET_ARM64
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/jit/lowerxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5809,8 +5809,7 @@ void Lowering::ContainCheckBinary(GenTreeOp* node)
binOpInRMW = IsBinOpInRMWStoreInd(node);
if (!binOpInRMW)
{
const unsigned operatorSize = genTypeSize(node->TypeGet());
if ((genTypeSize(op2->TypeGet()) == operatorSize) && IsContainableMemoryOp(op2))
if (IsContainableMemoryOpSize(node, op2) && IsContainableMemoryOp(op2))
{
isSafeToContainOp2 = IsSafeToContainMem(node, op2);
if (isSafeToContainOp2)
Expand All @@ -5829,7 +5828,7 @@ void Lowering::ContainCheckBinary(GenTreeOp* node)
directlyEncodable = true;
operand = op1;
}
else if ((genTypeSize(op1->TypeGet()) == operatorSize) && IsContainableMemoryOp(op1))
else if (IsContainableMemoryOpSize(node, op1) && IsContainableMemoryOp(op1))
{
isSafeToContainOp1 = IsSafeToContainMem(node, op1);
if (isSafeToContainOp1)
Expand Down

0 comments on commit b858484

Please sign in to comment.