RV64 comapre and branch instructions only support 64-bit operands.
The backend unconditionally generates zero/sign extend at Expand time
for compare and branch operands even if they are already as such
e.g. function args which ABI guarantees to be sign-extended (at callsite).

And subsequently REE fails to eliminate them as
        "missing defintion(s)"
specially for function args since they show up as missing explicit
definition.

So elide the sign extensions at Expand time for a subreg promoted var
with inner word sized value whcih doesn't need explicit sign extending
(fairly good represntative of an incoming function arg).

There are patches floating to enhance REE and/or new passes to elimiate
extensions, but it is always better to not generate them if possible,
given Expand is so early, the elimiated extend would help improve outcomes
of later passes such as combine if they have fewer operations/combinations
to deal with.

The test used was existing gcc.c-torture/execute/20020506-1.c -O2 zbb
It elimiates the SEXT.W and an additional branch

before                                  after
-------                                 ------
test2:                                  test2:
        sext.b  a0,a0
        blt     a0,zero,.L15
        bne     a1,zero,.L17                    bne     a1,zero,.L17

This is marked RFC as I only ran a spot check with a directed test and
want to use Patrick's pre-commit CI to do the A/B testing for me.

gcc/ChangeLog:
        * config/riscv/riscv.cc (riscv_extend_comparands): Don't
        sign-extend operand if subreg promoted with inner word size.

Signed-off-by: Vineet Gupta <vine...@rivosinc.com>
---
 gcc/config/riscv/riscv.cc | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f2dcb0db6fbd..a8d12717e43d 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3707,7 +3707,16 @@ riscv_extend_comparands (rtx_code code, rtx *op0, rtx 
*op1)
        }
       else
        {
-         *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
+       /* A subreg promoted SI of DI could be peeled to expose DI, eliding
+          an unnecessary sign extension.  */
+       if (GET_CODE (*op0) == SUBREG
+           && SUBREG_PROMOTED_VAR_P (*op0)
+           && GET_MODE_SIZE (GET_MODE (XEXP (*op0, 0))).to_constant ()
+              == GET_MODE_SIZE (word_mode))
+            *op0 = XEXP (*op0, 0);
+       else
+            *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0);
+
          if (*op1 != const0_rtx)
            *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1);
        }
-- 
2.34.1

Reply via email to