-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array variance checks are not optimized away for types known to be not arrays #97000
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionIt appears that array variance checks against e.g. Configuration.NET 8.0.100 Regression?No AnalysisGiven below pattern static bool Foo(List<int> l)
{
return (object)l is int[];
} The produced asm is G_M39343_IG01: ;; offset=0x0000
push rax
G_M39343_IG02: ;; offset=0x0001
mov rsi, rdi
mov rdi, 0x7FDDF17D91D0 ; int[]
call [CORINFO_HELP_ISINSTANCEOFARRAY]
test rax, rax
setne al
movzx rax, al
G_M39343_IG03: ;; offset=0x001D
add rsp, 8
ret instead of xor rax, rax
ret Should this pattern get optimized, this will allow to update e.g.
|
I was using this as a repro: internal class Program
{
private static void Main(string[] args)
{
Test(new List<int>());
}
[MethodImpl(MethodImplOptions.NoInlining)]
static bool Test(List<int> x) => Foo(x);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static bool Foo<TSource>(IEnumerable<TSource> x) => x is TSource[];
} |
Folding `x isinst B` where `x` is statically of type `A` is currently done via a call to `compareTypesForCast`. If it returns `TypeCompareState::Must` then we know that `A` can be cast to `B`, which also means any class derived from `A` can be cast to `B`, so we can always fold that. However, if it returns `TypeCompareState::MustNot` we only learn something if we know `x` is exactly `A`; otherwise, if `x` is more derived than `A`, it could still potentially be cast to `B`. In cases where the type hierarchies are distinct, however, we can still know that some type checks will fail. To detect the case add a query in the opposite direction; that is, if `B` cannot be cast to `A`, then the type hierarchies are distinct, so in that case we can fold it, regardless of having exact knowledge. This also requires some explicit checks for interface types, but perhaps we can move those to the EE side. Fix dotnet#97000
The diffs were very minor. Doesn't seem worth the TP cost. |
Description
It appears that array variance checks against e.g.
List<T>
are not optimized away for patterns like(obj)list is int[]
.Configuration
.NET 8.0.100
Regression?
No
Analysis
Given below pattern
The produced asm is
instead of
Should this pattern get optimized, this will allow to update e.g.
Enumerable.SequenceEquals
in such a way that type tests are optimized away and it directly forwards toCollectionsMarshal.AsSpan(list).SequenceEquals(...)
.The text was updated successfully, but these errors were encountered: