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