dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.74k forks source link

ILCompiler produces wrong code for calli on x64 platform #109883

Open HolographicHat opened 3 hours ago

HolographicHat commented 3 hours ago

Description

In some cases, ilcompiler uses the eax register instead of the al register for the return value in the assembly code generated for the il code calli bool ().

Reproduction Steps

Clone this repo and run publish_and_run.cmd, the output should be

ILCompiler8
FalseBranch but bar is False
ILCompiler9
TrueBranch but bar is False

Expected behavior

// c#
var bar = ((delegate*<nint, bool>) foo)(114514);
if (bar) { /* do something */ }
// msil
// [17 9 - 17 57]
IL_0021: stloc.1      // V_1
IL_0022: ldc.i4       114514 // 0x0001bf52
IL_0027: conv.i
IL_0028: ldloc.1      // V_1
IL_0029: calli        bool (native int)
IL_002e: stloc.0      // bar

// [18 9 - 18 17]
IL_002f: ldloc.0      // bar
IL_0030: brfalse.s    IL_005d
; assembly
mov     ecx, 1BF52h
call    rax
movzx   ebx, al
test    ebx, ebx    ; or test al, al
jz      short loc_1400C2082

Actual behavior

c#: same as above

msil: same as above

; assembly
mov     ecx, 1BF52h
call    rbx
mov     esi, eax    ; wrong
test    esi, esi
jnz     short loc_140044108

Regression?

works fine in 8.0.11, errors in 9.0.0-preview.1.24080.9

Known Workarounds

No response

Configuration

.NET Version: 9.0.100 OS: Windows 10.0.19045 Architecture: x64

Other information

No response

dotnet-policy-service[bot] commented 3 hours ago

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.