Skip to content

Commit

Permalink
[JIT] ARM64 - Combine cmp and shift ops into a single cmp op (#84605
Browse files Browse the repository at this point in the history
)

* Combine compare and shift ops into a single compare op

* Fix comment

* Expanding IsContainableBinaryOp.

* Remove commented code

* Added more cases

* Update codegenarm64.cpp

* Feedback

* Feedback
  • Loading branch information
TIHan committed Apr 17, 2023
1 parent 048467b commit 35ef766
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

#if defined(TARGET_ARM64)
static insCond JumpKindToInsCond(emitJumpKind condition);
static insOpts ShiftOpToInsOpts(genTreeOps op);
#elif defined(TARGET_XARCH)
static instruction JumpKindToCmov(emitJumpKind condition);
#endif
Expand Down
60 changes: 35 additions & 25 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2626,31 +2626,7 @@ void CodeGen::genCodeForBinary(GenTreeOp* tree)
}
}

switch (op2->gtOper)
{
case GT_LSH:
{
opt = INS_OPTS_LSL;
break;
}

case GT_RSH:
{
opt = INS_OPTS_ASR;
break;
}

case GT_RSZ:
{
opt = INS_OPTS_LSR;
break;
}

default:
{
unreached();
}
}
opt = ShiftOpToInsOpts(op2->gtOper);

emit->emitIns_R_R_R_I(ins, emitActualTypeSize(tree), targetReg, a->GetRegNum(), b->GetRegNum(),
c->AsIntConCommon()->IconValue(), opt);
Expand Down Expand Up @@ -4546,6 +4522,15 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)

emit->emitIns_R_I(ins, cmpSize, op1Reg, intConst->IconValue());
}
else if (op2->isContained())
{
assert(op2->OperIs(GT_LSH, GT_RSH, GT_RSZ));
assert(op2->gtGetOp2()->IsCnsIntOrI());
assert(op2->gtGetOp2()->isContained());

emit->emitIns_R_R_I(ins, cmpSize, op1->GetRegNum(), op2->gtGetOp1()->GetRegNum(),
op2->gtGetOp2()->AsIntConCommon()->IntegralValue(), ShiftOpToInsOpts(op2->gtOper));
}
else
{
emit->emitIns_R_R(ins, cmpSize, op1->GetRegNum(), op2->GetRegNum());
Expand Down Expand Up @@ -10389,4 +10374,29 @@ insCond CodeGen::JumpKindToInsCond(emitJumpKind condition)
}
}

//------------------------------------------------------------------------
// ShiftOpToInsOpts: Convert a shift-op to a insOpts.
//
// Arguments:
// shiftOp - the shift-op
//
insOpts CodeGen::ShiftOpToInsOpts(genTreeOps shiftOp)
{
switch (shiftOp)
{
case GT_LSH:
return INS_OPTS_LSL;

case GT_RSH:
return INS_OPTS_ASR;

case GT_RSZ:
return INS_OPTS_LSR;

default:
NO_WAY("expected a shift-op");
return INS_OPTS_NONE;
}
}

#endif // TARGET_ARM64
34 changes: 32 additions & 2 deletions src/coreclr/jit/lowerarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ bool Lowering::IsContainableBinaryOp(GenTree* parentNode, GenTree* childNode) co
return false;
}

if (parentNode->OperIs(GT_CMP, GT_OR, GT_XOR))
if (parentNode->OperIs(GT_CMP, GT_OR, GT_XOR) || parentNode->OperIsCompare())
{
if (IsInvariantInRange(childNode, parentNode))
{
Expand Down Expand Up @@ -2268,7 +2268,37 @@ void Lowering::ContainCheckCast(GenTreeCast* node)
//
void Lowering::ContainCheckCompare(GenTreeOp* cmp)
{
CheckImmedAndMakeContained(cmp, cmp->gtOp2);
GenTree* op1 = cmp->gtGetOp1();
GenTree* op2 = cmp->gtGetOp2();

if (CheckImmedAndMakeContained(cmp, op2))
return;

if (cmp->OperIsCompare() && CheckImmedAndMakeContained(cmp, op1))
{
std::swap(cmp->gtOp1, cmp->gtOp2);
cmp->ChangeOper(cmp->SwapRelop(cmp->gtOper));
return;
}

#ifdef TARGET_ARM64
if (comp->opts.OptimizationEnabled() && cmp->OperIsCompare())
{
if (IsContainableBinaryOp(cmp, op2))
{
MakeSrcContained(cmp, op2);
return;
}

if (IsContainableBinaryOp(cmp, op1))
{
MakeSrcContained(cmp, op1);
std::swap(cmp->gtOp1, cmp->gtOp2);
cmp->ChangeOper(cmp->SwapRelop(cmp->gtOper));
return;
}
}
#endif
}

#ifdef TARGET_ARM64
Expand Down

0 comments on commit 35ef766

Please sign in to comment.