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

            Bug ID: 102888
           Summary: missing case for combining / and % into one operation
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vanyacpp at gmail dot com
  Target Milestone: ---

Normally GCC combines a/b and a%b into one operation when they are computed in
the same basic-block. The example below has two functions. For one GCC is able
to combine the operations and for other not (presumably because of complicated
control-flow). I believe the two functions are functionally equivalent. 

unsigned long long reduce(unsigned long long a, unsigned long long b)
{
    while ((a % b) == 0)
        a /= b;

    return a;
}

unsigned long long reduce_opt(unsigned long long a, unsigned long long b)
{
    for (;;)
    {
        unsigned long long quot = a / b;
        unsigned long long rem = a % b;
        if (rem != 0)
            break;
        a = quot;
    }

    return a;
}

reduce.L3:
        mov     rax, r8
        xor     edx, edx
        div     rsi
        xor     edx, edx
        mov     r8, rax
        div     rsi
        test    rdx, rdx
        je      .L3

reduce_opt.L8:
        xor     edx, edx
        mov     r8, rax
        div     rsi
        test    rdx, rdx
        je      .L8

https://godbolt.org/z/9dqs8avE5

It would be great if GCC generated the same code for both of these functions.

Reply via email to