-
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
JIT: inconsistent CQ for div/mod by power of 2 idioms #11442
Comments
Although for the modulo a bit-operation ( private static int Div32Rem(int number, out int remainder)
{
int quotient = number >> 5; // Divide by 32.
remainder = number & 31; // Modulo 32
return quotient;
} as it's faster. PS: I assume you are absolutely aware of this, but just that this is noted 😉 |
Yep, the JIT already does that for unsigned modulo. And it's worth mentioning that it's faster:
Not only that it's one operation less but it's also independent from the quotient computation so it can be done in parallel. |
@dotnet/jit-contrib |
I may be missing something, but does that mean that these should produce the same code? public static uint X(uint i)
{
return (uint)(i % ((long)uint.MaxValue + 1));
}
public static uint X2(uint i)
{
return (uint)(i % 0x1_0000_0000L);
}
public static uint Y(uint i)
{
return (uint)i & uint.MaxValue;
} I get XX.X(UInt32)
L0000: push ebp
L0001: mov ebp, esp
L0003: sub esp, 8
L0006: push 0
L0008: push ecx
L0009: push 1
L000b: push 0
L000d: call 0x72042250
L0012: mov [ebp-8], eax
L0015: mov [ebp-4], edx
L0018: mov eax, [ebp-8]
L001b: mov esp, ebp
L001d: pop ebp
L001e: ret
XX.X2(UInt32)
L0000: push ebp
L0001: mov ebp, esp
L0003: sub esp, 8
L0006: push 0
L0008: push ecx
L0009: push 1
L000b: push 0
L000d: call 0x72042250
L0012: mov [ebp-8], eax
L0015: mov [ebp-4], edx
L0018: mov eax, [ebp-8]
L001b: mov esp, ebp
L001d: pop ebp
L001e: ret
XX.Y(UInt32)
L0000: mov eax, ecx
L0002: and eax, 0xffffffff
L0005: ret Is that covered by this issue? edit: I guess 32 bit only. maybe it's low priority then. |
Conerning this example: public int DivAndMod()
{
for (int i = 0; i < N; i++)
{
data[i / 32] |= (1 << (i % 32));
}
return data[N - 1];
} This could actually do the |
Related: #12218 |
From dotnet/corefx#33367:
Could be that these aren't exactly equivalent for negative values. But here
i
is non-negative.category:cq
theme:basic-cq
skill-level:intermediate
cost:small
impact:small
The text was updated successfully, but these errors were encountered: