Description
Given simple benchmark code
usingBenchmarkDotNet.Attributes;[DisassemblyDiagnoser]publicclassEnumTest{readonlyList<string>list=["hello","world","foo","bar"];[Benchmark]publicstringLast()=>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:
| sourceisIterator<TSource>iterator?iterator.TryGetLast(outfound): |
This results in the following codegen:
; Benchmarks.EnumTest.Last()pushrbxsubrsp,30movrbx,[rcx+8]testrbx,rbxje short M00_L03movrdx,rbxmovrcx,offset MT_System.Linq.Enumerable+Iterator`1[[System.String, System.Private.CoreLib]]call qword ptr [7FFE83476910]; System.Runtime.CompilerServices.CastHelpers.IsInstanceOfClass(Void*, System.Object)testrax,raxjne short M00_L01lear8,[rsp+28]movrdx,rbxmovrcx,7FFE838AFB20call qword ptr [7FFE8382D980]M00_L00:cmp byte ptr [rsp+28],0je short M00_L02addrsp,30poprbxretM00_L01:leardx,[rsp+28]movrcx,raxmovrax,[rax]movrax,[rax+48]call qword ptr [rax+18]jmp short M00_L00M00_L02:call qword ptr [7FFE8382CD38]int3M00_L03:movecx,11call qword ptr [7FFE8347F7B0]int3; Total bytes of code 114
While the expected codegen would probably look like:
; Benchmarks.EnumTest.Last()pushrbxsubrsp,30movrbx,[rcx+8]testrbx,rbxje short M00_L02lear8,[rsp+28]movrdx,rbxmovrcx,7FFE838AFB20call qword ptr [7FFE8382D980] ;; TryGetLastNonIteratorM00_L00:cmp byte ptr [rsp+28],0je short M00_L01addrsp,30poprbxretM00_L01:call qword ptr [7FFE8382CD38]int3M00_L02:movecx,11call qword ptr [7FFE8347F7B0]int3
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