-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unsafe.As breaks callvirt after inlining in .NET 8 RC2 #93650
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionIf a call to Reproduction StepsBad codegen sample: https://godbolt.org/z/YEoYM7xY5 Minimal repro: using System.Runtime.CompilerServices;
using System.Text;
internal static class Program
{
static void Main()
{
var sb = new Holder();
while (true)
{
var s = Bind(ref sb);
if (s.Length != 0)
{
Console.WriteLine("StringBuilder.ToString() returned: " + s);
return;
}
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static string Bind(ref Holder parameters) => GetString(parameters.GetBuilder());
public static string GetString(StringBuilder sb) => sb.ToString();
}
internal struct Holder
{
internal StringBuilder.AppendInterpolatedStringHandler _h;
public Holder() => _h = new(0, 0, new());
internal StringBuilder GetBuilder() => Unsafe.As<StringBuilder.AppendInterpolatedStringHandler, StringBuilder>(ref _h);
} Expected behavior
; Assembly listing for method Program:Bind(byref):System.String (Tier1)
; Emitting BLENDED_CODE for X64 with AVX - Windows
; Tier1 code
; optimized code
; rsp based frame
; partially interruptible
; 0 inlinees with PGO data; 1 single block inlinees; 0 inlinees without PGO data
G_M000_IG01: ;; offset=0x0000
sub rsp, 40
G_M000_IG02: ;; offset=0x0004
mov rcx, gword ptr [rcx]
cmp dword ptr [rcx], ecx
call [System.Text.StringBuilder:ToString():System.String:this]
nop
G_M000_IG03: ;; offset=0x0010
add rsp, 40
ret Actual behavior
; Assembly listing for method Program:Bind(byref):System.String (Tier1)
; Emitting BLENDED_CODE for X64 with AVX - Windows
; Tier1 code
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; 1 inlinees with PGO data; 3 single block inlinees; 0 inlinees without PGO data
G_M000_IG01: ;; offset=0x0000
sub rsp, 40
G_M000_IG02: ;; offset=0x0004
mov rcx, gword ptr [rcx]
cmp byte ptr [rcx], cl
call System.Object:GetType():System.Type:this
mov rcx, rax
mov edx, 1
call [System.RuntimeType:GetCachedName(int):System.String:this]
nop
G_M000_IG03: ;; offset=0x001D
add rsp, 40
ret Regression?This worked correctly in .NET 7 Known WorkaroundsNo response Configuration.NET 8.0.100-rc.2.23502.2, Windows x64 Other informationNo response
|
The bug is that There is an ambiguity when querying field classes for The proposed fix is to not return anything for not- diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index 81b6bbdc85c..0009c9045aa 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -18716,9 +18716,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldH
JITDUMP("Field's current class not available\n");
}
}
+
+ return fieldClass;
}
- return fieldClass;
+ return NO_CLASS_HANDLE;
} |
Thanks to @SingleAccretion for the fix. The JIT was assuming that an indirectly accessed value type field had the type of the field, but that might not be the case if the field was accessed via `Unsafe.As`. Fix this by limiting type deduction from these indirectly accessed fields to only ref type fields. Closes dotnet#93650.
Thanks to @SingleAccretion for the fix. The JIT was assuming that an indirectly accessed value type field had the type of the field, but that might not be the case if the field was accessed via `Unsafe.As`. Fix this by limiting type deduction from these indirectly accessed fields to only ref type fields. Closes #93650.
Thanks to @SingleAccretion for the fix. The JIT was assuming that an indirectly accessed value type field had the type of the field, but that might not be the case if the field was accessed via `Unsafe.As`. Fix this by limiting type deduction from these indirectly accessed fields to only ref type fields. Closes #93650.
Thanks to @SingleAccretion for the fix. The JIT was assuming that an indirectly accessed value type field had the type of the field, but that might not be the case if the field was accessed via `Unsafe.As`. Fix this by limiting type deduction from these indirectly accessed fields to only ref type fields. Closes #93650. Co-authored-by: Andy Ayers <[email protected]>
Description
If a call to
Unsafe.As<A, B>()
and another call that uses the result (e.g.,ToString()
) are inlined by JIT, it results in bad codegen. If inlined manually, codegen is correct.Reproduction Steps
Bad codegen sample: https://godbolt.org/z/YEoYM7xY5
Minimal repro:
Expected behavior
StringBuilder:ToString()
is called (asm listing after manually inlining GetString):Actual behavior
Object:ToString()
is inlined instead:Regression?
This worked correctly in .NET 7
Known Workarounds
No response
Configuration
.NET 8.0.100-rc.2.23502.2, Windows x64
Other information
No response
The text was updated successfully, but these errors were encountered: