This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
avoidance of lea after 5 operations?
- From: "Jason A. Donenfeld" <Jason at zx2c4 dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 11 Oct 2018 18:07:22 +0200
- Subject: avoidance of lea after 5 operations?
Hey GCConauts,
I've noticed some strange behavior in gcc > 5.
unsigned int hmmm5(unsigned int a, unsigned int b, unsigned int c)
{
return a + (b << c << c << c << c << c);
}
This function compiles how you'd expect:
mov ecx, edx
sal esi, cl
sal esi, cl
sal esi, cl
sal esi, cl
sal esi, cl
lea eax, [rsi+rdi]
ret
However, when performing more than 5 shifts, gcc switches to using add
instead of lea, which then generates an extra mov instruction:
unsigned int hmmm6(unsigned int a, unsigned int b, unsigned int c)
{
return a + (b << c << c << c << c << c << c);
}
Producing:
mov ecx, edx
mov eax, esi
sal eax, cl
sal eax, cl
sal eax, cl
sal eax, cl
sal eax, cl
sal eax, cl
add eax, edi
ret
Thinking this might be a side effect of avoid_lea_for_addr, I tried
setting '-mtune-ctrl=^avoid_lea_for_addr', but to no avail.
I also couldn't find anything in various documentation and instruction
tables regarding the latencies or scheduling of these functions that
would imply switching to add after 5 operations is somehow better.
I realize this is probably a fairly trivial matter, but I am very
curious if somebody knows which heuristic gcc is applying here, and
why exactly. It's not something done by any other compiler I could
find, and it only started happening with gcc 6.
Regards,
Jason