Skip to content

Commit b449a29

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

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

src/coreclr/jit/gentree.cpp

+54-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,60 @@ 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+
;
14525+
goto DONE_FOLD;
1451714526
}
1451814527
else if (val == 0xFF)
1451914528
{
@@ -14546,8 +14555,10 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1454614555
}
1454714556
}
1454814557
break;
14558+
}
1454914559

1455014560
case GT_OR:
14561+
{
1455114562
if (val == 0)
1455214563
{
1455314564
goto DONE_FOLD;
@@ -14558,34 +14569,33 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1455814569

1455914570
assert(val == 1);
1456014571

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-
}
14572+
// OR with one - return the 'one' node
14573+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
14574+
goto DONE_FOLD;
1456814575
}
1456914576
break;
14577+
}
1457014578

1457114579
case GT_LSH:
1457214580
case GT_RSH:
1457314581
case GT_RSZ:
1457414582
case GT_ROL:
1457514583
case GT_ROR:
14584+
{
1457614585
if (val == 0)
1457714586
{
1457814587
if (op2 == cons)
1457914588
{
1458014589
goto DONE_FOLD;
1458114590
}
14582-
else if (!opHasSideEffects)
14591+
else
1458314592
{
14584-
op = cons;
14593+
op = gtWrapWithSideEffects(cons, op, GTF_ALL_EFFECT);
1458514594
goto DONE_FOLD;
1458614595
}
1458714596
}
1458814597
break;
14598+
}
1458914599

1459014600
case GT_QMARK:
1459114601
{
@@ -14608,9 +14618,8 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1460814618
{
1460914619
fgWalkTreePre(&op, gtClearColonCond);
1461014620
}
14611-
}
14612-
1461314621
goto DONE_FOLD;
14622+
}
1461414623

1461514624
default:
1461614625
break;
@@ -14627,6 +14636,13 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
1462714636
JITDUMP("Transformed into:\n");
1462814637
DISPTREE(op);
1462914638

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

0 commit comments

Comments
 (0)