gnu/gcc/75f572322c011229794476502f52a9ae530107f8 match.pd: fold a round up spelled with inclusive or
Linux spells a power-of-two round up as:
((x - 1) | (2^k - 1)) + 1
For wrapping arithmetic, this is:
(x + (2^k - 1)) & -(2^k)
The latter form needs one fewer operation and exposes the zero low bits.
Apply the identity to scalar and vector integral types. Use :s on the
inclusive-or expression so the fold does not add work when that value
remains live.
unsigned long round_up (unsigned long x)
{
return ((x - 1) | 4095) + 1;
}
aarch64 -O2:
before:
round_up:
sub x0, x0, #1
orr x0, x0, 4095
add x0, x0, 1
ret
after:
round_up:
add x0, x0, 4095
and x0, x0, -4096
ret
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
* match.pd (((X - 1) | C) + 1): New simplification.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/round-up-ior-1.c: New test.
* gcc.dg/tree-ssa/round-up-ior-2.c: Likewise.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
3 files changed