https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126674
Bug ID: 126674
Summary: `(x - x%b) >= b` when x and b are both non-negative
can be simplified into `x >= b`
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: easyhack, missed-optimization
Severity: enhancement
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: pinskia at gcc dot gnu.org
Target Milestone: ---
Take:
```
int f(unsigned x, unsigned C)
{
return (x - x % C) >= C;
}
int g(unsigned x, unsigned C)
{
C = 10;
return (x - x % C) >= C;
}
```
These both can and should be optimized to:
x >= C;
The reason is if x < C, then `x - x % C` will be 0 so it will be false and the
original expression is false. It holds that `(x - x%C) <= x` is always true
(for all non-negative values) so `x <= C` holds the same as `(x - x%C) <= C`
Note `x >= 10` will be turned into `x > 9` so that needs match.
Also this should handle `<` too with the same reasoning as `>=` (it is just the
inverse of `>=`).
Note the LLVM pull request currently only handles `>=` and a constant but that
should stop us from implementing it fully.
The check for zero should be something like:
(!flag_non_call_exceptions || tree_expr_nonzero_p (@0))
Which is what we do for other division/mod patterns.