Repository: dotnet/runtime
File: src/coreclr/jit/assertionprop.cpp (C++)

Code before:
    }
#ifdef TARGET_64BIT
    else if (vnType == TYP_LONG)
    {
        *pConstant = vnStore->ConstantValue<INT64>(vn);
        *pFlags    = vnStore->IsVNHandle(vn) ? vnStore->GetHandleFlags(vn) : GTF_EMPTY;
        return true;
    }
#endif

    return false;
}

/*****************************************************************************
 *
 *  Given an assertion add it to the assertion table
 *
 *  If it is already in the assertion table return the assertionIndex that
 *  we use to refer to this element.
 *  Otherwise add it to the assertion table and return the assertionIndex that
 *  we use to refer to this element.
 *  If we need to add to the table and the table is full return the value zero
 */
AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
{
    noway_assert(newAssertion->assertionKind != OAK_INVALID);

    if (!optLocalAssertionProp)
    {
        // Ignore VN-based assertions with NoVN
        switch (newAssertion->op1.kind)
        {
            case O1K_LCLVAR:
            case O1K_VN:
            case O1K_BOUND_OPER_BND:
            case O1K_BOUND_LOOP_BND:
            case O1K_CONSTANT_LOOP_BND:
            case O1K_CONSTANT_LOOP_BND_UN:
            case O1K_EXACT_TYPE:
            case O1K_SUBTYPE:
                if (newAssertion->op1.vn == ValueNumStore::NoVN)
                {
                    return NO_ASSERTION_INDEX;
                }
                break;
            case O1K_ARR_BND:
                if ((newAssertion->op1.bnd.vnIdx == ValueNumStore::NoVN) ||
                    (newAssertion->op1.bnd.vnLen == ValueNumStore::NoVN))
                {
                    return NO_ASSERTION_INDEX;
                }

Review comment (bug):
We never produce constant assertions with NaN values anyway, moved to `optDebugCheckAssertion`

Code after:
        return NO_ASSERTION_INDEX;
    }

    optAssertionTabPrivate[optAssertionCount] = newAssertion;
    optAssertionCount++;

#ifdef DEBUG
    if (verbose)
    {
        printf("GenTreeNode creates assertion:\n");
        gtDispTree(optAssertionPropCurrentTree, nullptr, nullptr, true);
        printf(optLocalAssertionProp ? "In " FMT_BB " New Local " : "In " FMT_BB " New Global ", compCurBB->bbNum);
        optPrintAssertion(newAssertion, optAssertionCount);
    }
#endif // DEBUG

    // Track the short-circuit criteria
    optCanPropLclVar |= newAssertion.CanPropLclVar();
    optCanPropEqual |= newAssertion.CanPropEqualOrNotEqual();
    optCanPropNonNull |= newAssertion.CanPropNonNull();
    optCanPropSubRange |= newAssertion.CanPropSubRange();
    optCanPropBndsChk |= newAssertion.CanPropBndsCheck();

    // Assertion mask bits are [index + 1].
    if (optLocalAssertionProp)
    {
        assert(newAssertion.op1.kind == O1K_LCLVAR);

        // Mark the variables this index depends on
        unsigned lclNum = newAssertion.op1.lclNum;
        BitVecOps::AddElemD(apTraits, GetAssertionDep(lclNum), optAssertionCount - 1);
        if (newAssertion.op2.kind == O2K_LCLVAR_COPY)
        {
            lclNum = newAssertion.op2.lclNum;
            BitVecOps::AddElemD(apTraits, GetAssertionDep(lclNum), optAssertionCount - 1);
        }
    }

#ifdef DEBUG
    optDebugCheckAssertions(optAssertionCount);
#endif
    return optAssertionCount;
}

#ifdef DEBUG
void Compiler::optDebugCheckAssertion(const AssertionDsc& assertion) const
{
    assert(assertion.assertionKind < OAK_COUNT);
    assert(assertion.op1.kind < O1K_COUNT);
    assert(assertion.op2.kind < O2K_COUNT);
    // It would be good to check that op1.vn and op2.vn are valid value numbers.