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.

Reply via email to