Revert "Do not mark implicit byrefs with GTF_GLOB_REF" (#66415)
authorJakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Thu, 10 Mar 2022 05:10:10 +0000 (06:10 +0100)
committerGitHub <noreply@github.com>
Thu, 10 Mar 2022 05:10:10 +0000 (06:10 +0100)
* Revert "Do not mark implicit byrefs with GTF_GLOB_REF (#66266)"

This reverts commit 0a684281f661f5520ad7f358a5056a2eed5b50ba. This is
currently not safe to do in the JIT because we clear out address
exposure information in fgRetypeImplicitByRefArgs() and thus do not have
the necessary information in morph to know if indirections off of
implicit byrefs are global or not.

* Add a test

src/coreclr/jit/compiler.hpp
src/coreclr/jit/morph.cpp
src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.csproj [new file with mode: 0644]

index f10f117..595f8eb 100644 (file)
@@ -1114,6 +1114,19 @@ inline GenTreeField* Compiler::gtNewFieldRef(var_types type, CORINFO_FIELD_HANDL
         LclVarDsc* varDsc = lvaGetDesc(obj->AsUnOp()->gtOp1->AsLclVarCommon());
 
         varDsc->lvFieldAccessed = 1;
+#if defined(TARGET_AMD64) || defined(TARGET_ARM64)
+        // These structs are passed by reference and can easily become global
+        // references if those references are exposed. We clear out
+        // address-exposure information for these parameters when they are
+        // converted into references in fgRetypeImplicitByRefArgs() so we do
+        // not have the necessary information in morph to know if these
+        // indirections are actually global references, so we have to be
+        // conservative here.
+        if (varDsc->lvIsParam)
+        {
+            fieldNode->gtFlags |= GTF_GLOB_REF;
+        }
+#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64)
     }
     else
     {
index 1aa1320..db19e8f 100644 (file)
@@ -5896,9 +5896,8 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac)
         fgMorphImplicitByRefArgs(objRef);
     }
 
-    noway_assert(((objRef != nullptr) && ((objRef->IsLocalAddrExpr() != nullptr) ||
-                                          (objRef->IsImplicitByrefParameterValue(this) != nullptr))) ||
-                 (tree->gtFlags & GTF_GLOB_REF) != 0);
+    noway_assert(((objRef != nullptr) && (objRef->IsLocalAddrExpr() != nullptr)) ||
+                 ((tree->gtFlags & GTF_GLOB_REF) != 0));
 
     if (tree->AsField()->gtFldMayOverlap)
     {
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.cs b/src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.cs
new file mode 100644 (file)
index 0000000..9105afd
--- /dev/null
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Generated by Fuzzlyn v1.5 on 2022-03-09 14:59:40
+// Run on X64 Windows
+// Seed: 1682944285549106524
+// Reduced from 43.0 KiB to 0.5 KiB in 00:00:58
+// Debug: Outputs 0
+// Release: Outputs 255
+using System.Runtime.CompilerServices;
+
+public struct S0
+{
+    public bool F0;
+    public short F1;
+    public ushort F2;
+    public byte F4;
+    public sbyte F5;
+    public short F6;
+    
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    public int M6()
+    {
+        return (int)(Runtime_66414.s_3[0] ^ this.F5--);
+    }
+}
+
+public class Runtime_66414
+{
+    public static long[] s_3 = new long[]{0};
+    public static int Main()
+    {
+        var vr1 = new S0();
+        return M5(vr1) == 0 ? 100 : -1;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    public static int M5(S0 arg1)
+    {
+        arg1.F4 = (byte)(arg1.F5 - (uint)arg1.M6());
+        return arg1.F4;
+    }
+}
\ No newline at end of file
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_66414/Runtime_66414.csproj
new file mode 100644 (file)
index 0000000..f492aea
--- /dev/null
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>
\ No newline at end of file