Description
Given simple benchmark code
using BenchmarkDotNet.Attributes;
[DisassemblyDiagnoser]
public class EnumTest {
readonly List<string> list = ["hello", "world", "foo", "bar"];
[Benchmark]
public string Last() => list.Last();
}
It appears that both Last() and TryGetLast() that it calls out to get inlined which is good.
However, the type test of List<string> is Iterator<string> does not get optimized away even though it can never succeed:
|
source is Iterator<TSource> iterator ? iterator.TryGetLast(out found) : |
This results in the following codegen:
; Benchmarks.EnumTest.Last()
push rbx
sub rsp,30
mov rbx,[rcx+8]
test rbx,rbx
je short M00_L03
mov rdx,rbx
mov rcx,offset MT_System.Linq.Enumerable+Iterator`1[[System.String, System.Private.CoreLib]]
call qword ptr [7FFE83476910]; System.Runtime.CompilerServices.CastHelpers.IsInstanceOfClass(Void*, System.Object)
test rax,rax
jne short M00_L01
lea r8,[rsp+28]
mov rdx,rbx
mov rcx,7FFE838AFB20
call qword ptr [7FFE8382D980]
M00_L00:
cmp byte ptr [rsp+28],0
je short M00_L02
add rsp,30
pop rbx
ret
M00_L01:
lea rdx,[rsp+28]
mov rcx,rax
mov rax,[rax]
mov rax,[rax+48]
call qword ptr [rax+18]
jmp short M00_L00
M00_L02:
call qword ptr [7FFE8382CD38]
int 3
M00_L03:
mov ecx,11
call qword ptr [7FFE8347F7B0]
int 3
; Total bytes of code 114
While the expected codegen would probably look like:
; Benchmarks.EnumTest.Last()
push rbx
sub rsp,30
mov rbx,[rcx+8]
test rbx,rbx
je short M00_L02
lea r8,[rsp+28]
mov rdx,rbx
mov rcx,7FFE838AFB20
call qword ptr [7FFE8382D980] ;; TryGetLastNonIterator
M00_L00:
cmp byte ptr [rsp+28],0
je short M00_L01
add rsp,30
pop rbx
ret
M00_L01:
call qword ptr [7FFE8382CD38]
int 3
M00_L02:
mov ecx,11
call qword ptr [7FFE8347F7B0]
int 3
Configuration
.NET SDK:
Version: 9.0.100-rc.2.24423.15
Commit: 6bf8f98ca5
Workload version: 9.0.100-manifests.c7b42424
MSBuild version: 17.12.0-preview-24422-01+314cf24ea
Runtime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.100-rc.2.24423.15\
Regression?
No
Description
Given simple benchmark code
It appears that both
Last()andTryGetLast()that it calls out to get inlined which is good.However, the type test of
List<string> is Iterator<string>does not get optimized away even though it can never succeed:runtime/src/libraries/System.Linq/src/System/Linq/Last.cs
Line 73 in b579962
This results in the following codegen:
While the expected codegen would probably look like:
Configuration
Regression?
No