Skip to content

Commit 960870a

Browse files
committed
Allow gtFoldExprSpecial to handle side effects
1 parent 2a0162b commit 960870a

File tree

1 file changed

+53
-38
lines changed

1 file changed

+53
-38
lines changed

src/coreclr/jit/gentree.cpp

+53-38
Original file line numberDiff line numberDiff line change
@@ -14322,15 +14322,12 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1432214322

1432314323
val = cons->AsIntConCommon()->IconValue();
1432414324

14325-
// Transforms that would drop op cannot be performed if op has side effects
14326-
bool opHasSideEffects = (op->gtFlags & GTF_SIDE_EFFECT) != 0;
14327-
1432814325
// Helper function that creates a new IntCon node and morphs it, if required
1432914326
auto NewMorphedIntConNode = [&](int value) -> GenTreeIntCon* {
1433014327
GenTreeIntCon* icon = gtNewIconNode(value);
1433114328
if (fgGlobalMorph)
1433214329
{
14333-
fgMorphTreeDone(icon);
14330+
INDEBUG(icon->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
1433414331
}
1433514332
return icon;
1433614333
};
@@ -14365,43 +14362,52 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1436514362
switch (oper)
1436614363
{
1436714364
case GT_LE:
14368-
if (tree->IsUnsigned() && (val == 0) && (op1 == cons) && !opHasSideEffects)
14365+
{
14366+
if (tree->IsUnsigned() && (val == 0) && (op1 == cons))
1436914367
{
1437014368
// unsigned (0 <= x) is always true
14371-
op = NewMorphedIntConNode(1);
14369+
op = gtWrapWithSideEffects(NewMorphedIntConNode(1), op, GTF_ALL_EFFECT);
1437214370
goto DONE_FOLD;
1437314371
}
1437414372
break;
14373+
}
1437514374

1437614375
case GT_GE:
14377-
if (tree->IsUnsigned() && (val == 0) && (op2 == cons) && !opHasSideEffects)
14376+
{
14377+
if (tree->IsUnsigned() && (val == 0) && (op2 == cons))
1437814378
{
1437914379
// unsigned (x >= 0) is always true
14380-
op = NewMorphedIntConNode(1);
14380+
op = gtWrapWithSideEffects(NewMorphedIntConNode(1), op, GTF_ALL_EFFECT);
1438114381
goto DONE_FOLD;
1438214382
}
1438314383
break;
14384+
}
1438414385

1438514386
case GT_LT:
14386-
if (tree->IsUnsigned() && (val == 0) && (op2 == cons) && !opHasSideEffects)
14387+
{
14388+
if (tree->IsUnsigned() && (val == 0) && (op2 == cons))
1438714389
{
1438814390
// unsigned (x < 0) is always false
14389-
op = NewMorphedIntConNode(0);
14391+
op = gtWrapWithSideEffects(NewMorphedIntConNode(0), op, GTF_ALL_EFFECT);
1439014392
goto DONE_FOLD;
1439114393
}
1439214394
break;
14395+
}
1439314396

1439414397
case GT_GT:
14395-
if (tree->IsUnsigned() && (val == 0) && (op1 == cons) && !opHasSideEffects)
14398+
{
14399+
if (tree->IsUnsigned() && (val == 0) && (op1 == cons))
1439614400
{
1439714401
// unsigned (0 > x) is always false
14398-
op = NewMorphedIntConNode(0);
14402+
op = gtWrapWithSideEffects(NewMorphedIntConNode(0), op, GTF_ALL_EFFECT);
1439914403
goto DONE_FOLD;
1440014404
}
14405+
}
1440114406
FALLTHROUGH;
14407+
1440214408
case GT_EQ:
1440314409
case GT_NE:
14404-
14410+
{
1440514411
// Optimize boxed value classes; these are always false. This IL is
1440614412
// generated when a generic value is tested against null:
1440714413
// <T> ... foo(T x) { ... if ((object)x == null) ...
@@ -14463,57 +14469,59 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1446314469
{
1446414470
return gtFoldBoxNullable(tree);
1446514471
}
14466-
1446714472
break;
14473+
}
1446814474

1446914475
case GT_ADD:
14476+
{
1447014477
if (val == 0)
1447114478
{
1447214479
goto DONE_FOLD;
1447314480
}
1447414481
break;
14482+
}
1447514483

1447614484
case GT_MUL:
14485+
{
1447714486
if (val == 1)
1447814487
{
1447914488
goto DONE_FOLD;
1448014489
}
1448114490
else if (val == 0)
1448214491
{
14483-
/* Multiply by zero - return the 'zero' node, but not if side effects */
14484-
if (!opHasSideEffects)
14485-
{
14486-
op = cons;
14487-
goto DONE_FOLD;
14488-
}
14492+
// Multiply by zero - return the 'zero' node
14493+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
14494+
goto DONE_FOLD;
1448914495
}
1449014496
break;
14497+
}
1449114498

1449214499
case GT_DIV:
1449314500
case GT_UDIV:
14501+
{
1449414502
if ((op2 == cons) && (val == 1) && !op1->OperIsConst())
1449514503
{
1449614504
goto DONE_FOLD;
1449714505
}
1449814506
break;
14507+
}
1449914508

1450014509
case GT_SUB:
14510+
{
1450114511
if ((op2 == cons) && (val == 0) && !op1->OperIsConst())
1450214512
{
1450314513
goto DONE_FOLD;
1450414514
}
1450514515
break;
14516+
}
1450614517

1450714518
case GT_AND:
14519+
{
1450814520
if (val == 0)
1450914521
{
14510-
/* AND with zero - return the 'zero' node, but not if side effects */
14511-
14512-
if (!opHasSideEffects)
14513-
{
14514-
op = cons;
14515-
goto DONE_FOLD;
14516-
}
14522+
// AND with zero - return the 'zero' node
14523+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
14524+
goto DONE_FOLD;
1451714525
}
1451814526
else if (val == 0xFF)
1451914527
{
@@ -14546,8 +14554,10 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1454614554
}
1454714555
}
1454814556
break;
14557+
}
1454914558

1455014559
case GT_OR:
14560+
{
1455114561
if (val == 0)
1455214562
{
1455314563
goto DONE_FOLD;
@@ -14558,34 +14568,33 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1455814568

1455914569
assert(val == 1);
1456014570

14561-
/* OR with one - return the 'one' node, but not if side effects */
14562-
14563-
if (!opHasSideEffects)
14564-
{
14565-
op = cons;
14566-
goto DONE_FOLD;
14567-
}
14571+
// OR with one - return the 'one' node
14572+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
14573+
goto DONE_FOLD;
1456814574
}
1456914575
break;
14576+
}
1457014577

1457114578
case GT_LSH:
1457214579
case GT_RSH:
1457314580
case GT_RSZ:
1457414581
case GT_ROL:
1457514582
case GT_ROR:
14583+
{
1457614584
if (val == 0)
1457714585
{
1457814586
if (op2 == cons)
1457914587
{
1458014588
goto DONE_FOLD;
1458114589
}
14582-
else if (!opHasSideEffects)
14590+
else
1458314591
{
14584-
op = cons;
14592+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
1458514593
goto DONE_FOLD;
1458614594
}
1458714595
}
1458814596
break;
14597+
}
1458914598

1459014599
case GT_QMARK:
1459114600
{
@@ -14608,9 +14617,8 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1460814617
{
1460914618
fgWalkTreePre(&op, gtClearColonCond);
1461014619
}
14611-
}
14612-
1461314620
goto DONE_FOLD;
14621+
}
1461414622

1461514623
default:
1461614624
break;
@@ -14627,6 +14635,13 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1462714635
JITDUMP("Transformed into:\n");
1462814636
DISPTREE(op);
1462914637

14638+
if (fgGlobalMorph)
14639+
{
14640+
// We can sometimes produce a comma over the constant if the original op
14641+
// had a side effect, so just ensure we set the flag (which will be already
14642+
// set for the operands otherwise).
14643+
INDEBUG(op->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
14644+
}
1463014645
return op;
1463114646
}
1463214647

0 commit comments

Comments
 (0)