Fix ZeroInit of finally vars (#35723)
authorCarol Eidt <carol.eidt@microsoft.com>
Sat, 2 May 2020 15:58:57 +0000 (08:58 -0700)
committerGitHub <noreply@github.com>
Sat, 2 May 2020 15:58:57 +0000 (08:58 -0700)
Finally vars need zero-init'ing if we are enregistering them, but they will not necessarily be live-in to the first block, so we have to take care not to zero-init its last associated register in that case.

src/coreclr/src/jit/codegencommon.cpp

index 0eb2a70..452d4f4 100644 (file)
@@ -7569,6 +7569,25 @@ void CodeGen::genFnProlog()
 
         bool isInReg    = varDsc->lvIsInReg();
         bool isInMemory = !isInReg || varDsc->lvLiveInOutOfHndlr;
+
+        // Note that 'lvIsInReg()' will only be accurate for variables that are actually live-in to
+        // the first block. This will include all possibly-uninitialized locals, whose liveness
+        // will naturally propagate up to the entry block. However, we also set 'lvMustInit' for
+        // locals that are live-in to a finally block, and those may not be live-in to the first
+        // block. For those, we don't want to initialize the register, as it will not actually be
+        // occupying it on entry.
+        if (isInReg)
+        {
+            if (compiler->lvaEnregEHVars && varDsc->lvLiveInOutOfHndlr)
+            {
+                isInReg = VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex);
+            }
+            else
+            {
+                assert(VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex));
+            }
+        }
+
         if (isInReg)
         {
             regMaskTP regMask = genRegMask(varDsc->GetRegNum());