dotnet / dotnet/runtime

JIT: Strip out masking of shiftAmount way earlier when possible

Open
#126,799 3 comments 1 reaction 1 assignee Assigned to @Copilot View on GitHub
area-CodeGen-coreclr
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

When we write `foo >> shift` it gets imported as:
```
\--* RSZ int
+--* LCL_VAR int V01 arg1
\--* AND int
+--* LCL_VAR int V02 arg2
\--* CNS_INT int 31
```
Notice the masking by 31. Some architectures already perform this masking so we currently try to remove it in `LowerShift`:
https://github.com/dotnet/runtime/blob/e583c98763e224e5d6587a9d8fc732a33b1d808b/src/coreclr/jit/lower.cpp#L8809-L8828

Removing the mask way earlier like in import could save some tp and also handle more cases.
For example here the `(shift & 31)` got CSEd which causes the aforementioned opt to no longer recognize it, because its literally looking for `foo >> (shift & 31)`, whereas we end up with `foo >> cse0` where `cse0 = (shift & 31)`.
```cs
uint ShiftAndCSE(uint foo, int shift)
{
uint res = (foo >> shift);
res <<= shift;

return res;
}
```
```assembly
G_M46394_IG02: ;; offset=0x0000
and r8d, 31 ; <- currently not removed
shrx eax, edx, r8d
shlx eax, eax, r8d
```

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.