-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Switches with intrinsic const aren't getting optimized #78356
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsConsider: [MethodImpl(MethodImplOptions.NoInlining)]
private static int Test<TEnum>()
{
TypeCode code = Type.GetTypeCode(typeof(TEnum));
switch (code)
{
case TypeCode.Int32:
return 100;
case TypeCode.Int64:
return 200;
default:
return 300;
}
} called with ; Assembly listing for method ConsoleApp4.Program:Test[int]():int
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
; 0 inlinees with PGO data; 0 single block inlinees; 2 inlinees without PGO data
G_M000_IG01: ;; offset=0000H
G_M000_IG02: ;; offset=0000H
B809000000 mov eax, 9
83F809 cmp eax, 9
7407 je SHORT G_M000_IG04
G_M000_IG03: ;; offset=000AH
83F80B cmp eax, 11
7408 je SHORT G_M000_IG06
EB0C jmp SHORT G_M000_IG08
G_M000_IG04: ;; offset=0011H
B864000000 mov eax, 100
G_M000_IG05: ;; offset=0016H
C3 ret
G_M000_IG06: ;; offset=0017H
B8C8000000 mov eax, 200
G_M000_IG07: ;; offset=001CH
C3 ret
G_M000_IG08: ;; offset=001DH
B82C010000 mov eax, 300
G_M000_IG09: ;; offset=0022H
C3 ret
; Total bytes of code 35 so even though the ; Assembly listing for method ConsoleApp4.Program:Test[int]():int
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; optimized code
; rsp based frame
; partially interruptible
; No PGO data
G_M000_IG01: ;; offset=0000H
G_M000_IG02: ;; offset=0000H
B864000000 mov eax, 100
G_M000_IG03: ;; offset=0005H
C3 ret
; Total bytes of code 6
|
You should see it getting optimized if you switch on [MethodImpl(MethodImplOptions.NoInlining)]
private static int Test<TEnum>()
{
Type type = typeof(TEnum).GetEnumUnderlyingType();
if (type == typeof(int))
return 100;
if (type == typeof(long))
return 200;
return 300;
} |
I do, which is my local workaround. |
I think that switching on GetEnumUnderlyingType is the right forward-looking way to write this. We have been saying that IConvertible and TypeCode are legacy concepts. |
Ok. Though I still think outputting the code: B809000000 mov eax, 9
83F809 cmp eax, 9 is suspect :) |
Yes, it would be nice to optimize this better. The problem is not specific to intrinsics. Any switch over constant expression that is complex-enough will hit this problem. For example:
generates
|
Both Stephen's and Jan's examples are now folded to |
Consider:
called with
Test<DayOfWeek>
. The optimized code for this ends up being:so even though the
Type.GetTypeCode(typeof(TEnum))
is turned intomov eax, 9
, the whole switch is still implemented (thatmov eax, 9
followed by acmp eax, 9
is particularly fun). If I instead replace theType.GetTypeCode(typeof(TEnum))
withTypeCode.Int32
, then I do get the expected:The text was updated successfully, but these errors were encountered: