Type check in shared generic doesn't eliminate casts to/from confirmed exact type (original) (raw)
From #49608 (review)
A type check e.g. if (typeof(T) == typeof(string))
in a shared generic doesn't eliminate casts to and from a confirmed exact type
using System; using System.Collections.Generic; using System.Runtime.CompilerServices;
public class HashSet { private IEqualityComparer? _comparer;
public HashSet(IEqualityComparer<T>? comparer)
{
if (comparer is not null && comparer != EqualityComparer<T>.Default)
{
_comparer = comparer;
}
if (typeof(T) == typeof(string))
{
// Double casts to concrete and back to generic not eliminated
_comparer = (IEqualityComparer<T>?)
NonRandomizedStringEqualityComparer.GetStringComparer(
(IEqualityComparer<string>?)_comparer);
}
}
}
public static class NonRandomizedStringEqualityComparer { [MethodImpl(MethodImplOptions.NoInlining)] public static IEqualityComparer? GetStringComparer(IEqualityComparer? comparer) { return comparer; } }
Data
Ideally the non Unsafe version:
if (typeof(T) == typeof(string)) { _comparer = (IEqualityComparer?)NonRandomizedStringEqualityComparer .GetStringComparer((IEqualityComparer?)_comparer); }
Would produce the same asm as the Unsafe version:
if (typeof(T) == typeof(string)) { _comparer = Unsafe.As<IEqualityComparer?>( NonRandomizedStringEqualityComparer.GetStringComparer( Unsafe.As<IEqualityComparer?>(_comparer))); }
However the regular casting includes a double cast even though its passed the typeof(TKey) == typeof(string)
guard which implies the casts will always succeed.
G_M17833_IG07: mov rcx, qword ptr [rsi] call [CORINFO_HELP_READYTORUN_GENERIC_HANDLE] cmp rax, qword ptr [(reloc)] jne SHORT G_M17833_IG09 ;; bbWeight=1 PerfScore 8.00 G_M17833_IG08:
mov rcx, qword ptr [rsi]
call [CORINFO_HELP_READYTORUN_GENERIC_HANDLE]
mov rdi, rax mov rcx, gword ptr [rsi+24]
call [CORINFO_HELP_READYTORUN_CHKCAST]
mov rcx, rax call [NonRandomizedStringEqualityComparer:GetStringComparer(IEqualityComparer`1):IEqualityComparer`1]
mov rdx, rax
mov rcx, rdi
call [CORINFO_HELP_CHKCASTANY] lea rcx, bword ptr [rsi+24] mov rdx, rax call [CORINFO_HELP_ASSIGN_REF]
;; bbWeight=0.50 PerfScore 10.38
;; bbWeight=0.50 PerfScore 4.38
G_M17833_IG09:
nop
;; bbWeight=1 PerfScore 0.25
category:cq
theme:generics
skill-level:expert
cost:medium
impact:small