@@ -4043,6 +4043,7 @@ void Compiler::optAssertionProp_RangeProperties(ASSERT_VALARG_TP assertions,
40434043 GenTree* tree,
40444044 Statement* stmt,
40454045 BasicBlock* block,
4046+ bool onlyIfCheap,
40464047 bool * isKnownNonZero,
40474048 bool * isKnownNonNegative)
40484049{
@@ -4169,6 +4170,29 @@ void Compiler::optAssertionProp_RangeProperties(ASSERT_VALARG_TP assertions,
41694170 // Let's see if MergeEdgeAssertions can help us:
41704171 if (tree->TypeIs (TYP_INT))
41714172 {
4173+ if (!onlyIfCheap)
4174+ {
4175+ // For SSA-based we also need to check whether it overflows or not.
4176+ Range range = Range (Limit (Limit::keUndef));
4177+ if (GetRangeCheck ()->TryGetRange (block, tree, &range))
4178+ {
4179+ if (range.LowerLimit ().IsConstant ())
4180+ {
4181+ if (range.LowerLimit ().IsConstant ())
4182+ {
4183+ if (range.LowerLimit ().GetConstant () >= 0 )
4184+ {
4185+ *isKnownNonNegative = true ;
4186+ }
4187+ if (range.LowerLimit ().GetConstant () > 0 )
4188+ {
4189+ *isKnownNonZero = true ;
4190+ }
4191+ }
4192+ }
4193+ }
4194+ }
4195+
41724196 // See if (X + CNS) is known to be non-negative
41734197 if (tree->OperIs (GT_ADD) && tree->gtGetOp2 ()->IsIntCnsFitsInI32 ())
41744198 {
@@ -4257,8 +4281,8 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions,
42574281 bool op2IsNotZero;
42584282 bool op1IsNotNegative;
42594283 bool op2IsNotNegative;
4260- optAssertionProp_RangeProperties (assertions, op1, stmt, block, &op1IsNotZero, &op1IsNotNegative);
4261- optAssertionProp_RangeProperties (assertions, op2, stmt, block, &op2IsNotZero, &op2IsNotNegative);
4284+ optAssertionProp_RangeProperties (assertions, op1, stmt, block, false , &op1IsNotZero, &op1IsNotNegative);
4285+ optAssertionProp_RangeProperties (assertions, op2, stmt, block, false , &op2IsNotZero, &op2IsNotNegative);
42624286
42634287 bool changed = false ;
42644288 if (op1IsNotNegative && op2IsNotNegative && tree->OperIs (GT_DIV, GT_MOD))
@@ -4561,7 +4585,7 @@ GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions,
45614585 if (op2->IsIntegralConst (0 ) && tree->OperIsCmpCompare ())
45624586 {
45634587 bool isNonZero, isNeverNegative;
4564- optAssertionProp_RangeProperties (assertions, op1, stmt, block, &isNonZero, &isNeverNegative);
4588+ optAssertionProp_RangeProperties (assertions, op1, stmt, block, true , &isNonZero, &isNeverNegative);
45654589
45664590 if (tree->OperIs (GT_GE, GT_LT) && isNeverNegative)
45674591 {
@@ -4595,6 +4619,25 @@ GenTree* Compiler::optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions,
45954619 }
45964620 }
45974621
4622+ if (tree->OperIsCmpCompare () && op1->TypeIs (TYP_INT) && op2->IsIntCnsFitsInI32 () &&
4623+ // JIT-TP: Ignore "X relop 0" - it will be handled below
4624+ !op2->IsIntegralConst (0 ))
4625+ {
4626+ // NOTE: we can call GetRange for op2 as well, but that will be even more expensive,
4627+ Range rng1 = Range (Limit (Limit::keUndef));
4628+ if (GetRangeCheck ()->TryGetRange (block, op1, &rng1))
4629+ {
4630+ Range rng2 = Range (Limit (Limit::keConstant, static_cast <int >(op2->AsIntCon ()->IconValue ())));
4631+ RangeOps::RelationKind kind = RangeOps::EvalRelop (tree->OperGet (), tree->IsUnsigned (), rng1, rng2);
4632+ if ((kind != RangeOps::RelationKind::Unknown))
4633+ {
4634+ newTree = kind == RangeOps::RelationKind::AlwaysTrue ? gtNewTrue () : gtNewFalse ();
4635+ newTree = gtWrapWithSideEffects (newTree, tree, GTF_ALL_EFFECT);
4636+ return optAssertionProp_Update (newTree, tree, stmt);
4637+ }
4638+ }
4639+ }
4640+
45984641 // Look for assertions of the form (tree EQ/NE 0)
45994642 AssertionIndex index = optGlobalAssertionIsEqualOrNotEqualZero (assertions, tree);
46004643
@@ -4975,7 +5018,7 @@ GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions,
49755018 {
49765019 bool isKnownNonZero;
49775020 bool isKnownNonNegative;
4978- optAssertionProp_RangeProperties (assertions, lcl, stmt, block, &isKnownNonZero, &isKnownNonNegative);
5021+ optAssertionProp_RangeProperties (assertions, lcl, stmt, block, false , &isKnownNonZero, &isKnownNonNegative);
49795022 if (isKnownNonNegative)
49805023 {
49815024 cast->SetUnsigned ();
0 commit comments