Skip to content
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] ARM64 - Optimize x < 0 and x >= 0 #83176

Merged
merged 20 commits into from
Mar 16, 2023
Merged
15 changes: 13 additions & 2 deletions src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4532,7 +4532,18 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
if (op2->isContainedIntOrIImmed())
{
GenTreeIntConCommon* intConst = op2->AsIntConCommon();
emit->emitIns_R_I(ins, cmpSize, op1->GetRegNum(), intConst->IconValue());

regNumber op1Reg = op1->GetRegNum();

if (compiler->opts.OptimizationEnabled() && (ins == INS_cmp) && (targetReg != REG_NA) &&
tree->OperIs(GT_LT) && intConst->IsIntegralConst(0) && ((cmpSize == EA_4BYTE) || (cmpSize == EA_8BYTE)))
{
emit->emitIns_R_R_I(INS_lsr, cmpSize, targetReg, op1Reg, (int)cmpSize * 8 - 1);
genProduceReg(tree);
return;
}

emit->emitIns_R_I(ins, cmpSize, op1Reg, intConst->IconValue());
}
else
{
Expand Down Expand Up @@ -4725,7 +4736,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOp* tree)
{
ssize_t compareImm = op2->AsIntCon()->IconValue();

assert(isPow2(compareImm));
assert(isPow2(((size_t)compareImm)));

instruction ins = (tree->gtFlags & GTF_JCMP_EQ) ? INS_tbz : INS_tbnz;
int imm = genLog2((size_t)compareImm);
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3481,8 +3481,7 @@ GenTree* Compiler::gtReverseCond(GenTree* tree)
else if (tree->OperIs(GT_JCMP))
{
// Flip the GTF_JCMP_EQ
//
// This causes switching
// On ARM64, this causes switching
// cbz <=> cbnz
// tbz <=> tbnz
tree->gtFlags ^= GTF_JCMP_EQ;
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3379,6 +3379,14 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
flags = cond->OperIs(GT_EQ) ? GTF_JCMP_EQ : GTF_EMPTY;
useJCMP = true;
}
else if (cond->OperIs(GT_LT, GT_GE) && !cond->IsUnsigned() && relopOp2->IsIntegralConst(0))
{
// Codegen will use tbnz or tbz in codegen which do not affect the flag register
flags = GTF_JCMP_TST | (cond->OperIs(GT_LT) ? GTF_EMPTY : GTF_JCMP_EQ);
useJCMP = true;
relopOp2->AsIntConCommon()->SetIntegralValue(
(static_cast<INT64>(1) << (8 * genTypeSize(genActualType(relopOp1)) - 1)));
}
else if (cond->OperIs(GT_TEST_EQ, GT_TEST_NE) && isPow2(relopOp2->AsIntCon()->IconValue()))
{
// Codegen will use tbz or tbnz in codegen which do not affect the flag register
Expand Down