JIT: Fix arm gcstress/jistress issues (#32674)
authorAndy Ayers <andya@microsoft.com>
Sat, 22 Feb 2020 16:30:51 +0000 (08:30 -0800)
committerGitHub <noreply@github.com>
Sat, 22 Feb 2020 16:30:51 +0000 (08:30 -0800)
Three fixes for gc liveness and the profile exit hook on arm.

* If we're returning results via the hidden return buffer pointer,
make sure we treat R0 as gc live, as it holds a BYREF and may well be
a gc reference, when the method is invoked via reflection.
* If R0 is otherwise live make sure to check the "native" return type so
we handle struct-wrapped GC ref returns properly.
* If we have a tail call or tail jump, R0 is not the return value, so deducing
GC liveness for it based on method properties is unsound. It turns out in both
cases that R0 is not in use; for tail calls this is ensured by insertion of the
helper call before register allocation; for tail jumps, by spilling the argument
registers in `genJmpMethod`.

Expect this will fix most or all of the failures in #31770.

src/coreclr/src/jit/codegenarm.cpp

index 8522e28..4cca2e4 100644 (file)
@@ -1702,7 +1702,16 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper)
     bool     r0InUse;
     emitAttr attr = EA_UNKNOWN;
 
-    if (compiler->info.compRetType == TYP_VOID)
+    if (helper == CORINFO_HELP_PROF_FCN_TAILCALL)
+    {
+        // For the tail call case, the helper call is introduced during lower,
+        // so the allocator will arrange things so R0 is not in use here.
+        //
+        // For the tail jump case, all reg args have been spilled via genJmpMethod,
+        // so R0 is likewise not in use.
+        r0InUse = false;
+    }
+    else if (compiler->info.compRetType == TYP_VOID)
     {
         r0InUse = false;
     }
@@ -1718,9 +1727,13 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper)
 
     if (r0InUse)
     {
-        if (varTypeIsGC(compiler->info.compRetType))
+        if (varTypeIsGC(compiler->info.compRetNativeType))
+        {
+            attr = emitActualTypeSize(compiler->info.compRetNativeType);
+        }
+        else if (compiler->compMethodReturnsRetBufAddr())
         {
-            attr = emitActualTypeSize(compiler->info.compRetType);
+            attr = EA_BYREF;
         }
         else
         {