-
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
Eliminate bound checks for "arr[index % arr.Length]" #84231
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak Issue DetailsCloses #9421 Example: int Bucket(int[] buckets, int hashcode) => buckets[hashcode % buckets.Length]; Codegen diff: ; Method Bucket(int[],int):int:this
G_M35976_IG01:
- 4883EC28 sub rsp, 40
488BCA mov rcx, rdx
G_M35976_IG02:
448B4908 mov r9d, dword ptr [rcx+08H]
418BC0 mov eax, r8d
99 cdq
41F7F9 idiv edx:eax, r9d
- 413BD1 cmp edx, r9d
- 730B jae SHORT G_M35976_IG04
8BC2 mov eax, edx
8B448110 mov eax, dword ptr [rcx+4*rax+10H]
G_M35976_IG03:
- 4883C428 add rsp, 40
C3 ret
-G_M35976_IG04:
- E8C962525F call CORINFO_HELP_RNGCHKFAIL
- CC int3
-; Total bytes of code: 40
+; Total bytes of code: 21
|
@dotnet/jit-contrib @SingleAccretion @jakobbotsch PTAL - this pattern used to be popular but then we replaced it with Lemire's FastMod in most places, but it's still used here and there (my changes in BCL obviosly didn't make it to SPMI diffs) The PR does two things:
|
@AndyAyersMS PTAL since you reviewed my previous "eliminate bound checks" PR |
wasm failures are #80619 |
There are a fair number of places we use FastMod instead of % to index into an array. The former was strictly better, but now the latter avoids the bounds check the former still incurs. Does this change the equation, or is the former still better enough even with the extra check? |
I believe that one is still better since it avoids expensive idiv instruction (not that expensive on modern cpus though). E.g. it makes sense to use FastMod even in C++ code - #65926 |
Right, but there neither thing being compared has an extra cmp/branch, whereas now the FastMod one in .NET does but % doesn't. |
I'd be surprised to see FastMod slower 🙂 |
Closes #9421
Example:
Codegen diff:
As was mentioned in the issue, this only works for XARCH since on ARM we always expand
a % b
early in Morph toa - (a / b) * b
. Will be fixed if we move that transformation to lower.PS: Index has to be something non-negative, e.g. a constant or unsigned type, etc.