Skip to content

Commit b72b7f0

Browse files
authored
[arm64] JIT: X % 2 == 0 -> X & 1 == 0 (#62399)
1 parent 2cbc071 commit b72b7f0

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

src/coreclr/jit/morph.cpp

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11453,6 +11453,37 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1145311453
{
1145411454
return fgMorphTree(optimizedTree);
1145511455
}
11456+
11457+
// Pattern-matching optimization:
11458+
// (a % c) ==/!= 0
11459+
// for power-of-2 constant `c`
11460+
// =>
11461+
// a & (c - 1) ==/!= 0
11462+
// For integer `a`, even if negative.
11463+
if (opts.OptimizationEnabled() && !optValnumCSE_phase)
11464+
{
11465+
assert(tree->OperIs(GT_EQ, GT_NE));
11466+
if (op1->OperIs(GT_MOD) && varTypeIsIntegral(op1) && op2->IsIntegralConst(0))
11467+
{
11468+
GenTree* op1op2 = op1->AsOp()->gtOp2;
11469+
if (op1op2->IsCnsIntOrI())
11470+
{
11471+
const ssize_t modValue = op1op2->AsIntCon()->IconValue();
11472+
if (isPow2(modValue))
11473+
{
11474+
JITDUMP("\nTransforming:\n");
11475+
DISPTREE(tree);
11476+
11477+
op1->SetOper(GT_AND); // Change % => &
11478+
op1op2->AsIntConCommon()->SetIconValue(modValue - 1); // Change c => c - 1
11479+
fgUpdateConstTreeValueNumber(op1op2);
11480+
11481+
JITDUMP("\ninto:\n");
11482+
DISPTREE(tree);
11483+
}
11484+
}
11485+
}
11486+
}
1145611487
}
1145711488

1145811489
FALLTHROUGH;
@@ -13361,30 +13392,6 @@ GenTree* Compiler::fgOptimizeEqualityComparisonWithConst(GenTreeOp* cmp)
1336113392
GenTree* op1 = cmp->gtGetOp1();
1336213393
GenTreeIntConCommon* op2 = cmp->gtGetOp2()->AsIntConCommon();
1336313394

13364-
// Pattern-matching optimization:
13365-
// (a % c) ==/!= 0
13366-
// for power-of-2 constant `c`
13367-
// =>
13368-
// a & (c - 1) ==/!= 0
13369-
// For integer `a`, even if negative.
13370-
if (opts.OptimizationEnabled())
13371-
{
13372-
if (op1->OperIs(GT_MOD) && varTypeIsIntegral(op1) && op2->IsIntegralConst(0))
13373-
{
13374-
GenTree* op1op2 = op1->AsOp()->gtOp2;
13375-
if (op1op2->IsCnsIntOrI())
13376-
{
13377-
ssize_t modValue = op1op2->AsIntCon()->IconValue();
13378-
if (isPow2(modValue))
13379-
{
13380-
op1->SetOper(GT_AND); // Change % => &
13381-
op1op2->AsIntConCommon()->SetIconValue(modValue - 1); // Change c => c - 1
13382-
fgUpdateConstTreeValueNumber(op1op2);
13383-
}
13384-
}
13385-
}
13386-
}
13387-
1338813395
// Check for "(expr +/- icon1) ==/!= (non-zero-icon2)".
1338913396
if (op2->IsCnsIntOrI() && (op2->IconValue() != 0))
1339013397
{

0 commit comments

Comments
 (0)