JIT: Fix OSR local detection for implicit byref promotion (#67678)
authorAndy Ayers <andya@microsoft.com>
Thu, 7 Apr 2022 15:13:47 +0000 (08:13 -0700)
committerGitHub <noreply@github.com>
Thu, 7 Apr 2022 15:13:47 +0000 (08:13 -0700)
In #67247 I revised how the JIT determines if a local requires special
handling for OSR, but for implicit byrefs we may move locals for promoted
fields back and forth between parents and this messes with the new logic.
The fix is to reset the `lvIsOSRLocal` bit explicitly when creating the
fields for an implicit byref promotion.

Also added a bit of sanity checking to `lvaIsOSRLocal`.

Fixes #67488.

src/coreclr/jit/compiler.cpp
src/coreclr/jit/morph.cpp

index 5d7b518..cd4edae 100644 (file)
@@ -9741,7 +9741,20 @@ bool Compiler::lvaIsOSRLocal(unsigned varNum)
     LclVarDsc* const varDsc = lvaGetDesc(varNum);
 
 #ifdef DEBUG
-    if (!opts.IsOSR())
+    if (opts.IsOSR())
+    {
+        if (varDsc->lvIsOSRLocal)
+        {
+            // Sanity check for promoted fields of OSR locals.
+            //
+            if (varNum >= info.compLocalsCount)
+            {
+                assert(varDsc->lvIsStructField);
+                assert(varDsc->lvParentLcl < info.compLocalsCount);
+            }
+        }
+    }
+    else
     {
         assert(!varDsc->lvIsOSRLocal);
     }
index 68346bb..30032b3 100644 (file)
@@ -17691,6 +17691,13 @@ void Compiler::fgRetypeImplicitByRefArgs()
 #if FEATURE_MULTIREG_ARGS
                     fieldVarDsc->SetOtherArgReg(REG_NA);
 #endif
+                    // Promoted fields of implicit byrefs can't be OSR locals.
+                    //
+                    if (fieldVarDsc->lvIsOSRLocal)
+                    {
+                        assert(opts.IsOSR());
+                        fieldVarDsc->lvIsOSRLocal = false;
+                    }
                 }
 
                 // Hijack lvFieldLclStart to record the new temp number.