On 9/27/24 1:36 AM, Jovan Vukic wrote:
Based on the valuable feedback I received, I decided to implement the patch
in the RTL pipeline. Since a similar optimization already exists in
simplify_binary_operation_1, I chose to generalize my original approach
and place it directly below that code.

The expression (X xor C1) + C2 is simplified to X xor (C1 xor C2) under
the conditions described in the patch. This is a more general optimization,
but it still applies to the RISC-V case, which was my initial goal:

long f1(long x, long y) {
     return (x > y) ? 2 : 3;
}


Before the patch, the generated assembly is:

f1(long, long):
         sgt     a0,a0,a1
         xori    a0,a0,1
         addi    a0,a0,2
         ret

After the patch, the generated assembly is:

f1(long, long):
         sgt     a0,a0,a1
         xori    a0,a0,3
         ret


The patch optimizes cases like x LT/GT y ? 2 : 3 (and x GE/LE y ? 3 : 2),
as initially intended. Since this optimization is more general, I noticed
it also optimizes cases like x < CONST ? 3 : 2 when CONST < 0. I’ve added
tests for these cases as well.

A bit of logic behind the patch: The equality A + B == A ^ B + 2 * (A & B)
always holds true. This can be simplified to A ^ B if 2 * (A & B) == 0.
In our case, we have A == X ^ C1, B == C2 and X is either 0 or 1.

2024-09-27  Jovan Vukic  <jovan.vu...@rt-rk.com>

         PR target/108038

gcc/ChangeLog:

         * simplify-rtx.cc (simplify_context::simplify_binary_operation_1): New
         simplification.

gcc/testsuite/ChangeLog:

         * gcc.target/riscv/slt-1.c: New test.
THanks. I fixed a tabs vs space issue in the ChangeLog and pushed this to the trunk.

jeff

Reply via email to