Skip to content

Commit

Permalink
ARM64: Avoid LEA for volatile IND (#64354)
Browse files Browse the repository at this point in the history
Co-authored-by: Kunal Pathak <Kunal.Pathak@microsoft.com>
  • Loading branch information
EgorBo and kunalspathak authored Jan 27, 2022
1 parent bd84729 commit 5409d71
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
25 changes: 18 additions & 7 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4891,20 +4891,29 @@ bool Lowering::AreSourcesPossiblyModifiedLocals(GenTree* addr, GenTree* base, Ge
// addressing mode and transform them to a GT_LEA
//
// Arguments:
// use - the use of the address we want to transform
// addr - the use of the address we want to transform
// isContainable - true if this addressing mode can be contained
// targetType - on arm we can use "scale" only for appropriate target type
// parent - the node that consumes the given addr (most likely it's an IND)
//
// Returns:
// true if the address node was changed to a LEA, false otherwise.
//
bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType)
bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent)
{
if (!addr->OperIs(GT_ADD) || addr->gtOverflow())
{
return false;
}

#ifdef TARGET_ARM64
if (parent->OperIsIndir() && parent->AsIndir()->IsVolatile())
{
// For Arm64 we avoid using LEA for volatile INDs
// because we won't be able to use ldar/star
return false;
}
#endif

GenTree* base = nullptr;
GenTree* index = nullptr;
unsigned scale = 0;
Expand All @@ -4920,6 +4929,8 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, var_types ta
&scale, // scaling
&offset); // displacement

var_types targetType = parent->OperIsIndir() ? parent->TypeGet() : TYP_UNDEF;

#ifdef TARGET_ARMARCH
// Multiplier should be a "natural-scale" power of two number which is equal to target's width.
//
Expand Down Expand Up @@ -5109,7 +5120,7 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
GenTree* parent = use.User();
if (!parent->OperIsIndir() && !parent->OperIs(GT_ADD))
{
TryCreateAddrMode(node, false);
TryCreateAddrMode(node, false, parent);
}
}
#endif // !TARGET_ARMARCH
Expand Down Expand Up @@ -6778,7 +6789,7 @@ void Lowering::ContainCheckBitCast(GenTree* node)
void Lowering::LowerStoreIndirCommon(GenTreeStoreInd* ind)
{
assert(ind->TypeGet() != TYP_STRUCT);
TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), true, ind);
if (!comp->codeGen->gcInfo.gcIsWriteBarrierStoreIndNode(ind))
{
if (varTypeIsFloating(ind) && ind->Data()->IsCnsFltOrDbl())
Expand Down Expand Up @@ -6846,7 +6857,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// TODO-Cleanup: We're passing isContainable = true but ContainCheckIndir rejects
// address containment in some cases so we end up creating trivial (reg + offfset)
// or (reg + reg) LEAs that are not necessary.
TryCreateAddrMode(ind->Addr(), true, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), true, ind);
ContainCheckIndir(ind);

if (ind->OperIs(GT_NULLCHECK) || ind->IsUnusedValue())
Expand All @@ -6859,7 +6870,7 @@ void Lowering::LowerIndir(GenTreeIndir* ind)
// If the `ADDR` node under `STORE_OBJ(dstAddr, IND(struct(ADDR))`
// is a complex one it could benefit from an `LEA` that is not contained.
const bool isContainable = false;
TryCreateAddrMode(ind->Addr(), isContainable, ind->TypeGet());
TryCreateAddrMode(ind->Addr(), isContainable, ind);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class Lowering final : public Phase
void ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenTree* addr);
void LowerPutArgStk(GenTreePutArgStk* tree);

bool TryCreateAddrMode(GenTree* addr, bool isContainable, var_types targetType = TYP_UNDEF);
bool TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* parent);

bool TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode);

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/lowerxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp)
//
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
TryCreateAddrMode(blkNode->Addr(), false);
TryCreateAddrMode(blkNode->Addr(), false, blkNode);

GenTree* dstAddr = blkNode->Addr();
GenTree* src = blkNode->Data();
Expand Down Expand Up @@ -408,7 +408,7 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT
return;
}

if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true))
if (!addr->OperIsAddrMode() && !TryCreateAddrMode(addr, true, blkNode))
{
return;
}
Expand Down Expand Up @@ -5799,7 +5799,7 @@ bool Lowering::TryGetContainableHWIntrinsicOp(GenTreeHWIntrinsic* containingNode
void Lowering::ContainCheckHWIntrinsicAddr(GenTreeHWIntrinsic* node, GenTree* addr)
{
assert((addr->TypeGet() == TYP_I_IMPL) || (addr->TypeGet() == TYP_BYREF));
TryCreateAddrMode(addr, true);
TryCreateAddrMode(addr, true, node);
if ((addr->OperIs(GT_CLS_VAR_ADDR, GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA) ||
(addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))) &&
IsSafeToContainMem(node, addr))
Expand Down

0 comments on commit 5409d71

Please sign in to comment.