Native Disassembly only shows first basic block
I rather like the Native Disassembly feature in LINQPad and use it often to compare implementations. However it seems to be broken I think in the latest version, because only the first basicblock is shown. For example:
ref T ElementAt(T[] array, int offset)
=> ref array[offset];
Above code generates the following. At line L0008 it refers to label L0017 but that code is not visible anymore. (It used to show: int 3)
L0000 sub rsp, 0x28
L0004 cmp r8d, [rdx+8]
L0008 jae short L0017
L000a mov eax, r8d
L000d lea rax, [rdx+rax*4+0x10]
L0012 add rsp, 0x28
L0016 ret
Does anyone know a workaround? (Other than going back to a previous version of LINQPad)
Comments
-
8.8.6
(latest beta), the same:ref T ElementAt<T>(T[] array, int offset) => ref array[offset];
L0000 sub rsp, 0x28 L0004 cmp r8d, [rdx+8] L0008 jae short L0017 L000a mov eax, r8d L000d lea rax, [rdx+rax*4+0x10] L0012 add rsp, 0x28 L0016 ret
-
Can you provide a full repro? I've tried running a fresh install of LINQPad 8.8.6 (Windows Sandbox) with the following script:
void Main() { } ref T ElementAt<T>(T[] array, int offset) => ref array[offset];
This is the X64 shown:
ElementAt<T> (T[], Int32) L0000 push rbp L0001 push rdi L0002 sub rsp, 0x28 L0006 lea rbp, [rsp+0x30] L000b mov [rbp+0x10], rcx L000f mov [rbp+0x18], rdx L0013 mov [rbp+0x20], r8d L0017 cmp dword ptr [0x7ffbdfdac258], 0 L001e je short L0025 L0020 call 0x00007ffc3e863390 L0025 mov rax, [rbp+0x18] L0029 mov ecx, [rbp+0x20] L002c cmp ecx, [rax+8] L002f jb short L0036 L0031 call 0x00007ffbdeb11728 L0036 mov edx, ecx L0038 lea rax, [rax+rdx*4+0x10] L003d add rsp, 0x28 L0041 pop rdi L0042 pop rbp L0043 ret
-
Here is a full example. A clue might be that on my work-pc it works okay if I select .NET 8, but only shows the first basic block when .NET 9 is selected.
LINQPad version: 8.7.4 (X64)
Host runtime version: 8.0.12
Default query runtime version: 9.0.1
Default query reference assembly version: 9.0.1
Roslyn Version: 4.12.0-3.24572.7
FSharp.Compiler.Service version: 43.8.101.0
NuGet client version: 6.7.1.1void Main() { var myArray = new int[10]; ref var a = ref ElementAt(myArray, 5); a = 5; myArray.Dump(); } ref T ElementAt<T>(T[] array, int offset) => ref array[offset];
This outputs with /o+:
X64
Main ()L0000 sub rsp, 0x28 L0004 mov rcx, 0x7ffa29498aa8 L000e mov edx, 0xa L0013 call 0x00007ffa88fb7a40 L0018 mov dword ptr [rax+0x24], 5 L001f mov rdx, rax L0022 mov rcx, 0x7ffa2a02f040 L002c call qword ptr [0x7ffa2a0441f8] L0032 nop L0033 add rsp, 0x28 L0037 ret
ElementAt (T[], Int32)
L0000 sub rsp, 0x28 L0004 cmp r8d, [rdx+8] L0008 jae short L0017 L000a mov eax, r8d L000d lea rax, [rdx+rax*4+0x10] L0012 add rsp, 0x28 L0016 ret
-
Code generated is the same for .NET 8/9
-
Thanks. I'll dig into this some time next week.
-
The truncated output is caused by a workaround for a ClrMD bug which appears now to be fixed.
I've removed the workaround in 8.8.8. Let me know how you get along.