[Bug tree-optimization/124675] New: Missed optimization: Fold `(x % C) + (x % C < 0 ? C : 0)` to `x & (C-1)` when C is a power of 2

Explorer09 at gmail dot com gcc-bugzilla@gcc.gnu.org
Sat Mar 28 11:29:00 GMT 2026


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

            Bug ID: 124675
           Summary: Missed optimization: Fold `(x % C) + (x % C < 0 ? C :
                    0)` to `x & (C-1)` when C is a power of 2
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: Explorer09 at gmail dot com
  Target Milestone: ---

Clang performs this optimization while GCC doesn't yet.

```c
int func1(int x) {
    int rem = x % 4;
    if (rem < 0) {
        rem += 4;
    }
    return rem;
}

int func2(int x) {
    return ((x % 4) + ((x % 4) < 0 ? 4 : 0));
}

int func3(int x) {
    return ((unsigned int)x % 4);
}
```

Compiler Explorer link:
https://godbolt.org/z/KT747575d

Such a pattern may be combined with a division, which effectively makes the
quotient rounds towards negative infinity. It's a more portable pattern than an
arithmetic right shift, because in C, the >> operator with a negative
left-operand has implementation-defined behavior.

```c
int func4(int x, int *rem) {
    int quo = x / 4;
    *rem = x % 4;
    if (*rem < 0) {
        quo--;
        *rem += 4;
    }
    return quo;
}

int func5(int x, int *rem) {
    *rem = x % 4;
    if (*rem < 0) {
        *rem += 4;
    }
    int quo = (x - *rem) / 4;
    return quo;
}
```


More information about the Gcc-bugs mailing list