diff --git a/src/coreclr/jit/copyprop.cpp b/src/coreclr/jit/copyprop.cpp index bdf7edaff8cb82..991c658edd612e 100644 --- a/src/coreclr/jit/copyprop.cpp +++ b/src/coreclr/jit/copyprop.cpp @@ -309,26 +309,24 @@ void Compiler::optCopyPropPushDef(GenTreeOp* asg, else { assert((lclNode->gtFlags & GTF_VAR_DEF) != 0); - ssaDefNum = GetSsaNumForLocalVarDef(lclNode); - // This will be "RESERVED_SSA_NUM" for promoted struct fields assigned using the parent struct. - // TODO-CQ: fix this. - assert((ssaDefNum != SsaConfig::RESERVED_SSA_NUM) || lvaGetDesc(lclNode)->CanBeReplacedWithItsField(this)); + // Quirk: do not collect defs from PHIs. Preserves previous behavior. + if (!asg->IsPhiDefn()) + { + ssaDefNum = GetSsaNumForLocalVarDef(lclNode); + + // This will be "RESERVED_SSA_NUM" for promoted struct fields assigned using the parent struct. + // TODO-CQ: fix this. + assert((ssaDefNum != SsaConfig::RESERVED_SSA_NUM) || lvaGetDesc(lclNode)->CanBeReplacedWithItsField(this)); + } } // The default is "not available". LclSsaVarDsc* ssaDef = nullptr; + if (ssaDefNum != SsaConfig::RESERVED_SSA_NUM) { - // This code preserves previous behavior. In principle, "ssaDefVN" should - // always be obtained directly from the SSA def descriptor and be valid. - ValueNum ssaDefVN = GetUseAsgDefVNOrTreeVN(lclNode); - assert(ssaDefVN != ValueNumStore::NoVN); - - if (ssaDefVN != ValueNumStore::VNForVoid()) - { - ssaDef = lvaGetDesc(lclNum)->GetPerSsaData(ssaDefNum); - } + ssaDef = lvaGetDesc(lclNum)->GetPerSsaData(ssaDefNum); } CopyPropSsaDefStack* defStack; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 68be59d032db61..e52b3226f3bd82 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7730,25 +7730,14 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) { // Should not have been recorded as updating ByrefExposed mem. assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree)); + assert(rhsVNPair.BothDefined()); - assert(rhsVNPair.GetLiberal() != ValueNumStore::NoVN); - - lhs->gtVNPair = rhsVNPair; lvaTable[lcl->GetLclNum()].GetPerSsaData(lclDefSsaNum)->m_vnPair = rhsVNPair; -#ifdef DEBUG - if (verbose) - { - printf("N%03u ", lhs->gtSeqNum); - Compiler::printTreeID(lhs); - printf(" "); - gtDispNodeName(lhs); - gtDispLeaf(lhs, nullptr); - printf(" => "); - vnpPrint(lhs->gtVNPair, 1); - printf("\n"); - } -#endif // DEBUG + JITDUMP("Tree [%06u] assigned VN to local var V%02u/%d: ", dspTreeID(tree), lcl->GetLclNum(), + lclDefSsaNum); + JITDUMPEXEC(vnpPrint(rhsVNPair, 1)); + JITDUMP("\n"); } else if (lvaVarAddrExposed(lcl->GetLclNum())) { @@ -7760,19 +7749,12 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) ValueNum heapVN = vnStore->VNForExpr(compCurBB, TYP_HEAP); recordAddressExposedLocalStore(tree, heapVN DEBUGARG("local assign")); } -#ifdef DEBUG else { - if (verbose) - { - JITDUMP("Tree "); - Compiler::printTreeID(tree); - printf(" assigns to non-address-taken local var V%02u; excluded from SSA, so value not " - "tracked.\n", - lcl->GetLclNum()); - } + JITDUMP("Tree [%06u] assigns to non-address-taken local var V%02u; excluded from SSA, so value not" + "tracked.\n", + dspTreeID(tree), lcl->GetLclNum()); } -#endif // DEBUG } break; case GT_LCL_FLD: @@ -7815,24 +7797,13 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) lclFld->TypeGet()); } } + lvaTable[lclFld->GetLclNum()].GetPerSsaData(lclDefSsaNum)->m_vnPair = newLhsVNPair; - lhs->gtVNPair = newLhsVNPair; -#ifdef DEBUG - if (verbose) - { - if (lhs->gtVNPair.GetLiberal() != ValueNumStore::NoVN) - { - printf("N%03u ", lhs->gtSeqNum); - Compiler::printTreeID(lhs); - printf(" "); - gtDispNodeName(lhs); - gtDispLeaf(lhs, nullptr); - printf(" => "); - vnpPrint(lhs->gtVNPair, 1); - printf("\n"); - } - } -#endif // DEBUG + + JITDUMP("Tree [%06u] assigned VN to local var V%02u/%d: ", dspTreeID(tree), lclFld->GetLclNum(), + lclDefSsaNum); + JITDUMPEXEC(vnpPrint(newLhsVNPair, 1)); + JITDUMP("\n"); } else if (lvaVarAddrExposed(lclFld->GetLclNum())) { @@ -7843,6 +7814,12 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) ValueNum heapVN = vnStore->VNForExpr(compCurBB, TYP_HEAP); recordAddressExposedLocalStore(tree, heapVN DEBUGARG("local field assign")); } + else + { + JITDUMP("Tree [%06u] assigns to non-address-taken local var V%02u; excluded from SSA, so value not" + "tracked.\n", + dspTreeID(tree), lclFld->GetLclNum()); + } } break; @@ -8529,12 +8506,8 @@ void Compiler::fgValueNumberTree(GenTree* tree) } else { + // Location nodes get the "Void" VN. assert((lcl->gtFlags & GTF_VAR_DEF) != 0); - - // Give location nodes VNForVoid. Note that for non-struct - // locals, this will get overriden in "fgValueNumberAssignment", - // because some code (notably copy propagation) depends on that. - // TODO-Cleanup: get rid of this dependency. lcl->SetVNs(vnStore->VNPForVoid()); } }