From 661c7df9c9fb8977b77bb9996220984a7f19af73 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 3 Nov 2023 16:17:10 +0100 Subject: [PATCH 1/9] Convert DIV/MOD to UDIV/UMOD --- src/coreclr/jit/assertionprop.cpp | 24 +++++++++++++++++++ src/coreclr/jit/compiler.h | 38 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 348764908e83ed..94c7437a6e4814 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -4787,6 +4787,30 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, case GT_RETURN: return optAssertionProp_Return(assertions, tree->AsUnOp(), stmt); + case GT_MOD: + case GT_DIV: + { + // Convert MOD/DIV to UMOD/UDIV if both operands are known to be non-negative. + // For now, we're mainly interested in "X op CNS" pattern (where CNS > 0). + const GenTree* op1 = tree->gtGetOp1(); + const GenTree* op2 = tree->gtGetOp2(); + if (!optLocalAssertionProp && !BitVecOps::IsEmpty(apTraits, assertions) && op2->IsNeverNegative(this)) + { + const ValueNum lclVN = vnStore->VNConservativeNormalValue(op1->gtVNPair); + for (AssertionIndex index = 1; index <= optAssertionCount; index++) + { + AssertionDsc* curAssertion = optGetAssertion(index); + if (BitVecOps::IsMember(apTraits, assertions, index - 1) && + curAssertion->IsNeverNegative(this, lclVN)) + { + tree->SetOper(tree->OperIs(GT_DIV) ? GT_UDIV : GT_UMOD, GenTree::PRESERVE_VN); + break; + } + } + } + return nullptr; + } + case GT_BLK: case GT_IND: case GT_STOREIND: diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index dfafe03461d349..8c5e67b3f42e7e 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7598,6 +7598,44 @@ class Compiler return false; } + bool IsNeverNegative(Compiler* comp, ValueNum vn) + { + if (!IsConstantBound()) + { + return false; + } + + ValueNumStore::ConstantBoundInfo info; + comp->vnStore->GetConstantBoundInfo(op1.vn, &info); + if ((info.cmpOpVN != vn) || info.isUnsigned) + { + return false; + } + + // Root assertion has to be either: + // (X relop CNS) == 0 + // (X relop CNS) != 0 + if ((op2.kind != O2K_CONST_INT) || (op2.u1.iconVal != 0)) + { + return false; + } + + genTreeOps oper = (genTreeOps)info.cmpOper; + + // (X relop CNS) == 0: + if (assertionKind == OAK_EQUAL) + { + oper = GenTree::ReverseRelop(oper); + } + + if (info.constVal >= 0) + { + // "X >= CNS" or "X > CNS" + return (oper == GT_GE) || (oper == GT_GT); + } + return false; + } + bool Complementary(AssertionDsc* that, bool vnBased) { return ComplementaryKind(assertionKind, that->assertionKind) && HasSameOp1(that, vnBased) && From ab1a3c179ebe0c181b2b3f1f1c0d21d1ce708c6a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 3 Nov 2023 16:55:31 +0100 Subject: [PATCH 2/9] Clean up --- src/coreclr/jit/assertionprop.cpp | 3 ++- src/coreclr/jit/gentree.cpp | 14 -------------- src/coreclr/jit/gentree.h | 8 -------- src/coreclr/jit/lower.cpp | 1 - 4 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 94c7437a6e4814..efec43ad03a700 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -4794,7 +4794,8 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, // For now, we're mainly interested in "X op CNS" pattern (where CNS > 0). const GenTree* op1 = tree->gtGetOp1(); const GenTree* op2 = tree->gtGetOp2(); - if (!optLocalAssertionProp && !BitVecOps::IsEmpty(apTraits, assertions) && op2->IsNeverNegative(this)) + if (varTypeIsIntegral(tree) && !optLocalAssertionProp && !BitVecOps::IsEmpty(apTraits, assertions) && + op2->IsNeverNegative(this)) { const ValueNum lclVN = vnStore->VNConservativeNormalValue(op1->gtVNPair); for (AssertionIndex index = 1; index <= optAssertionCount; index++) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 48d76cf396edb9..180149a5cf83a2 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -8764,8 +8764,6 @@ void GenTreeOp::CheckDivideByConstOptimized(Compiler* comp) { if (UsesDivideByConstOptimized(comp)) { - gtFlags |= GTF_DIV_BY_CNS_OPT; - // Now set DONT_CSE on the GT_CNS_INT divisor, note that // with ValueNumbering we can have a non GT_CNS_INT divisor GenTree* divisor = gtGetOp2()->gtEffectiveVal(/*commaOnly*/ true); @@ -11143,18 +11141,6 @@ void Compiler::gtDispNode(GenTree* tree, IndentStack* indentStack, _In_ _In_opt_ } goto DASH; - case GT_DIV: - case GT_MOD: - case GT_UDIV: - case GT_UMOD: - if (tree->gtFlags & GTF_DIV_BY_CNS_OPT) - { - printf("M"); // We will use a Multiply by reciprical - --msgLength; - break; - } - goto DASH; - case GT_LCL_FLD: case GT_LCL_VAR: case GT_LCL_ADDR: diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 005cb2bfe187f0..ff45d2def41686 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -547,8 +547,6 @@ enum GenTreeFlags : unsigned int GTF_DIV_MOD_NO_OVERFLOW = 0x40000000, // GT_DIV, GT_MOD -- Div or mod definitely does not overflow. - GTF_DIV_BY_CNS_OPT = 0x80000000, // GT_DIV -- Uses the division by constant optimization to compute this division - GTF_CHK_INDEX_INBND = 0x80000000, // GT_BOUNDS_CHECK -- have proven this check is always in-bounds GTF_ARRLEN_NONFAULTING = 0x20000000, // GT_ARR_LENGTH -- An array length operation that cannot fault. Same as GT_IND_NONFAULTING. @@ -3007,12 +3005,6 @@ struct GenTreeOp : public GenTreeUnOp // then sets the flag GTF_DIV_BY_CNS_OPT and GTF_DONT_CSE on the constant void CheckDivideByConstOptimized(Compiler* comp); - // True if this node is marked as using the division by constant optimization - bool MarkedDivideByConstOptimized() const - { - return (gtFlags & GTF_DIV_BY_CNS_OPT) != 0; - } - #if !defined(TARGET_64BIT) || defined(TARGET_ARM64) bool IsValidLongMul(); #endif diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 8a810c65d5cdcf..57ec7d2d4b2f2f 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -6584,7 +6584,6 @@ bool Lowering::LowerUnsignedDivOrMod(GenTreeOp* divMod) unreached(); #endif } - assert(divMod->MarkedDivideByConstOptimized()); const bool requiresDividendMultiuse = !isDiv; const weight_t curBBWeight = m_block->getBBWeight(comp); From 2862fa2372d0ac7b78831e1e6ee00263566e11b7 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 12:15:40 +0100 Subject: [PATCH 3/9] Clean up --- src/coreclr/jit/assertionprop.cpp | 52 +++++++++++++++++-------------- src/coreclr/jit/compiler.h | 5 ++- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index efec43ad03a700..13c046aaee8ab2 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3551,6 +3551,33 @@ GenTree* Compiler::optAssertionProp_BlockStore(ASSERT_VALARG_TP assertions, GenT return nullptr; } +GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeOp* tree, Statement* stmt) +{ + if (optLocalAssertionProp || !varTypeIsIntegral(tree) || BitVecOps::IsEmpty(apTraits, assertions)) + { + return nullptr; + } + + // For now, we're mainly interested in "X op CNS" pattern (where CNS > 0). + // Technically, we can check assertions for both operands, but it's not clear if it's worth it. + if (!tree->gtGetOp2()->IsNeverNegative(this)) + { + return nullptr; + } + + const ValueNum dividendVN = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair); + for (AssertionIndex index = 1; index <= optAssertionCount; index++) + { + AssertionDsc* curAssertion = optGetAssertion(index); + if (BitVecOps::IsMember(apTraits, assertions, index - 1) && curAssertion->IsNeverNegative(this, dividendVN)) + { + tree->SetOper(tree->OperIs(GT_DIV) ? GT_UDIV : GT_UMOD, GenTree::PRESERVE_VN); + return optAssertionProp_Update(tree, tree, stmt); + } + } + return nullptr; +} + //------------------------------------------------------------------------ // optAssertionProp_Return: Try and optimize a GT_RETURN via assertions. // @@ -4789,28 +4816,7 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, case GT_MOD: case GT_DIV: - { - // Convert MOD/DIV to UMOD/UDIV if both operands are known to be non-negative. - // For now, we're mainly interested in "X op CNS" pattern (where CNS > 0). - const GenTree* op1 = tree->gtGetOp1(); - const GenTree* op2 = tree->gtGetOp2(); - if (varTypeIsIntegral(tree) && !optLocalAssertionProp && !BitVecOps::IsEmpty(apTraits, assertions) && - op2->IsNeverNegative(this)) - { - const ValueNum lclVN = vnStore->VNConservativeNormalValue(op1->gtVNPair); - for (AssertionIndex index = 1; index <= optAssertionCount; index++) - { - AssertionDsc* curAssertion = optGetAssertion(index); - if (BitVecOps::IsMember(apTraits, assertions, index - 1) && - curAssertion->IsNeverNegative(this, lclVN)) - { - tree->SetOper(tree->OperIs(GT_DIV) ? GT_UDIV : GT_UMOD, GenTree::PRESERVE_VN); - break; - } - } - } - return nullptr; - } + return optAssertionProp_ModDiv(assertions, tree->AsOp(), stmt); case GT_BLK: case GT_IND: @@ -4837,11 +4843,9 @@ GenTree* Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, case GT_LE: case GT_GT: case GT_GE: - return optAssertionProp_RelOp(assertions, tree, stmt); case GT_JTRUE: - if (block != nullptr) { return optVNConstantPropOnJTrue(block, tree); diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8c5e67b3f42e7e..b035a295b7fa84 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7600,6 +7600,8 @@ class Compiler bool IsNeverNegative(Compiler* comp, ValueNum vn) { + // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND + // representing "(X relop CNS) ==/!= 0" assertion. if (!IsConstantBound()) { return false; @@ -7622,7 +7624,7 @@ class Compiler genTreeOps oper = (genTreeOps)info.cmpOper; - // (X relop CNS) == 0: + // Normalize "(X relop CNS) == false" to "(X reversed_relop CNS) == true" if (assertionKind == OAK_EQUAL) { oper = GenTree::ReverseRelop(oper); @@ -7780,6 +7782,7 @@ class Compiler GenTree* optAssertionProp_LclFld(ASSERT_VALARG_TP assertions, GenTreeLclVarCommon* tree, Statement* stmt); GenTree* optAssertionProp_LocalStore(ASSERT_VALARG_TP assertions, GenTreeLclVarCommon* store, Statement* stmt); GenTree* optAssertionProp_BlockStore(ASSERT_VALARG_TP assertions, GenTreeBlk* store, Statement* stmt); + GenTree* optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeOp* tree, Statement* stmt); GenTree* optAssertionProp_Return(ASSERT_VALARG_TP assertions, GenTreeUnOp* ret, Statement* stmt); GenTree* optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, Statement* stmt); GenTree* optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTreeCast* cast, Statement* stmt); From ac83ee1bd9e9812646f952cb2cdf57a7ee9b3083 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 14:48:55 +0100 Subject: [PATCH 4/9] Clean up --- src/coreclr/jit/assertionprop.cpp | 55 ++++++++++++++++++++++++++++++- src/coreclr/jit/compiler.h | 40 ---------------------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 13c046aaee8ab2..db1a335e84322f 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3551,6 +3551,21 @@ GenTree* Compiler::optAssertionProp_BlockStore(ASSERT_VALARG_TP assertions, GenT return nullptr; } +//------------------------------------------------------------------------ +// optAssertionProp_ModDiv: Convert DIV/MOD to UDIV/UMOD if both operands +// can be proven to be non-negative, e.g.: +// +// if (x > 0) // creates "x > 0" assertion +// return x / 8; // DIV can be converted to UDIV +// +// Arguments: +// assertions - set of live assertions +// tree - the DIV/MOD node to optimize +// stmt - statement containing DIV/MOD +// +// Returns: +// Updated UDIV/UMOD node, or "nullptr" +// GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeOp* tree, Statement* stmt) { if (optLocalAssertionProp || !varTypeIsIntegral(tree) || BitVecOps::IsEmpty(apTraits, assertions)) @@ -3569,8 +3584,46 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO for (AssertionIndex index = 1; index <= optAssertionCount; index++) { AssertionDsc* curAssertion = optGetAssertion(index); - if (BitVecOps::IsMember(apTraits, assertions, index - 1) && curAssertion->IsNeverNegative(this, dividendVN)) + if (!BitVecOps::IsMember(apTraits, assertions, index - 1)) + { + continue; + } + + // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND + // representing "(X relop CNS) ==/!= 0" assertion. + if (!curAssertion->IsConstantBound()) + { + continue; + } + + ValueNumStore::ConstantBoundInfo info; + vnStore->GetConstantBoundInfo(curAssertion->op1.vn, &info); + + if (info.cmpOpVN != dividendVN) + { + continue; + } + + // Root assertion has to be either: + // (X relop CNS) == 0 + // (X relop CNS) != 0 + if ((curAssertion->op2.kind != O2K_CONST_INT) || (curAssertion->op2.u1.iconVal != 0)) + { + continue; + } + + auto cmpOper = static_cast(info.cmpOper); + + // Normalize "(X relop CNS) == false" to "(X reversed_relop CNS) == true" + if (curAssertion->assertionKind == OAK_EQUAL) + { + cmpOper = GenTree::ReverseRelop(cmpOper); + } + + // "X >= CNS" or "X > CNS" where CNS is >= 0 + if ((info.constVal >= 0) && ((cmpOper == GT_GE) || (cmpOper == GT_GT))) { + JITDUMP("Converting DIV/MOD to unsigned UDIV/UMOD since both operands are never negative...\n") tree->SetOper(tree->OperIs(GT_DIV) ? GT_UDIV : GT_UMOD, GenTree::PRESERVE_VN); return optAssertionProp_Update(tree, tree, stmt); } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index b035a295b7fa84..4427b86dcdd2ec 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7598,46 +7598,6 @@ class Compiler return false; } - bool IsNeverNegative(Compiler* comp, ValueNum vn) - { - // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND - // representing "(X relop CNS) ==/!= 0" assertion. - if (!IsConstantBound()) - { - return false; - } - - ValueNumStore::ConstantBoundInfo info; - comp->vnStore->GetConstantBoundInfo(op1.vn, &info); - if ((info.cmpOpVN != vn) || info.isUnsigned) - { - return false; - } - - // Root assertion has to be either: - // (X relop CNS) == 0 - // (X relop CNS) != 0 - if ((op2.kind != O2K_CONST_INT) || (op2.u1.iconVal != 0)) - { - return false; - } - - genTreeOps oper = (genTreeOps)info.cmpOper; - - // Normalize "(X relop CNS) == false" to "(X reversed_relop CNS) == true" - if (assertionKind == OAK_EQUAL) - { - oper = GenTree::ReverseRelop(oper); - } - - if (info.constVal >= 0) - { - // "X >= CNS" or "X > CNS" - return (oper == GT_GE) || (oper == GT_GT); - } - return false; - } - bool Complementary(AssertionDsc* that, bool vnBased) { return ComplementaryKind(assertionKind, that->assertionKind) && HasSameOp1(that, vnBased) && From 2b01f7766265a82754c01828b3d2554da007a112 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 15:04:48 +0100 Subject: [PATCH 5/9] formatting --- src/coreclr/jit/assertionprop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index db1a335e84322f..ab61d24dbe1a82 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3588,7 +3588,7 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO { continue; } - + // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND // representing "(X relop CNS) ==/!= 0" assertion. if (!curAssertion->IsConstantBound()) From 2169ef302cb5249fe1a7696f5a0b999a3db188c4 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 16:52:25 +0100 Subject: [PATCH 6/9] Address feedback --- src/coreclr/jit/assertionprop.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index ab61d24dbe1a82..8b14d3e0c58ab6 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3580,15 +3580,16 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO return nullptr; } - const ValueNum dividendVN = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair); + const ValueNum dividendVN = vnStore->VNLiberalNormalValue(tree->gtGetOp1()->gtVNPair); for (AssertionIndex index = 1; index <= optAssertionCount; index++) { - AssertionDsc* curAssertion = optGetAssertion(index); if (!BitVecOps::IsMember(apTraits, assertions, index - 1)) { continue; } + AssertionDsc* curAssertion = optGetAssertion(index); + // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND // representing "(X relop CNS) ==/!= 0" assertion. if (!curAssertion->IsConstantBound()) @@ -3612,7 +3613,7 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO continue; } - auto cmpOper = static_cast(info.cmpOper); + genTreeOps cmpOper = static_cast(info.cmpOper); // Normalize "(X relop CNS) == false" to "(X reversed_relop CNS) == true" if (curAssertion->assertionKind == OAK_EQUAL) From a37bfb53724021907637092b0ef4ae25a1894fad Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 17:11:44 +0100 Subject: [PATCH 7/9] revert to Conservative VN --- src/coreclr/jit/assertionprop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 8b14d3e0c58ab6..07b3a99a83b90b 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3580,7 +3580,7 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO return nullptr; } - const ValueNum dividendVN = vnStore->VNLiberalNormalValue(tree->gtGetOp1()->gtVNPair); + const ValueNum dividendVN = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair); for (AssertionIndex index = 1; index <= optAssertionCount; index++) { if (!BitVecOps::IsMember(apTraits, assertions, index - 1)) From 44d33f1fb897d255db1900a9d66a789c0175fd18 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 4 Nov 2023 18:44:28 +0100 Subject: [PATCH 8/9] Use BitVecOps::Iter --- src/coreclr/jit/assertionprop.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 07b3a99a83b90b..d465bb7adc2e20 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3580,15 +3580,17 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO return nullptr; } - const ValueNum dividendVN = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair); - for (AssertionIndex index = 1; index <= optAssertionCount; index++) + const ValueNum dividendVN = vnStore->VNConservativeNormalValue(tree->gtGetOp1()->gtVNPair); + BitVecOps::Iter iter(apTraits, assertions); + unsigned index = 0; + while (iter.NextElem(&index)) { - if (!BitVecOps::IsMember(apTraits, assertions, index - 1)) + const AssertionIndex assertionIndex = GetAssertionIndex(index); + if (assertionIndex > optAssertionCount) { - continue; + break; } - - AssertionDsc* curAssertion = optGetAssertion(index); + AssertionDsc* curAssertion = optGetAssertion(assertionIndex); // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND // representing "(X relop CNS) ==/!= 0" assertion. From 979e1428ab6a3bddc9d0a000cc84299b5789c9b9 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 6 Nov 2023 01:35:49 +0100 Subject: [PATCH 9/9] Update assertionprop.cpp --- src/coreclr/jit/assertionprop.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index d465bb7adc2e20..69d06a5f3fb079 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3585,12 +3585,7 @@ GenTree* Compiler::optAssertionProp_ModDiv(ASSERT_VALARG_TP assertions, GenTreeO unsigned index = 0; while (iter.NextElem(&index)) { - const AssertionIndex assertionIndex = GetAssertionIndex(index); - if (assertionIndex > optAssertionCount) - { - break; - } - AssertionDsc* curAssertion = optGetAssertion(assertionIndex); + AssertionDsc* curAssertion = optGetAssertion(GetAssertionIndex(index)); // OAK_[NOT]_EQUAL assertion with op1 being O1K_CONSTANT_LOOP_BND // representing "(X relop CNS) ==/!= 0" assertion.