This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/17236] inefficient code for long long multiply on x86
- From: "bonzini at gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 18 Dec 2007 07:43:16 -0000
- Subject: [Bug rtl-optimization/17236] inefficient code for long long multiply on x86
- References: <bug-17236-1008@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #7 from bonzini at gnu dot org 2007-12-18 07:43 -------
The generated code has changed a lot recently, though it still uses two spills:
pushl %esi
pushl %ebx
movl 12(%esp), %ebx ; load alow
movl 20(%esp), %esi ; load blow
movl 24(%esp), %ecx ; load bhigh
imull %ebx, %ecx ; bhigh = bhigh * alow
movl 16(%esp), %eax ; load ahigh
imull %esi, %eax ; ahigh = ahigh * blow
addl %eax, %ecx
movl %esi, %eax ; need to move a low part in %eax
mull %ebx
leal (%ecx,%edx), %esi ; what the heck, a simple addl could do!
movl %esi, %edx
popl %ebx
popl %esi
The important thing is that the adds are one before, and one after the
multiply. And the RTL before reload is very nice!
28 r64:SI=[argp:SI]
30 r66:SI=[argp:SI+0x8]
7 {r62:SI=[argp:SI+0xc]*r64:SI;clobber flags:CC;}
8 {r63:SI=[argp:SI+0x4]*r66:SI;clobber flags:CC;}
9 {r62:SI=r62:SI+r63:SI;clobber flags:CC;}
10 {r61:DI=zero_extend(r66:SI)*zero_extend(r64:SI);clobber flags:CC;}
12 {r61:DI#4=r62:SI+r61:DI#4;clobber flags:CC;}
That could be basically
mov (blow), %eax
mov (alow), %ecx
imul (bhigh), %eax, %ebx ;needs reload of (bh) in %ebx
imul (ahigh), %ecx, %edx ;needs reload of (ah) in %edx
addl %edx, %ebx
mul %ecx
addl %ebx, %edx
So, if we are content with a single spill, there is now mainly a register
allocation problem. For zero spills, we would need rematerialization of either
alow or blow, as in:
mov (blow), %eax
imul (bhigh), %eax, %ecx ;needs reload of (bh) in %ecx
imul (ahigh), (alow), %edx ;needs reload of (ah) in %edx
addl %edx, %ecx
mul (al)
addl %ebx, %edx
So, for now let's aim at having one spill. Then the main problem is that gcc
should try to keep one of alow or blow in %eax, in order to reuse it for the
mull. Then it could do with a single spill, like this:
pushl %ebx
movl 12(%esp), %eax ; load alow
movl 20(%esp), %ecx ; load blow
movl 24(%esp), %ebx ; load bhigh, input reload
imull %eax, %ebx
movl 16(%esp), %edx ; load ahigh, input reload
imull %ecx, %edx
addl %edx, %ebx
mul %ecx
addl %ebx, %edx
popl %ebx
--
bonzini at gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |bonzini at gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17236