Skip to content

Commit db681fb

Browse files
authored
Revert "Use rangecheck in assertprop (#112766)" (#112872)
This reverts commit 6022adf.
1 parent 2a19c9d commit db681fb

File tree

3 files changed

+38
-129
lines changed

3 files changed

+38
-129
lines changed

src/coreclr/jit/assertionprop.cpp

+6-70
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1111
*/
1212

1313
#include "jitpch.h"
14-
#include "rangecheck.h"
1514
#ifdef _MSC_VER
1615
#pragma hdrstop
1716
#endif
@@ -4126,69 +4125,6 @@ void Compiler::optAssertionProp_RangeProperties(ASSERT_VALARG_TP assertions,
41264125
}
41274126
}
41284127
}
4129-
4130-
if (*isKnownNonZero && *isKnownNonNegative)
4131-
{
4132-
return;
4133-
}
4134-
4135-
// Let's see if MergeEdgeAssertions can help us:
4136-
if (tree->TypeIs(TYP_INT))
4137-
{
4138-
// See if (X + CNS) is known to be non-negative
4139-
if (tree->OperIs(GT_ADD) && tree->gtGetOp2()->IsIntCnsFitsInI32())
4140-
{
4141-
Range rng = Range(Limit(Limit::keDependent));
4142-
ValueNum vn = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair);
4143-
RangeCheck::MergeEdgeAssertions(this, vn, ValueNumStore::NoVN, assertions, &rng, false);
4144-
4145-
int cns = static_cast<int>(tree->gtGetOp2()->AsIntCon()->IconValue());
4146-
rng.LowerLimit().AddConstant(cns);
4147-
4148-
if ((rng.LowerLimit().IsConstant() && !rng.LowerLimit().AddConstant(cns)) ||
4149-
(rng.UpperLimit().IsConstant() && !rng.UpperLimit().AddConstant(cns)))
4150-
{
4151-
// Add cns to both bounds if they are constants. Make sure the addition doesn't overflow.
4152-
return;
4153-
}
4154-
4155-
if (rng.LowerLimit().IsConstant())
4156-
{
4157-
// E.g. "X + -8" when X's range is [8..unknown]
4158-
// it's safe to say "X + -8" is non-negative
4159-
if ((rng.LowerLimit().GetConstant() == 0))
4160-
{
4161-
*isKnownNonNegative = true;
4162-
}
4163-
4164-
// E.g. "X + 8" when X's range is [0..CNS]
4165-
// Here we have to check the upper bound as well to avoid overflow
4166-
if ((rng.LowerLimit().GetConstant() > 0) && rng.UpperLimit().IsConstant() &&
4167-
rng.UpperLimit().GetConstant() > rng.LowerLimit().GetConstant())
4168-
{
4169-
*isKnownNonNegative = true;
4170-
*isKnownNonZero = true;
4171-
}
4172-
}
4173-
}
4174-
else
4175-
{
4176-
Range rng = Range(Limit(Limit::keDependent));
4177-
RangeCheck::MergeEdgeAssertions(this, treeVN, ValueNumStore::NoVN, assertions, &rng, false);
4178-
Limit lowerBound = rng.LowerLimit();
4179-
if (lowerBound.IsConstant())
4180-
{
4181-
if (lowerBound.GetConstant() >= 0)
4182-
{
4183-
*isKnownNonNegative = true;
4184-
}
4185-
if (lowerBound.GetConstant() > 0)
4186-
{
4187-
*isKnownNonZero = true;
4188-
}
4189-
}
4190-
}
4191-
}
41924128
}
41934129

41944130
//------------------------------------------------------------------------
@@ -4915,6 +4851,12 @@ GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTreeCas
49154851
// Skip over a GT_COMMA node(s), if necessary to get to the lcl.
49164852
GenTree* lcl = op1->gtEffectiveVal();
49174853

4854+
// If we don't have a cast of a LCL_VAR then bail.
4855+
if (!lcl->OperIs(GT_LCL_VAR))
4856+
{
4857+
return nullptr;
4858+
}
4859+
49184860
// Try and see if we can make this cast into a cheaper zero-extending version
49194861
// if the input is known to be non-negative.
49204862
if (!cast->IsUnsigned() && genActualTypeIsInt(lcl) && cast->TypeIs(TYP_LONG) && (TARGET_POINTER_SIZE == 8))
@@ -4928,12 +4870,6 @@ GenTree* Compiler::optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTreeCas
49284870
}
49294871
}
49304872

4931-
// If we don't have a cast of a LCL_VAR then bail.
4932-
if (!lcl->OperIs(GT_LCL_VAR))
4933-
{
4934-
return nullptr;
4935-
}
4936-
49374873
IntegralRange range = IntegralRange::ForCastInput(cast);
49384874
AssertionIndex index = optAssertionIsSubrange(lcl, range, assertions);
49394875
if (index != NO_ASSERTION_INDEX)

src/coreclr/jit/rangecheck.cpp

+31-53
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ void RangeCheck::OptimizeRangeCheck(BasicBlock* block, Statement* stmt, GenTree*
251251
{
252252
JITDUMP("Looking for array size assertions for: " FMT_VN "\n", arrLenVn);
253253
Range arrLength = Range(Limit(Limit::keDependent));
254-
MergeEdgeAssertions(m_pCompiler, arrLenVn, arrLenVn, block->bbAssertionIn, &arrLength);
254+
MergeEdgeAssertions(arrLenVn, block->bbAssertionIn, &arrLength);
255255
if (arrLength.lLimit.IsConstant())
256256
{
257257
arrSize = arrLength.lLimit.GetConstant();
@@ -640,28 +640,20 @@ void RangeCheck::MergeEdgeAssertions(GenTreeLclVarCommon* lcl, ASSERT_VALARG_TP
640640

641641
LclSsaVarDsc* ssaData = m_pCompiler->lvaGetDesc(lcl)->GetPerSsaData(lcl->GetSsaNum());
642642
ValueNum normalLclVN = m_pCompiler->vnStore->VNConservativeNormalValue(ssaData->m_vnPair);
643-
ValueNum arrLenVN = m_pCompiler->vnStore->VNConservativeNormalValue(m_pCurBndsChk->GetArrayLength()->gtVNPair);
644-
MergeEdgeAssertions(m_pCompiler, normalLclVN, arrLenVN, assertions, pRange);
643+
MergeEdgeAssertions(normalLclVN, assertions, pRange);
645644
}
646645

647646
//------------------------------------------------------------------------
648647
// MergeEdgeAssertions: Merge assertions on the edge flowing into the block about a variable
649648
//
650649
// Arguments:
651-
// comp - the compiler instance
652-
// normalLclVN - the value number to look for assertions for
653-
// preferredBoundVN - when this VN is set, it will be given preference over constant limits
654-
// assertions - the assertions to use
655-
// pRange - the range to tighten with assertions
650+
// normalLclVN - the value number to look for assertions for
651+
// assertions - the assertions to use
652+
// pRange - the range to tighten with assertions
656653
//
657-
void RangeCheck::MergeEdgeAssertions(Compiler* comp,
658-
ValueNum normalLclVN,
659-
ValueNum preferredBoundVN,
660-
ASSERT_VALARG_TP assertions,
661-
Range* pRange,
662-
bool log)
654+
void RangeCheck::MergeEdgeAssertions(ValueNum normalLclVN, ASSERT_VALARG_TP assertions, Range* pRange)
663655
{
664-
if (BitVecOps::IsEmpty(comp->apTraits, assertions))
656+
if (BitVecOps::IsEmpty(m_pCompiler->apTraits, assertions))
665657
{
666658
return;
667659
}
@@ -671,14 +663,14 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
671663
return;
672664
}
673665

674-
// Walk through the "assertions" to check if they apply.
675-
BitVecOps::Iter iter(comp->apTraits, assertions);
666+
// Walk through the "assertions" to check if the apply.
667+
BitVecOps::Iter iter(m_pCompiler->apTraits, assertions);
676668
unsigned index = 0;
677669
while (iter.NextElem(&index))
678670
{
679671
AssertionIndex assertionIndex = GetAssertionIndex(index);
680672

681-
Compiler::AssertionDsc* curAssertion = comp->optGetAssertion(assertionIndex);
673+
Compiler::AssertionDsc* curAssertion = m_pCompiler->optGetAssertion(assertionIndex);
682674

683675
Limit limit(Limit::keUndef);
684676
genTreeOps cmpOper = GT_NONE;
@@ -691,7 +683,7 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
691683
ValueNumStore::CompareCheckedBoundArithInfo info;
692684

693685
// Get i, len, cns and < as "info."
694-
comp->vnStore->GetCompareCheckedBoundArithInfo(curAssertion->op1.vn, &info);
686+
m_pCompiler->vnStore->GetCompareCheckedBoundArithInfo(curAssertion->op1.vn, &info);
695687

696688
// If we don't have the same variable we are comparing against, bail.
697689
if (normalLclVN != info.cmpOp)
@@ -705,12 +697,12 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
705697
}
706698

707699
// If the operand that operates on the bound is not constant, then done.
708-
if (!comp->vnStore->IsVNInt32Constant(info.arrOp))
700+
if (!m_pCompiler->vnStore->IsVNInt32Constant(info.arrOp))
709701
{
710702
continue;
711703
}
712704

713-
int cons = comp->vnStore->ConstantValue<int>(info.arrOp);
705+
int cons = m_pCompiler->vnStore->ConstantValue<int>(info.arrOp);
714706
limit = Limit(Limit::keBinOpArray, info.vnBound, info.arrOper == GT_SUB ? -cons : cons);
715707
cmpOper = (genTreeOps)info.cmpOper;
716708
}
@@ -720,7 +712,7 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
720712
ValueNumStore::CompareCheckedBoundArithInfo info;
721713

722714
// Get the info as "i", "<" and "len"
723-
comp->vnStore->GetCompareCheckedBound(curAssertion->op1.vn, &info);
715+
m_pCompiler->vnStore->GetCompareCheckedBound(curAssertion->op1.vn, &info);
724716

725717
// If we don't have the same variable we are comparing against, bail.
726718
if (normalLclVN == info.cmpOp)
@@ -744,7 +736,7 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
744736
ValueNumStore::ConstantBoundInfo info;
745737

746738
// Get the info as "i", "<" and "100"
747-
comp->vnStore->GetConstantBoundInfo(curAssertion->op1.vn, &info);
739+
m_pCompiler->vnStore->GetConstantBoundInfo(curAssertion->op1.vn, &info);
748740

749741
// If we don't have the same variable we are comparing against, bail.
750742
if (normalLclVN != info.cmpOpVN)
@@ -764,10 +756,10 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
764756
continue;
765757
}
766758

767-
int cnstLimit = comp->vnStore->CoercedConstantValue<int>(curAssertion->op2.vn);
759+
int cnstLimit = m_pCompiler->vnStore->CoercedConstantValue<int>(curAssertion->op2.vn);
768760

769761
if ((cnstLimit == 0) && (curAssertion->assertionKind == Compiler::OAK_NOT_EQUAL) &&
770-
comp->vnStore->IsVNCheckedBound(curAssertion->op1.vn))
762+
m_pCompiler->vnStore->IsVNCheckedBound(curAssertion->op1.vn))
771763
{
772764
// we have arr.Len != 0, so the length must be atleast one
773765
limit = Limit(Limit::keConstant, 1);
@@ -812,31 +804,31 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
812804

813805
// Make sure the assertion is of the form != 0 or == 0 if it isn't a constant assertion.
814806
if (!isConstantAssertion && (curAssertion->assertionKind != Compiler::OAK_NO_THROW) &&
815-
(curAssertion->op2.vn != comp->vnStore->VNZeroForType(TYP_INT)))
807+
(curAssertion->op2.vn != m_pCompiler->vnStore->VNZeroForType(TYP_INT)))
816808
{
817809
continue;
818810
}
819811
#ifdef DEBUG
820-
if (comp->verbose)
812+
if (m_pCompiler->verbose)
821813
{
822-
comp->optPrintAssertion(curAssertion, assertionIndex);
814+
m_pCompiler->optPrintAssertion(curAssertion, assertionIndex);
823815
}
824816
#endif
825817

826818
// Limits are sometimes made with the form vn + constant, where vn is a known constant
827819
// see if we can simplify this to just a constant
828-
if (limit.IsBinOpArray() && comp->vnStore->IsVNInt32Constant(limit.vn))
820+
if (limit.IsBinOpArray() && m_pCompiler->vnStore->IsVNInt32Constant(limit.vn))
829821
{
830-
Limit tempLimit = Limit(Limit::keConstant, comp->vnStore->ConstantValue<int>(limit.vn));
822+
Limit tempLimit = Limit(Limit::keConstant, m_pCompiler->vnStore->ConstantValue<int>(limit.vn));
831823
if (tempLimit.AddConstant(limit.cns))
832824
{
833825
limit = tempLimit;
834826
}
835827
}
836828

837-
ValueNum arrLenVN = preferredBoundVN;
829+
ValueNum arrLenVN = m_pCompiler->vnStore->VNConservativeNormalValue(m_pCurBndsChk->GetArrayLength()->gtVNPair);
838830

839-
if (comp->vnStore->IsVNConstant(arrLenVN))
831+
if (m_pCompiler->vnStore->IsVNConstant(arrLenVN))
840832
{
841833
// Set arrLenVN to NoVN; this will make it match the "vn" recorded on
842834
// constant limits (where we explicitly track the constant and don't
@@ -925,10 +917,7 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
925917

926918
if (limit.vn != arrLenVN)
927919
{
928-
if (log)
929-
{
930-
JITDUMP("Array length VN did not match arrLen=" FMT_VN ", limit=" FMT_VN "\n", arrLenVN, limit.vn);
931-
}
920+
JITDUMP("Array length VN did not match arrLen=" FMT_VN ", limit=" FMT_VN "\n", arrLenVN, limit.vn);
932921
continue;
933922
}
934923

@@ -938,10 +927,7 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
938927
// Incoming limit doesn't tighten the existing upper limit.
939928
if (limCns >= curCns)
940929
{
941-
if (log)
942-
{
943-
JITDUMP("Bound limit %d doesn't tighten current bound %d\n", limCns, curCns);
944-
}
930+
JITDUMP("Bound limit %d doesn't tighten current bound %d\n", limCns, curCns);
945931
continue;
946932
}
947933
}
@@ -968,12 +954,8 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
968954

969955
case GT_GT:
970956
case GT_GE:
971-
// GT/GE being unsigned creates a non-contiguous range which we can't represent
972-
// using single Range object.
973-
if (!isUnsigned)
974-
{
975-
pRange->lLimit = limit;
976-
}
957+
pRange->lLimit = limit;
958+
// it doesn't matter if it's isUnsigned or not here - it's not negative anyway.
977959
break;
978960

979961
case GT_EQ:
@@ -985,13 +967,9 @@ void RangeCheck::MergeEdgeAssertions(Compiler* comp,
985967
// All other 'cmpOper' kinds leave lLimit/uLimit unchanged
986968
break;
987969
}
988-
989-
if (log)
990-
{
991-
JITDUMP("The range after edge merging:");
992-
JITDUMP(pRange->ToString(comp));
993-
JITDUMP("\n");
994-
}
970+
JITDUMP("The range after edge merging:");
971+
JITDUMP(pRange->ToString(m_pCompiler));
972+
JITDUMP("\n");
995973
}
996974
}
997975

src/coreclr/jit/rangecheck.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -686,12 +686,7 @@ class RangeCheck
686686
void MergeEdgeAssertions(GenTreeLclVarCommon* lcl, ASSERT_VALARG_TP assertions, Range* pRange);
687687

688688
// Inspect the assertions about the current ValueNum to refine pRange
689-
static void MergeEdgeAssertions(Compiler* comp,
690-
ValueNum num,
691-
ValueNum preferredBoundVN,
692-
ASSERT_VALARG_TP assertions,
693-
Range* pRange,
694-
bool log = true);
689+
void MergeEdgeAssertions(ValueNum num, ASSERT_VALARG_TP assertions, Range* pRange);
695690

696691
// The maximum possible value of the given "limit". If such a value could not be determined
697692
// return "false". For example: CORINFO_Array_MaxLength for array length.

0 commit comments

Comments
 (0)