Skip to content

Commit 3b61c12

Browse files
Solve most of the regressions
In morph, when narrowing the AND operand, only insert casts if necessary - prefer to use "optNarrowTree". Otherwise we end up with redundant register shuffling.
1 parent d2dd580 commit 3b61c12

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

src/coreclr/jit/morph.cpp

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13789,44 +13789,54 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
1378913789

1379013790
noway_assert(op1->TypeGet() == TYP_LONG && op1->OperGet() == GT_AND);
1379113791

13792-
/* Is the result of the mask effectively an INT ? */
13793-
13794-
GenTree* andMask;
13795-
andMask = op1->AsOp()->gtOp2;
13796-
if (andMask->gtOper != GT_CNS_NATIVELONG)
13797-
{
13798-
goto COMPARE;
13799-
}
13800-
if ((andMask->AsIntConCommon()->LngValue() >> 32) != 0)
13792+
// The transform below cannot preserve VNs.
13793+
if (fgGlobalMorph)
1380113794
{
13802-
goto COMPARE;
13803-
}
13795+
// Is the result of the mask effectively an INT ?
1380413796

13805-
/* Now we know that we can cast AsOp()->gtOp1 of AND to int */
13797+
GenTree* andMask = op1->AsOp()->gtOp2;
13798+
13799+
if (andMask->gtOper != GT_CNS_NATIVELONG)
13800+
{
13801+
goto COMPARE;
13802+
}
13803+
if ((andMask->AsIntConCommon()->LngValue() >> 32) != 0)
13804+
{
13805+
goto COMPARE;
13806+
}
1380613807

13807-
op1->AsOp()->gtOp1 = gtNewCastNode(TYP_INT, op1->AsOp()->gtOp1, false, TYP_INT);
13808+
// Now we narrow AsOp()->gtOp1 of AND to int.
13809+
if (optNarrowTree(op1->AsOp()->gtGetOp1(), TYP_LONG, TYP_INT, ValueNumPair(), false))
13810+
{
13811+
optNarrowTree(op1->AsOp()->gtGetOp1(), TYP_LONG, TYP_INT, ValueNumPair(), true);
13812+
}
13813+
else
13814+
{
13815+
op1->AsOp()->gtOp1 = gtNewCastNode(TYP_INT, op1->AsOp()->gtGetOp1(), false, TYP_INT);
13816+
}
1380813817

13809-
/* now replace the mask node (AsOp()->gtOp2 of AND node) */
13818+
// now replace the mask node (AsOp()->gtOp2 of AND node).
1381013819

13811-
noway_assert(andMask == op1->AsOp()->gtOp2);
13820+
noway_assert(andMask == op1->AsOp()->gtOp2);
1381213821

13813-
ival1 = (int)andMask->AsIntConCommon()->LngValue();
13814-
andMask->SetOper(GT_CNS_INT);
13815-
andMask->gtType = TYP_INT;
13816-
andMask->AsIntCon()->gtIconVal = ival1;
13822+
ival1 = (int)andMask->AsIntConCommon()->LngValue();
13823+
andMask->SetOper(GT_CNS_INT);
13824+
andMask->gtType = TYP_INT;
13825+
andMask->AsIntCon()->gtIconVal = ival1;
1381713826

13818-
/* now change the type of the AND node */
13827+
// now change the type of the AND node.
1381913828

13820-
op1->gtType = TYP_INT;
13829+
op1->gtType = TYP_INT;
1382113830

13822-
/* finally we replace the comparand */
13831+
// finally we replace the comparand.
1382313832

13824-
ival2 = (int)cns2->AsIntConCommon()->LngValue();
13825-
cns2->SetOper(GT_CNS_INT);
13826-
cns2->gtType = TYP_INT;
13833+
ival2 = (int)cns2->AsIntConCommon()->LngValue();
13834+
cns2->SetOper(GT_CNS_INT);
13835+
cns2->gtType = TYP_INT;
1382713836

13828-
noway_assert(cns2 == op2);
13829-
cns2->AsIntCon()->gtIconVal = ival2;
13837+
noway_assert(cns2 == op2);
13838+
cns2->AsIntCon()->gtIconVal = ival2;
13839+
}
1383013840

1383113841
goto COMPARE;
1383213842

0 commit comments

Comments
 (0)