Skip to content

Type test List<T> is Iterator<T> that can never succeed is not optimized away #106966

Description

@neon-sunset

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

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMItenet-performancePerformance related issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions