On 9/23/24 2:32 AM, Artemiy Volkov wrote:
Implement a match.pd pattern for C1 - X cmp C2, where C1 and C2 are
integer constants and X is of a UB-on-overflow type.  The pattern is
simplified to X rcmp C1 - C2 by moving X and C2 to the other side of the
comparison (with opposite signs).  If C1 - C2 happens to overflow,
replace the whole expression with either a constant 0 or a constant 1
node, depending on the comparison operator and the sign of the overflow.

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

10 - (int) x <= 9;

now compiles to

sgt     a0,a0,zero

instead of

li      a5,10
sub     a0,a5,a0
slti    a0,a0,10

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.  Existing tests were
adjusted where necessary.

gcc/ChangeLog:

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

gcc/testsuite/ChangeLog:

         * gcc.dg/tree-ssa/pr116024.c: New test.
         * gcc.dg/pr67089-6.c: Adjust.
I think Richi is already engaged on the review side, so I'll let him own especially since he knows more about match.pd patterns than I do.


+int32_t i1(void)
+{
+  int32_t l = 2;
+  l = 10 - (int32_t)f();
+  return l <= 9; // f() > 0
+}
Why the initialization of l = 2? It's trivially dead and I expect it to be cleaned up early in the optimization pipeline. It looks like most of the tests in the series have this trivially dead initialization code.

Jeff




Reply via email to