From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7921) id EA659385841A; Wed, 15 Nov 2023 17:35:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EA659385841A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1700069729; bh=R03RjJ+ng3Nk8gaHwIq6T6703PfWGfGkZElNIuKUJ+s=; h=From:To:Subject:Date:From; b=uBOrmWAi6CvFs8YIN6MLX6kEhlAmhlFGSjiupET3RcdtOz6ZSBrDmcGAwghI5y3lm ilUK2wviOD1GfS3fmzNxHdwCYn/ZM/pJHzIGc7xCBJiWJ7rMXg8xztBMhY5MGxNcc+ OZIw6Q+tYPfFodqPzES5S7rgWTV+zFFaNWIkJGEs= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Vineet Gupta To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-5506] RISC-V: elide unnecessary sign extend when expanding cmp_and_jump X-Act-Checkin: gcc X-Git-Author: Vineet Gupta X-Git-Refname: refs/heads/master X-Git-Oldrev: b126f3ffbef59b0b08c2c2a664133d7d6f5ca235 X-Git-Newrev: fb4e2c1648ea4cf1b1d34205a1da519702328d92 Message-Id: <20231115173529.EA659385841A@sourceware.org> Date: Wed, 15 Nov 2023 17:35:29 +0000 (GMT) List-Id: https://gcc.gnu.org/g:fb4e2c1648ea4cf1b1d34205a1da519702328d92 commit r14-5506-gfb4e2c1648ea4cf1b1d34205a1da519702328d92 Author: Vineet Gupta Date: Tue Oct 24 20:38:49 2023 -0700 RISC-V: elide unnecessary sign extend when expanding cmp_and_jump RV64 compare and branch instructions only support 64-bit operands. At Expand time, the backend conservatively zero/sign extends its operands even if not needed, such as incoming function args which ABI/ISA guarantee to be sign-extended already (this is true for SI, HI, QI operands) And subsequently REE fails to eliminate them as "missing defintion(s)" or "multiple definition(s) since function args don't have explicit definition. So during expand riscv_extend_comparands (), if an operand is a subreg-promoted SI with inner DI, which is representative of a function arg, just peel away the subreg to expose the DI, eliding the sign extension. As Jeff noted this routine is also used in if-conversion so potentially can also help there. Note there's currently patches floating around to improve REE and also a new pass to eliminate unneccesary extensions, but it is still beneficial to not generate those extra extensions in first place. It is obviously less work for post-reload passes such as REE, but even for earlier passes, such as combine, having to deal with one less thing and ensuing fewer combinations is a win too. Way too many existing tests used to observe this issue. e.g. gcc.c-torture/compile/20190827-1.c -O2 -march=rv64gc It elimiates the SEXT.W gcc/ChangeLog: * config/riscv/riscv.cc (riscv_sign_extend_if_not_subreg_prom): New. * (riscv_extend_comparands): Call New function on operands. Tested-by: Patrick O'Neill # pre-commit-CI #676 Signed-off-by: Vineet Gupta Diff: --- gcc/config/riscv/riscv.cc | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e919850fc6c..e466d4f168a 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -3695,6 +3695,24 @@ riscv_zero_if_equal (rtx cmp0, rtx cmp1) cmp0, cmp1, 0, 0, OPTAB_DIRECT); } +/* Helper function for riscv_extend_comparands to Sign-extend the OP. + However if the OP is SI subreg promoted with an inner DI, such as + (subreg/s/v:SI (reg/v:DI) 0) + just peel off the SUBREG to get DI, avoiding extraneous extension. */ + +static void +riscv_sign_extend_if_not_subreg_prom (rtx *op) +{ + if (GET_CODE (*op) == SUBREG + && SUBREG_PROMOTED_VAR_P (*op) + && SUBREG_PROMOTED_SIGNED_P (*op) + && (GET_MODE_SIZE (GET_MODE (XEXP (*op, 0))).to_constant () + == GET_MODE_SIZE (word_mode))) + *op = XEXP (*op, 0); + else + *op = gen_rtx_SIGN_EXTEND (word_mode, *op); +} + /* Sign- or zero-extend OP0 and OP1 for integer comparisons. */ static void @@ -3724,9 +3742,10 @@ riscv_extend_comparands (rtx_code code, rtx *op0, rtx *op1) } else { - *op0 = gen_rtx_SIGN_EXTEND (word_mode, *op0); + riscv_sign_extend_if_not_subreg_prom (op0); + if (*op1 != const0_rtx) - *op1 = gen_rtx_SIGN_EXTEND (word_mode, *op1); + riscv_sign_extend_if_not_subreg_prom (op1); } } }