Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix spill check for multireg local #38360

Merged
merged 2 commits into from
Jun 25, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/coreclr/src/jit/treelifeupdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,24 +220,24 @@ void TreeLifeUpdater<ForCodeGen>::UpdateLifeVar(GenTree* tree)
// if it's a partial definition then variable "x" must have had a previous, original, site to be born.
bool isBorn;
bool isDying;
bool spill;
// GTF_SPILL will be set on a MultiRegLclVar if any registers need to be spilled.
bool spill = ((lclVarTree->gtFlags & GTF_SPILL) != 0);
bool isMultiRegLocal = lclVarTree->IsMultiRegLclVar();
if (isMultiRegLocal)
{
assert((tree->gtFlags & GTF_VAR_USEASG) == 0);
isBorn = ((tree->gtFlags & GTF_VAR_DEF) != 0);
// We should never have an 'IndirOfAddrOfLocal' for a multi-reg.
assert(lclVarTree == tree);
assert((lclVarTree->gtFlags & GTF_VAR_USEASG) == 0);
isBorn = ((lclVarTree->gtFlags & GTF_VAR_DEF) != 0);
// Note that for multireg locals we can have definitions for which some of those are last uses.
// We don't want to add those to the varDeltaSet because otherwise they will be added as newly
// live.
isDying = !isBorn && tree->AsLclVar()->HasLastUse();
// GTF_SPILL will be set if any registers need to be spilled.
spill = ((tree->gtFlags & GTF_SPILL) != 0);
isDying = !isBorn && lclVarTree->HasLastUse();
}
else
{
isBorn = ((lclVarTree->gtFlags & GTF_VAR_DEF) != 0 && (lclVarTree->gtFlags & GTF_VAR_USEASG) == 0);
isDying = ((lclVarTree->gtFlags & GTF_VAR_DEATH) != 0);
spill = ((lclVarTree->gtFlags & GTF_SPILL) != 0);
}

// Since all tracked vars are register candidates, but not all are in registers at all times,
Expand Down Expand Up @@ -276,7 +276,8 @@ void TreeLifeUpdater<ForCodeGen>::UpdateLifeVar(GenTree* tree)
unsigned firstFieldVarNum = varDsc->lvFieldLclStart;
for (unsigned i = 0; i < varDsc->lvFieldCnt; ++i)
{
LclVarDsc* fldVarDsc = &(compiler->lvaTable[firstFieldVarNum + i]);
bool fieldIsSpilled = spill && ((lclVarTree->GetRegSpillFlagByIdx(i) & GTF_SPILL) != 0);
LclVarDsc* fldVarDsc = &(compiler->lvaTable[firstFieldVarNum + i]);
noway_assert(fldVarDsc->lvIsStructField);
assert(fldVarDsc->lvTracked);
unsigned fldVarIndex = fldVarDsc->lvVarIndex;
Expand All @@ -300,7 +301,7 @@ void TreeLifeUpdater<ForCodeGen>::UpdateLifeVar(GenTree* tree)
}
compiler->codeGen->genUpdateRegLife(fldVarDsc, isBorn, isFieldDying DEBUGARG(tree));
// If this was marked for spill, genProduceReg should already have spilled it.
assert(!spill);
assert(!fieldIsSpilled);
}
}
spill = false;
Expand Down