Skip to content

Commit

Permalink
JIT: fix case where implied subrange assertions can get lost in morph (
Browse files Browse the repository at this point in the history
…#112020)

If a method used short bit vectors during morph, modifications to the
assertion set were being made to a copy, not to the original.

Also, restrict implied boolean subrange assertions to integer vars.
  • Loading branch information
AndyAyersMS authored Jan 31, 2025
1 parent eb73ab1 commit 55e9ab5
Showing 1 changed file with 22 additions and 17 deletions.
39 changes: 22 additions & 17 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12412,26 +12412,31 @@ void Compiler::fgAssertionGen(GenTree* tree)
// If this tree creates an assignment of 0 or 1 to an int local, also create a [0..1] subrange
// assertion for that local, in case this local is used as a bool.
//
auto addImpliedBoolSubrangeAssertion = [=](AssertionIndex index, ASSERT_TP assertions) {
auto addImpliedAssertions = [=](AssertionIndex index, ASSERT_TP& assertions) {
AssertionDsc* const assertion = optGetAssertion(index);
if ((assertion->assertionKind == OAK_EQUAL) && (assertion->op1.kind == O1K_LCLVAR) &&
(assertion->op2.kind == O2K_CONST_INT))
{
ssize_t iconVal = assertion->op2.u1.iconVal;
if ((iconVal == 0) || (iconVal == 1))
{
AssertionDsc extraAssertion = {OAK_SUBRANGE};
extraAssertion.op1.kind = O1K_LCLVAR;
extraAssertion.op1.lcl.lclNum = assertion->op1.lcl.lclNum;
extraAssertion.op2.kind = O2K_SUBRANGE;
extraAssertion.op2.u2 = IntegralRange(SymbolicIntegerValue::Zero, SymbolicIntegerValue::One);
LclVarDsc* const lclDsc = lvaGetDesc(assertion->op1.lcl.lclNum);

AssertionIndex extraIndex = optFinalizeCreatingAssertion(&extraAssertion);
if (extraIndex != NO_ASSERTION_INDEX)
if (varTypeIsIntegral(lclDsc->TypeGet()))
{
ssize_t iconVal = assertion->op2.u1.iconVal;
if ((iconVal == 0) || (iconVal == 1))
{
unsigned const bvIndex = extraIndex - 1;
BitVecOps::AddElemD(apTraits, assertions, bvIndex);
announce(extraIndex, "[bool range] ");
AssertionDsc extraAssertion = {OAK_SUBRANGE};
extraAssertion.op1.kind = O1K_LCLVAR;
extraAssertion.op1.lcl.lclNum = assertion->op1.lcl.lclNum;
extraAssertion.op2.kind = O2K_SUBRANGE;
extraAssertion.op2.u2 = IntegralRange(SymbolicIntegerValue::Zero, SymbolicIntegerValue::One);

AssertionIndex extraIndex = optFinalizeCreatingAssertion(&extraAssertion);
if (extraIndex != NO_ASSERTION_INDEX)
{
unsigned const bvIndex = extraIndex - 1;
BitVecOps::AddElemD(apTraits, assertions, bvIndex);
announce(extraIndex, "[bool range] ");
}
}
}
}
Expand Down Expand Up @@ -12485,15 +12490,15 @@ void Compiler::fgAssertionGen(GenTree* tree)
announce(ifTrueAssertionIndex, "[if true] ");
unsigned const bvIndex = ifTrueAssertionIndex - 1;
BitVecOps::AddElemD(apTraits, apLocalIfTrue, bvIndex);
addImpliedBoolSubrangeAssertion(ifTrueAssertionIndex, apLocalIfTrue);
addImpliedAssertions(ifTrueAssertionIndex, apLocalIfTrue);
}

if (ifFalseAssertionIndex != NO_ASSERTION_INDEX)
{
announce(ifFalseAssertionIndex, "[if false] ");
unsigned const bvIndex = ifFalseAssertionIndex - 1;
BitVecOps::AddElemD(apTraits, apLocal, ifFalseAssertionIndex - 1);
addImpliedBoolSubrangeAssertion(ifFalseAssertionIndex, apLocal);
addImpliedAssertions(ifFalseAssertionIndex, apLocal);
}
}
else
Expand All @@ -12502,7 +12507,7 @@ void Compiler::fgAssertionGen(GenTree* tree)
announce(apIndex, "");
unsigned const bvIndex = apIndex - 1;
BitVecOps::AddElemD(apTraits, apLocal, bvIndex);
addImpliedBoolSubrangeAssertion(apIndex, apLocal);
addImpliedAssertions(apIndex, apLocal);
}
}

Expand Down

0 comments on commit 55e9ab5

Please sign in to comment.