@@ -14518,9 +14518,10 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
14518
14518
// Optimize boxed value classes; these are always false. This IL is
14519
14519
// generated when a generic value is tested against null:
14520
14520
// <T> ... foo(T x) { ... if ((object)x == null) ...
14521
- if ((val == 0) && op->IsBoxedValue())
14521
+ // Also fold checks against known non-null data like static readonlys
14522
+ if ((val == 0) && !fgAddrCouldBeNull(op))
14522
14523
{
14523
- JITDUMP("\nAttempting to optimize BOX(valueType) %s null [%06u]\n", GenTree::OpName(oper),
14524
+ JITDUMP("\nAttempting to optimize BOX(valueType)/non-null %s null [%06u]\n", GenTree::OpName(oper),
14524
14525
dspTreeID(tree));
14525
14526
14526
14527
// We don't expect GT_GT with signed compares, and we
@@ -14532,44 +14533,46 @@ GenTree* Compiler::gtFoldExprSpecial(GenTree* tree)
14532
14533
}
14533
14534
else
14534
14535
{
14535
- // The tree under the box must be side effect free
14536
- // since we will drop it if we optimize.
14537
- assert(!gtTreeHasSideEffects(op->AsBox()->BoxOp(), GTF_SIDE_EFFECT));
14536
+ bool wrapEffects = true;
14537
+ if (op->IsBoxedValue())
14538
+ {
14539
+ // The tree under the box must be side effect free
14540
+ // since we will drop it if we optimize.
14541
+ assert(!gtTreeHasSideEffects(op->AsBox()->BoxOp(), GTF_SIDE_EFFECT));
14538
14542
14539
- // See if we can optimize away the box and related statements.
14540
- GenTree* boxSourceTree = gtTryRemoveBoxUpstreamEffects(op);
14541
- bool didOptimize = (boxSourceTree != nullptr);
14543
+ // See if we can optimize away the box and related statements.
14544
+ wrapEffects = ( gtTryRemoveBoxUpstreamEffects(op) == nullptr );
14545
+ }
14542
14546
14543
- // If optimization succeeded, remove the box.
14544
- if (didOptimize)
14547
+ // Set up the result of the compare.
14548
+ int compareResult;
14549
+ if (oper == GT_GT)
14545
14550
{
14546
- // Set up the result of the compare.
14547
- int compareResult = 0;
14548
- if (oper == GT_GT)
14549
- {
14550
- // GT_GT(null, box) == false
14551
- // GT_GT(box, null) == true
14552
- compareResult = (op1 == op);
14553
- }
14554
- else if (oper == GT_EQ)
14555
- {
14556
- // GT_EQ(box, null) == false
14557
- // GT_EQ(null, box) == false
14558
- compareResult = 0;
14559
- }
14560
- else
14561
- {
14562
- assert(oper == GT_NE);
14563
- // GT_NE(box, null) == true
14564
- // GT_NE(null, box) == true
14565
- compareResult = 1;
14566
- }
14567
-
14568
- JITDUMP("\nSuccess: replacing BOX(valueType) %s null with %d\n", GenTree::OpName(oper),
14569
- compareResult);
14551
+ // GT_GT(null, op) == false
14552
+ // GT_GT(op, null) == true
14553
+ compareResult = (op1 == op);
14554
+ }
14555
+ else if (oper == GT_EQ)
14556
+ {
14557
+ // GT_EQ(op, null) == false
14558
+ // GT_EQ(null, op) == false
14559
+ compareResult = 0;
14560
+ }
14561
+ else
14562
+ {
14563
+ assert(oper == GT_NE);
14564
+ // GT_NE(op, null) == true
14565
+ // GT_NE(null, op) == true
14566
+ compareResult = 1;
14567
+ }
14570
14568
14571
- return NewMorphedIntConNode(compareResult);
14569
+ GenTree* newTree = gtNewIconNode(compareResult);
14570
+ if (wrapEffects)
14571
+ {
14572
+ newTree = gtWrapWithSideEffects(newTree, op, GTF_ALL_EFFECT);
14572
14573
}
14574
+ op = newTree;
14575
+ goto DONE_FOLD;
14573
14576
}
14574
14577
}
14575
14578
else
0 commit comments