]> git.ipfire.org Git - thirdparty/gcc.git/commit
tree-optimization/116024 - simplify C1-X cmp C2 for wrapping signed types
authorArtemiy Volkov <Artemiy.Volkov@synopsys.com>
Wed, 9 Oct 2024 00:04:13 +0000 (18:04 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 9 Oct 2024 00:04:13 +0000 (18:04 -0600)
commite5f5cffb8c8243896a9d3bd0e2b8f14c70f8df1e
tree1c1f53a1b813567e5b731236b00a0c874d1728fe
parent65b33d43d29b148e127b1ba997f1bbc2c7028b94
tree-optimization/116024 - simplify C1-X cmp C2 for wrapping signed types

Implement a match.pd transformation inverting the sign of X in
C1 - X cmp C2, where C1 and C2 are integer constants and X is
of a wrapping signed type, by observing that:

(a) If cmp is == or !=, simply move X and C2 to opposite sides of
the comparison to arrive at X cmp C1 - C2.

(b) If cmp is <:
- C1 - X < C2 means that C1 - X spans the values of -INF,
  -INF + 1, ..., C2 - 1;
        - Therefore, X is one of C1 - -INF, C1 - (-INF + 1), ...,
  C1 - C2 + 1;
- Subtracting (C1 + 1), X - (C1 + 1) is one of - (-INF) - 1,
          - (-INF) - 2, ..., -C2;
        - Using the fact that - (-INF) - 1 is +INF, derive that
          X - (C1 + 1) spans the values +INF, +INF - 1, ..., -C2;
        - Thus, the original expression can be simplified to
          X - (C1 + 1) > -C2 - 1.

(c) Similarly, C1 - X <= C2 is equivalent to X - (C1 + 1) >= -C2 - 1.

(d) The >= and > cases are negations of (b) and (c), respectively.

(e) In all cases, the expression -C2 - 1 can be shortened to
bit_not (C2).

This transformation allows to occasionally save load-immediate /
subtraction instructions, e.g. the following statement:

10 - (int)f() >= 20;

now compiles to

addi    a0,a0,-11
slti    a0,a0,-20

instead of

li      a5,10
sub     a0,a5,a0
slti    t0,a0,20
xori    a0,t0,1

on 32-bit RISC-V when compiled with -fwrapv.

Additional examples can be found in the newly added test file.  This
patch has been bootstrapped and regtested on aarch64, x86_64, and i386,
and additionally regtested on riscv32.

gcc/ChangeLog:

PR tree-optimization/116024
* match.pd: New transformation around integer comparison.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr116024-1-fwrapv.c: New test.
gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr116024-1-fwrapv.c [new file with mode: 0644]