dotnet / dotnet/runtime

JIT: Optimize some bitwise ops in context of enum flags

Open
#125,899 2 comments 0 reactions 0 assignees View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/cT46Tn5TE

https://github.com/dotnet/runtime/blob/f416dc4f97c836c6b91617e9c1857a752072b5e2/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.netstandard.cs#L114-L130

For the above method we generate (with #124738):
```asm
G_M38219_IG02: ;; offset=0x0000
mov eax, edx
and eax, 1
mov ecx, eax
or ecx, 256
test edx, 256
cmovne eax, ecx
mov ecx, eax
or ecx, 0x8000
test edx, 0x8000
cmovne eax, ecx
mov ecx, eax
or ecx, 0x4000
test edx, 0x4000
cmovne eax, ecx
;; size=56 bbWeight=1 PerfScore 3.50
G_M38219_IG03: ;; offset=0x0038
ret
```
While clang/gcc generate:
```asm
GetAssemblyNameFlags(int):
mov eax, edi
and eax, 49409
ret
```

We are missing 2 things.
First, we need to transform this if-version:
```cs
if ((flags & 256) != 0)
{
assemblyNameFlags |= 256;
}
```
into the simpler equivalent: `assemblyNameFlags |= flags & 256`

Second, when we end up with a bunch of these, e.g:
```cs
assemblyNameFlags |= flags & 256;
assemblyNameFlags |= flags & 512;
```
we need to merge them into one: `assemblyNameFlags |= flags & (256 | 512);`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.