summaryrefslogtreecommitdiff
path: root/src/jit/valuenum.cpp
diff options
context:
space:
mode:
authorBrian Sullivan <briansul@microsoft.com>2018-10-31 17:11:38 -0700
committerBrian Sullivan <briansul@microsoft.com>2018-11-05 11:07:24 -0800
commitadbc0f5f613eb72131d3224c24ef79ca589b1d06 (patch)
treeb113b4287517b9db3c9b8d222503938c53611049 /src/jit/valuenum.cpp
parent4410262505b5ebe308476116e9e833b210394638 (diff)
downloadcoreclr-adbc0f5f613eb72131d3224c24ef79ca589b1d06.tar.gz
coreclr-adbc0f5f613eb72131d3224c24ef79ca589b1d06.tar.bz2
coreclr-adbc0f5f613eb72131d3224c24ef79ca589b1d06.zip
Fix constant propagation with nested structs
Fixes #18672 Test case is here: JIT/Regression/JitBlue/GitHub_18672/GitHub_18672.cs
Diffstat (limited to 'src/jit/valuenum.cpp')
-rw-r--r--src/jit/valuenum.cpp39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp
index ddc1a0ee36..b090b80fc7 100644
--- a/src/jit/valuenum.cpp
+++ b/src/jit/valuenum.cpp
@@ -2235,7 +2235,6 @@ TailCall:
}
else
{
-
// Give up if we've run out of budget.
if (--(*pBudget) <= 0)
{
@@ -6082,8 +6081,8 @@ ValueNum Compiler::fgMemoryVNForLoopSideEffects(MemoryKind memoryKind,
assert(nonLoopPred != nullptr);
// What is its memory post-state?
ValueNum newMemoryVN = GetMemoryPerSsaData(nonLoopPred->bbMemorySsaNumOut[memoryKind])->m_vnPair.GetLiberal();
- assert(newMemoryVN !=
- ValueNumStore::NoVN); // We must have processed the single non-loop pred before reaching the loop entry.
+ assert(newMemoryVN != ValueNumStore::NoVN); // We must have processed the single non-loop pred before reaching the
+ // loop entry.
#ifdef DEBUG
if (verbose)
@@ -6352,10 +6351,6 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
{
GenTree* lhs = tree->gtGetOp1();
GenTree* rhs = tree->gtGetOp2();
-#ifdef DEBUG
- // Sometimes we query the memory ssa map in an assertion, and need a dummy location for the ignored result.
- unsigned memorySsaNum;
-#endif
if (tree->OperIsInitBlkOp())
{
@@ -6366,7 +6361,7 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
{
assert(lclVarTree->gtFlags & GTF_VAR_DEF);
// Should not have been recorded as updating the GC heap.
- assert(!GetMemorySsaMap(GcHeap)->Lookup(tree, &memorySsaNum));
+ assert(!GetMemorySsaMap(GcHeap)->Lookup(tree));
unsigned lclNum = lclVarTree->GetLclNum();
@@ -6375,7 +6370,7 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
if (lvaInSsa(lclNum))
{
// Should not have been recorded as updating ByrefExposed.
- assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree, &memorySsaNum));
+ assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree));
unsigned lclDefSsaNum = GetSsaNumForLocalVarDef(lclVarTree);
@@ -6435,7 +6430,7 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
if (tree->DefinesLocal(this, &lclVarTree, &isEntire))
{
// Should not have been recorded as updating the GC heap.
- assert(!GetMemorySsaMap(GcHeap)->Lookup(tree, &memorySsaNum));
+ assert(!GetMemorySsaMap(GcHeap)->Lookup(tree));
unsigned lhsLclNum = lclVarTree->GetLclNum();
FieldSeqNode* lhsFldSeq = nullptr;
@@ -6443,12 +6438,11 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
if (lvaInSsa(lhsLclNum))
{
// Should not have been recorded as updating ByrefExposed.
- assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree, &memorySsaNum));
+ assert(!GetMemorySsaMap(ByrefExposed)->Lookup(tree));
unsigned lclDefSsaNum = GetSsaNumForLocalVarDef(lclVarTree);
- if (lhs->IsLocalExpr(this, &lclVarTree, &lhsFldSeq) ||
- (lhs->OperIsBlk() && (lhs->AsBlk()->gtBlkSize == lvaLclSize(lhsLclNum))))
+ if (lhs->IsLocalExpr(this, &lclVarTree, &lhsFldSeq))
{
noway_assert(lclVarTree->gtLclNum == lhsLclNum);
}
@@ -6599,12 +6593,15 @@ void Compiler::fgValueNumberBlockAssignment(GenTree* tree)
}
else if (lhsFldSeq != nullptr && isEntire)
{
- // This can occur in for structs with one field, itself of a struct type.
- // We won't promote these.
- // TODO-Cleanup: decide what exactly to do about this.
- // Always treat them as maps, making them use/def, or reconstitute the
- // map view here?
- isNewUniq = true;
+ // This can occur for structs with one field, itself of a struct type.
+ // We are assigning the one field and it is also the entire enclosing struct.
+ //
+ // Use an unique value number for the old map, as this is an an entire assignment
+ // and we won't have any other values in the map
+ ValueNumPair oldMap;
+ oldMap.SetBoth(vnStore->VNForExpr(compCurBB, lclVarTree->TypeGet()));
+ rhsVNPair = vnStore->VNPairApplySelectorsAssign(oldMap, lhsFldSeq, rhsVNPair, lclVarTree->TypeGet(),
+ compCurBB);
}
else if (!isNewUniq)
{
@@ -8479,8 +8476,8 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN
// Add the accumulated exceptions.
call->gtVNPair = vnStore->VNPWithExc(call->gtVNPair, vnpExc);
}
- assert(args == nullptr ||
- generateUniqueVN); // All arguments should be processed or we generate unique VN and do not care.
+ assert(args == nullptr || generateUniqueVN); // All arguments should be processed or we generate unique VN and do
+ // not care.
}
void Compiler::fgValueNumberCall(GenTreeCall* call)