https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70703

            Bug ID: 70703
           Summary: Regression in register usage on x86
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vda.linux at googlemail dot com
  Target Milestone: ---

$ cat bad.c
unsigned ud_x_641_mul(unsigned x) {
    /* optimized version of x / 641 */
    return ((unsigned long long)x * 0x663d81) >> 32;
}

With gcc from current svn:
$ gcc -m32 -fomit-frame-pointer -O2 bad.c -S && cat bad.s
...
ud_x_641_mul:
        .cfi_startproc
        movl    $6700417, %ecx
        movl    %ecx, %eax
        mull    4(%esp)
        movl    %edx, %ecx
        movl    %ecx, %eax
        ret

Same result with -Os. Note two pointless mov insns.

gcc 5.3.1 is "better", it adds only one unnecessary insn:

ud_x_641_mul:
        .cfi_startproc
        movl    $6700417, %ecx
        movl    %ecx, %eax
        mull    4(%esp)
        movl    %edx, %eax
        ret

gcc 4.4.x and 4.7.2 were generating this code, which looks optimal:
ud_x_641_mul:
        .cfi_startproc
        movl    $6700417, %eax
        mull    4(%esp)
        movl    %edx, %eax
        ret

I did not test other versions of gcc yet.

Reply via email to