Noticed in https://github.com/dotnet/coreclr/issues/27917#issuecomment-557519701 We can optimize some movs away for patterns like (byte)x | (byte)y with (byte)(x | y), etc.
For example:
static int Downcast(int a, int b)
{
return (byte)a | (byte)b;
}
static long Upcast(int a, int b)
{
return (long)a & (long)b; // not only "|"
}
Current codegen:
; Method Foo:Downcast(int,int):int
movzx rax, cl
movzx rdx, dl
or eax, edx
ret
; Method Foo:Upcast(int,int):long
movsxd rax, ecx
movsxd rdx, edx
and rax, rdx
ret
Expected codegen (from godbolt and linux abi)
; Method Foo:Downcast(int,int):int
or edi, esi
movzx eax, dil
ret
; Method Foo:Upcast(int,int):long
and edi, esi
movsxd rax, edi
ret
Should be a simple optimization, e.g.:
\--* OR int
+--* CAST int <- ubyte <- int
| \--* LCL_VAR int V00 arg0
\--* CAST int <- ubyte <- int
\--* LCL_VAR int V01 arg1
To:
\--* CAST int <- ubyte <- int
\--* OR int
+--* LCL_VAR int V00 arg0
\--* LCL_VAR int V01 arg1
Also, should work for pointers:
static unsafe int DowncastPtr(int a, int b)
{
return *((byte*)&a) | *((byte*)&b);
}
category:cq
theme:basic-cq
skill-level:beginner
cost:small
Noticed in https://github.com/dotnet/coreclr/issues/27917#issuecomment-557519701 We can optimize some movs away for patterns like
(byte)x | (byte)ywith(byte)(x | y), etc.For example:
Current codegen:
Expected codegen (from godbolt and linux abi)
Should be a simple optimization, e.g.:
To:
Also, should work for pointers:
category:cq
theme:basic-cq
skill-level:beginner
cost:small