Perf improvements to Span and Memory by GrabYourPitchforks · Pull Request #20771 · dotnet/coreclr (original) (raw)
return condition ? false : true
emits a branch
G_M61453_IG01:
G_M61453_IG02: 8BC7 mov eax, edi 8BFE mov edi, esi 4803C7 add rax, rdi 8BFA mov edi, edx 483BC7 cmp rax, rdi 7706 ja SHORT G_M61453_IG04 B801000000 mov eax, 1
G_M61453_IG03: C3 ret
G_M61453_IG04: 33C0 xor eax, eax
G_M61453_IG05: C3 ret
When written as just return cond
the "setb al / movzx eax, al" is generated.
G_M61452_IG01:
G_M61452_IG02: 8BC7 mov eax, edi 8BFE mov edi, esi 4803C7 add rax, rdi 8BFA mov edi, edx 483BC7 cmp rax, rdi 0F96C0 setbe al 0FB6C0 movzx rax, al
G_M61452_IG03: C3 ret
But when this methods gets inlined, this patterns vanishes. Trivial example:
internal static bool IsRangeInBounds(int offset, int length, int availableLength) { return (ulong)(uint)offset + (ulong)(uint)length <= (ulong)(uint)availableLength; }
[MethodImpl(MethodImplOptions.NoInlining)] private static int Foo(int offset, int len, int availLen) { if (!IsRangeInBounds(offset, len, availLen)) Throw();
return availLen - (offset + len);
void Throw() => throw new Exception();
}
generates
G_M7900_IG01: 50 push rax
G_M7900_IG02: 8BC7 mov eax, edi 8BCE mov ecx, esi 4803C1 add rax, rcx 8BCA mov ecx, edx 483BC1 cmp rax, rcx 770B ja SHORT G_M7900_IG05
G_M7900_IG03: 03FE add edi, esi 8BC2 mov eax, edx 2BC7 sub eax, edi
G_M7900_IG04: 4883C408 add rsp, 8 C3 ret
G_M7900_IG05: E869F9FFFF call Program:g__Throw|7_0() CC int3