public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant
@ 2011-03-11 16:41 wschmidt at gcc dot gnu.org
  2011-03-11 17:11 ` [Bug rtl-optimization/48077] " pinskia at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: wschmidt at gcc dot gnu.org @ 2011-03-11 16:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

           Summary: [Code Improvement] Use multiplication by magic number
                    for integer division by constant
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: wschmidt@gcc.gnu.org
                CC: bergner@gcc.gnu.org, pthaugen@gcc.gnu.org,
                    meissner@gcc.gnu.org, dje.gcc@gmail.com,
                    wschmidt@gcc.gnu.org
            Target: powerpc64-linux, others


We noticed a significant performance difference between gcc and xlc at all
optimization levels for a small application that repeatedly takes a value
modulo an integer constant.  Gcc expands division by a constant into a sequence
of shifts, adds, and subtracts.  Xlc converts division by a constant into
multiplication by a corresponding magic number.  See H.S. Warren's _Hacker's
Delight_ for details.  See http://www.hackersdelight.org/magic.htm for a magic
number calculator.

A small test case shows the difference:

-----------------------------------------
int *values;
int *hash_table;

int demonstrate (int i)
{
  return hash_table [values [i] % 1000];
}
-----------------------------------------

On powerpc64-linux, xlc -c -S -O3 -q32 test.c produces:

demonstrate:
    addis      r4,r0,values@ha
    rlwinm     r3,r3,2,0,29
    addis      r6,r0,hash_table@ha
    addis      r5,r0,4194
    addi       r0,r5,19923
    lwz        r4,values@l(r4)
    lwz        r5,hash_table@l(r6)
    lwzx       r3,r4,r3
    rlwinm     r4,r3,1,31,31
    mulhw      r0,r3,r0
    srawi      r0,r0,6
    add        r6,r0,r4
    rlwinm     r0,r6,10,0,21
    rlwinm     r4,r6,5,0,26
    subf       r0,r4,r0
    rlwinm     r6,r6,3,0,28
    add        r4,r0,r6
    subf       r0,r4,r3
    rlwinm     r3,r0,2,0,29
    lwzx       r3,r5,r3
    bclr       BO_ALWAYS,CR0_LT

Note the multiply by 274877907, built by:

    addis      r5,r0,4194
    addi       r0,r5,19923

If you plug 1000 into the magic number calculator at the website above, that's
the magic number produced.

By contrast, gcc -c -S -O3 -m32 test.c produces:

.L.demonstrate:
    addis 9,2,.LC0@toc@ha
    ld 9,.LC0@toc@l(9)
    sldi 3,3,2
    addis 11,2,.LC1@toc@ha
    ld 9,0(9)
    ld 10,.LC1@toc@l(11)
    lwzx 9,9,3
    extsw 0,9
    sldi 8,0,7
    sldi 11,0,9
    add 11,8,11
    subf 11,0,11
    sldi 11,11,3
    add 11,11,0
    sldi 8,11,2
    add 11,11,8
    sldi 11,11,2
    add 11,11,0
    sldi 11,11,3
    add 11,11,0
    sldi 8,11,3
    subf 11,11,8
    sldi 11,11,4
    add 0,11,0
    sldi 11,0,2
    subf 0,0,11
    srdi 0,0,32
    srawi 11,9,31
    srawi 0,0,6
    subf 0,11,0
    slwi 8,0,7
    slwi 11,0,2
    subf 11,11,8
    add 0,11,0
    ld 11,0(10)
    slwi 0,0,3
    subf 9,0,9
    extsw 9,9
    sldi 9,9,2
    lwax 3,11,9
    blr

Note the long string of dependencies in the gcc code; not only is the code
quite a bit larger, but there is very little ILP.

Consider converting integer division to multiplication by a magic number when
appropriate for the target machine.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug rtl-optimization/48077] [Code Improvement] Use multiplication by magic number for integer division by constant
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
@ 2011-03-11 17:11 ` pinskia at gcc dot gnu.org
  2011-03-11 18:34 ` wschmidt at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu.org @ 2011-03-11 17:11 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> 2011-03-11 17:11:25 UTC ---
Actually GCC is expanding the division by a constant into a multiplication but
using shifts and adds to do the multiplication based on the cost.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug rtl-optimization/48077] [Code Improvement] Use multiplication by magic number for integer division by constant
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
  2011-03-11 17:11 ` [Bug rtl-optimization/48077] " pinskia at gcc dot gnu.org
@ 2011-03-11 18:34 ` wschmidt at gcc dot gnu.org
  2011-03-11 19:22 ` [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux wschmidt at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: wschmidt at gcc dot gnu.org @ 2011-03-11 18:34 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

--- Comment #2 from William J. Schmidt <wschmidt at gcc dot gnu.org> 2011-03-11 18:34:41 UTC ---
OK, interesting, thanks for the information.  It seems the analysis of the cost
is not particularly good here.  I'll dig into where the expansion is occurring.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
  2011-03-11 17:11 ` [Bug rtl-optimization/48077] " pinskia at gcc dot gnu.org
  2011-03-11 18:34 ` wschmidt at gcc dot gnu.org
@ 2011-03-11 19:22 ` wschmidt at gcc dot gnu.org
  2011-03-11 20:43 ` meissner at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: wschmidt at gcc dot gnu.org @ 2011-03-11 19:22 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

William J. Schmidt <wschmidt at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Target|powerpc64-linux, others     |powerpc64-linux
          Component|rtl-optimization            |target
            Summary|[Code Improvement] Use      |[Code Improvement] Poor
                   |multiplication by magic     |expansion of multiply on
                   |number for integer division |powerpc64-linux
                   |by constant                 |

--- Comment #3 from William J. Schmidt <wschmidt at gcc dot gnu.org> 2011-03-11 19:22:06 UTC ---
Changing this to a target issue.  Confirmed that gcc is producing the correct
magic number multiply, which survives till final assembly output, when the poor
expansion takes place.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2011-03-11 19:22 ` [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux wschmidt at gcc dot gnu.org
@ 2011-03-11 20:43 ` meissner at gcc dot gnu.org
  2011-03-11 21:28 ` wschmidt at gcc dot gnu.org
  2011-03-14 10:26 ` rguenth at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: meissner at gcc dot gnu.org @ 2011-03-11 20:43 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

--- Comment #4 from Michael Meissner <meissner at gcc dot gnu.org> 2011-03-11 20:43:20 UTC ---
It depends on what the default cpu is for the system.  If you say -mcpu=power4,
-mcpu=power5, or -mcpu=power7, it generates code similar to what XLC generates
with mulhw to get the recrip. and a mulli:

demonstrate:
        lis 9,values@ha
        slwi 3,3,2
        lwz 11,values@l(9)
        lis 0,0x1062
        ori 0,0,19923
        lwzx 9,11,3
        lis 11,hash_table@ha
        lwz 8,hash_table@l(11)
        mulhw 0,9,0
        srawi 10,9,31
        srawi 0,0,6
        subf 0,10,0
        mulli 0,0,1000
        subf 9,0,9
        slwi 9,9,2
        lwzx 3,8,9
        blr

If you say -mcpu=power6 the mulli is replaced by shifts and adds, similar to
what XLC generates.

demonstrate:
        lis 11,values@ha
        slwi 3,3,2
        lwz 9,values@l(11)
        lis 11,hash_table@ha
        add 9,9,3
        lwz 8,hash_table@l(11)
        lwz 10,0(9)
        lis 9,0x1062
        ori 9,9,19923
        mulhw 9,10,9
        srawi 0,10,31
        srawi 9,9,6
        subf 9,0,9
        slwi 11,9,2
        slwi 0,9,7
        subf 0,11,0
        add 0,0,9
        slwi 0,0,3
        subf 10,0,10
        slwi 10,10,2
        add 8,8,10
        lwz 3,0(8)
        blr


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2011-03-11 20:43 ` meissner at gcc dot gnu.org
@ 2011-03-11 21:28 ` wschmidt at gcc dot gnu.org
  2011-03-14 10:26 ` rguenth at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: wschmidt at gcc dot gnu.org @ 2011-03-11 21:28 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

--- Comment #5 from William J. Schmidt <wschmidt at gcc dot gnu.org> 2011-03-11 21:27:25 UTC ---
BTW, I mis-entered the optimization level before.  The code generation was at
-O2 when the mulhw was expanded into shifts/adds with the default P6 tuning. 
At -O3 and up, the mulhw is intact.

This is all explained by the default tuning model in place during testing,
since Power6 had a poorer performing integer multiply than the other machine
models.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux
  2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2011-03-11 21:28 ` wschmidt at gcc dot gnu.org
@ 2011-03-14 10:26 ` rguenth at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: rguenth at gcc dot gnu.org @ 2011-03-14 10:26 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48077

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID

--- Comment #6 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-03-14 10:26:33 UTC ---
Thus, works fine.


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-03-14 10:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-11 16:41 [Bug rtl-optimization/48077] New: [Code Improvement] Use multiplication by magic number for integer division by constant wschmidt at gcc dot gnu.org
2011-03-11 17:11 ` [Bug rtl-optimization/48077] " pinskia at gcc dot gnu.org
2011-03-11 18:34 ` wschmidt at gcc dot gnu.org
2011-03-11 19:22 ` [Bug target/48077] [Code Improvement] Poor expansion of multiply on powerpc64-linux wschmidt at gcc dot gnu.org
2011-03-11 20:43 ` meissner at gcc dot gnu.org
2011-03-11 21:28 ` wschmidt at gcc dot gnu.org
2011-03-14 10:26 ` rguenth at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).