On 7/10/2026 8:29 PM, [email protected] wrote:
From: MITSUNARI Shigeo <[email protected]>

For 32-bit unsigned integer division by constants that require a wider
magic multiplier (mh != 0), use a pre-shifted magic constant in a mode
twice as wide and a single high-part multiply instead of the traditional
sub/shift/add sequence, when that is no more expensive.

The (size+1)-bit magic constant (2^size + ml) is pre-shifted by
(size - post_shift) bits so that the quotient is obtained directly from
the high part of the widened multiply, then truncated back to the
original mode.  The widened sequence is only used when its cost, measured
with seq_cost, does not exceed that of the classic sub/shift/add sequence.

This reduces the instruction count for divisions like x/7 from 7
instructions to 4 on x86_64.

Before (x / 7):
     movl    %edi, %eax
     imulq   $613566757, %rax, %rax
     shrq    $32, %rax
     subl    %eax, %edi
     shrl    %edi
     addl    %edi, %eax
     shrl    $2, %eax

After:
     movabsq $2635249153617166336, %rcx
     movl    %edi, %eax
     mulq    %rcx
     movl    %edx, %eax

gcc/ChangeLog:

        * expmed.cc (expand_wide_mulh_udiv): New function.
        (expand_divmod): Use it for unsigned constant division needing a
        wide multiplier on 64-bit targets, when no more expensive than the
        sub/shift/add sequence.

gcc/testsuite/ChangeLog:

        * gcc.target/i386/mulq-highpart.c: New test.
I've pushed this to the trunk.  Thanks!

jeff

Reply via email to