On 9/30/24 2:04 AM, Artemiy Volkov wrote:
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 an unsigned 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 range of 0, 1, ..., C2 - 1;
         - This means that X spans the range of C1 - (C2 - 1),
          C1 - (C2 - 2), ..., C1;
        - Subtracting C1 - (C2 - 1), X - (C1 - (C2 - 1)) is one of 0, 1,
          ..., C1 - (C1 - (C2 - 1));
         - Simplifying the above, X - (C1 - C2 + 1) is one of 0, 1, ...,
          C2 - 1;
         - Summarizing, the expression C1 - X < C2 can be transformed
          into X - (C1 - C2 + 1) < C2.

(c) Similarly, if cmp is <=:
        - C1 - X <= C2 means that C1 - X is one of 0, 1, ..., C2;
        - It follows that X is one of C1 - C2, C1 - (C2 - 1), ..., C1;
         - Subtracting C1 - C2, X - (C1 - C2) has range 0, 1, ..., C2;
         - Thus, the expression C1 - X <= C2 can be transformed into
          X - (C1 - C2) <= C2.

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

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

300 - (unsigned int)f() < 100;

now compiles to

addi    a0,a0,-201
sltiu   a0,a0,100

instead of

li      a5,300
sub     a0,a5,a0
sltiu   a0,a0,100

on 32-bit RISC-V.

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.c: New test.

Signed-off-by: Artemiy Volkov <arte...@synopsys.com>
Thanks.  I've pushed this to the trunk.
jeff

Reply via email to