Skip to content

Commit cf89ec4

Browse files
authored
JIT: Optimize bit-wise AND with a constant mask in combination with a left shift in a compare (#111979)
This optmizes the generated code when having a pattern like '(SomeConstant & (1 << value)) != 0' which was previously only optimized for '(variable & (1 << value)) != 0'. Fix #111554
1 parent dea928c commit cf89ec4

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/coreclr/jit/lower.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4352,24 +4352,32 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp)
43524352
if (cmp->OperIs(GT_TEST_EQ, GT_TEST_NE))
43534353
{
43544354
//
4355-
// Transform TEST_EQ|NE(x, LSH(1, y)) into BT(x, y) when possible. Using BT
4355+
// Transform TEST_EQ|NE(x, LSH(1, y)) or TEST_EQ|NE(LSH(1, y), x) into BT(x, y) when possible. Using BT
43564356
// results in smaller and faster code. It also doesn't have special register
43574357
// requirements, unlike LSH that requires the shift count to be in ECX.
43584358
// Note that BT has the same behavior as LSH when the bit index exceeds the
43594359
// operand bit size - it uses (bit_index MOD bit_size).
43604360
//
43614361

4362-
GenTree* lsh = cmp->gtGetOp2();
4362+
GenTree* lsh = cmp->AsOp()->gtOp1;
4363+
GenTree* op = cmp->AsOp()->gtOp2;
43634364

4364-
if (lsh->OperIs(GT_LSH) && varTypeIsIntOrI(lsh->TypeGet()) && lsh->gtGetOp1()->IsIntegralConst(1))
4365+
if (!lsh->OperIs(GT_LSH))
4366+
{
4367+
std::swap(lsh, op);
4368+
}
4369+
4370+
if (lsh->OperIs(GT_LSH) && varTypeIsIntOrI(lsh) && lsh->gtGetOp1()->IsIntegralConst(1))
43654371
{
43664372
cmp->SetOper(cmp->OperIs(GT_TEST_EQ) ? GT_BITTEST_EQ : GT_BITTEST_NE);
4367-
cmp->AsOp()->gtOp2 = lsh->gtGetOp2();
4368-
cmp->gtGetOp2()->ClearContained();
43694373

43704374
BlockRange().Remove(lsh->gtGetOp1());
43714375
BlockRange().Remove(lsh);
43724376

4377+
cmp->AsOp()->gtOp1 = op;
4378+
cmp->AsOp()->gtOp2 = lsh->gtGetOp2();
4379+
cmp->gtGetOp2()->ClearContained();
4380+
43734381
return cmp->gtNext;
43744382
}
43754383
}

0 commit comments

Comments
 (0)