Skip to content

Commit c0bad3c

Browse files
authored
Improve narrowing of GT_AND nodes. (dotnet#18916)
This is a follow-up to to dotnet#18816 which resulted in a 6 byte regression in one of the desktop SuperPMI methods. This change removes that regression and adds a number of improved diffs. If we are narrowing GT_AND to an unsigned type and one of the operands can be narrowed into that type, the result of the GT_AND will also fit into that type and can be narrowed. The same is true if one of the operands is an int const and can be narrowed into 'dsst'. The change also ensures that we don't call optNarrowTree(false) more than once on each of the GT_AND operands.
1 parent d9641a0 commit c0bad3c

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

src/jit/optimizer.cpp

+52-11
Original file line numberDiff line numberDiff line change
@@ -5711,34 +5711,76 @@ bool Compiler::optNarrowTree(GenTree* tree, var_types srct, var_types dstt, Valu
57115711
switch (tree->gtOper)
57125712
{
57135713
case GT_AND:
5714+
noway_assert(genActualType(tree->gtType) == genActualType(op1->gtType));
57145715
noway_assert(genActualType(tree->gtType) == genActualType(op2->gtType));
57155716

5716-
// Is op2 a small constant than can be narrowed into dstt?
5717-
// if so the result of the GT_AND will also fit into 'dstt' and can be narrowed
5718-
if ((op2->gtOper == GT_CNS_INT) && optNarrowTree(op2, srct, dstt, NoVNPair, false))
5717+
GenTree* opToNarrow;
5718+
opToNarrow = nullptr;
5719+
GenTree** otherOpPtr;
5720+
otherOpPtr = nullptr;
5721+
bool canNotNarrowOperand;
5722+
canNotNarrowOperand = false;
5723+
5724+
// If 'dstt' is unsigned and one of the operands can be narrowed into 'dsst',
5725+
// the result of the GT_AND will also fit into 'dstt' and can be narrowed.
5726+
// The same is true if one of the operands is an int const and can be narrowed into 'dsst'.
5727+
if (!gtIsActiveCSE_Candidate(op2) && ((op2->gtOper == GT_CNS_INT) || varTypeIsUnsigned(dstt)))
57195728
{
5720-
// We will change the type of the tree and narrow op2
5729+
if (optNarrowTree(op2, srct, dstt, NoVNPair, false))
5730+
{
5731+
opToNarrow = op2;
5732+
otherOpPtr = &tree->gtOp.gtOp1;
5733+
}
5734+
else
5735+
{
5736+
canNotNarrowOperand = true;
5737+
}
5738+
}
5739+
5740+
if ((opToNarrow == nullptr) && !gtIsActiveCSE_Candidate(op1) &&
5741+
((op1->gtOper == GT_CNS_INT) || varTypeIsUnsigned(dstt)))
5742+
{
5743+
if (optNarrowTree(op1, srct, dstt, NoVNPair, false))
5744+
{
5745+
opToNarrow = op1;
5746+
otherOpPtr = &tree->gtOp.gtOp2;
5747+
}
5748+
else
5749+
{
5750+
canNotNarrowOperand = true;
5751+
}
5752+
}
5753+
5754+
if (opToNarrow != nullptr)
5755+
{
5756+
// We will change the type of the tree and narrow opToNarrow
57215757
//
57225758
if (doit)
57235759
{
57245760
tree->gtType = genActualType(dstt);
57255761
tree->SetVNs(vnpNarrow);
57265762

5727-
optNarrowTree(op2, srct, dstt, NoVNPair, true);
5728-
// We may also need to cast away the upper bits of op1
5763+
optNarrowTree(opToNarrow, srct, dstt, NoVNPair, true);
5764+
// We may also need to cast away the upper bits of *otherOpPtr
57295765
if (srcSize == 8)
57305766
{
57315767
assert(tree->gtType == TYP_INT);
5732-
op1 = gtNewCastNode(TYP_INT, op1, false, TYP_INT);
5768+
GenTree* castOp = gtNewCastNode(TYP_INT, op1, false, TYP_INT);
57335769
#ifdef DEBUG
5734-
op1->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
5770+
castOp->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
57355771
#endif
5736-
tree->gtOp.gtOp1 = op1;
5772+
*otherOpPtr = castOp;
57375773
}
57385774
}
57395775
return true;
57405776
}
57415777

5778+
if (canNotNarrowOperand)
5779+
{
5780+
noway_assert(doit == false);
5781+
return false;
5782+
}
5783+
57425784
goto COMMON_BINOP;
57435785

57445786
case GT_ADD:
@@ -5753,10 +5795,9 @@ bool Compiler::optNarrowTree(GenTree* tree, var_types srct, var_types dstt, Valu
57535795

57545796
case GT_OR:
57555797
case GT_XOR:
5756-
COMMON_BINOP:
57575798
noway_assert(genActualType(tree->gtType) == genActualType(op1->gtType));
57585799
noway_assert(genActualType(tree->gtType) == genActualType(op2->gtType));
5759-
5800+
COMMON_BINOP:
57605801
if (gtIsActiveCSE_Candidate(op1) || gtIsActiveCSE_Candidate(op2) ||
57615802
!optNarrowTree(op1, srct, dstt, NoVNPair, doit) || !optNarrowTree(op2, srct, dstt, NoVNPair, doit))
57625803
{

0 commit comments

Comments
 (0)