switch (tree->AsBoundsChk()->gtThrowKind)
{
case SCK_RNGCHK_FAIL:
- sprintf_s(bufp, sizeof(buf), " %s_Rng", name);
+ {
+ bufp += SimpleSprintf_s(bufp, buf, sizeof(buf), " %s_Rng", name);
+ if (tree->AsBoundsChk()->gtIndRngFailBB != nullptr)
+ {
+ bufp += SimpleSprintf_s(bufp, buf, sizeof(buf), " -> " FMT_BB,
+ tree->AsBoundsChk()->gtIndRngFailBB->bbNum);
+ }
break;
+ }
case SCK_ARG_EXCPN:
sprintf_s(bufp, sizeof(buf), " %s_Arg", name);
break;
{
unsigned varNum = compiler->lvaTrackedIndexToLclNum(varIndex);
LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
- regNumber regNum = getVarReg(map, varIndex);
regNumber oldRegNum = varDsc->GetRegNum();
- regNumber newRegNum = regNum;
+ regNumber newRegNum = getVarReg(map, varIndex);
if (oldRegNum != newRegNum)
{
if (block->bbPreds == nullptr)
{
+ assert((block != compiler->fgFirstBB) || (prevBlock != nullptr));
+ JITDUMP("\n\nNo predecessor; ");
+
+ // Some throw blocks do not have predecessor. For such blocks, we want to return the fact
+ // that predecessor is indeed null instead of returning the prevBlock. Returning prevBlock
+ // will be wrong, because LSRA would think that the variable is live in registers based on
+ // the lexical flow, but that won't be true according to the control flow.
+ // Example:
+ //
+ // IG05:
+ // ... ; V01 is in 'rdi'
+ // JNE IG07
+ // ...
+ // IG06:
+ // ...
+ // ... ; V01 is in 'rbx'
+ // JMP IG08
+ // IG07:
+ // ... ; LSRA thinks V01 is in 'rbx' if IG06 is set as previous block of IG07.
+ // ....
+ // CALL CORINFO_HELP_RNGCHKFAIL
+ // ...
+ // IG08:
+ // ...
+ // ...
+ if (block->bbJumpKind == BBJ_THROW)
+ {
+ JITDUMP(" - throw block; ");
+ return nullptr;
+ }
+
// We may have unreachable blocks, due to optimization.
// We don't want to set the predecessor as null in this case, since that will result in
// unnecessary DummyDefs, and possibly result in inconsistencies requiring resolution
// (since these unreachable blocks can have reachable successors).
- assert((block != compiler->fgFirstBB) || (prevBlock != nullptr));
- JITDUMP("\n\nNo predecessor; ");
return prevBlock;
}