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

            Bug ID: 118397
           Summary: Missed optimization (x % (C1 * C2) / C2) vs. ((x / C2)
                    % C1)
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

When an expression contains modulo and division, if the modulo happens first
but the divisor is a multiple of the divisor later on, the expression can be
optimized by swapping and division and modulo, especially when this can reduce
code size (`-Os` option).

(Sometimes it is desirable to swap the operators the other way around, if the
compiler can tell if the divisor has been loaded already by the surrounding
code.)

Below are the examples: `func1a`, `func1b` and `func1c` are equivalent;
likewise for `func2a`, `func2b` and `func2c`.

(Can be tested in Compiler Explorer. x86-64 gcc 14.2 with `-Os` option)

```c
unsigned long long func1a(unsigned long long x) {
    return (x / 60) % 60;
}

unsigned long long func1b(unsigned long long x) {
    return (x % 3600) / 60;
}

unsigned long long func1c(unsigned long long x) {
    return (x % (60 * 60)) / 60;
}

unsigned long long func2a(unsigned long long x) {
    return (x / 60) % 24;
}

unsigned long long func2b(unsigned long long x) {
    return (x % 1440) / 60;
}

unsigned long long func2c(unsigned long long x) {
    return (x % (24 * 60)) / 60;
}
```

Reply via email to