From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2119) id 172643858C54; Wed, 7 Jun 2023 19:59:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 172643858C54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686167958; bh=YR8fjW7M406htNsXWYpSnSBZhJaK7hNQF4m3thz8Xm8=; h=From:To:Subject:Date:From; b=HDUKKt8DIb3Vm+ZCFYsqkTYEKqOVPJqtnbrvxqjoocnvakhvvQhcz2jdKD22Id915 QPb36OR3B/eZpuDnsbX2G3GbIBjkI1U46KgAodhSXuXeRIf3uzrhlPULg9xCg5FA+K H3jmtJwKeujvB8URyF1+IvynLZMujfKLO07elB9I= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jeff Law To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1622] RISC-V: Eliminate extension after for *w instructions X-Act-Checkin: gcc X-Git-Author: Jeff Law X-Git-Refname: refs/heads/master X-Git-Oldrev: 7f26e76c9848aeea9ec10ea701a6168464a4a9c2 X-Git-Newrev: 99bfdb072e67fa3fe294d86b4b2a9f686f8d9705 Message-Id: <20230607195918.172643858C54@sourceware.org> Date: Wed, 7 Jun 2023 19:59:18 +0000 (GMT) List-Id: https://gcc.gnu.org/g:99bfdb072e67fa3fe294d86b4b2a9f686f8d9705 commit r14-1622-g99bfdb072e67fa3fe294d86b4b2a9f686f8d9705 Author: Jeff Law Date: Wed Jun 7 13:40:16 2023 -0600 RISC-V: Eliminate extension after for *w instructions This patch tries to prevent generating unnecessary sign extension after *w instructions like "addiw" or "divw". The main idea of it is to add SUBREG_PROMOTED fields during expanding. I have tested on SPEC2017 there is no regression. Only gcc.dg/pr30957-1.c test failed. To solve that I did some changes in loop-iv.cc, but not sure that it is suitable. gcc/ChangeLog: * config/riscv/bitmanip.md (rotrdi3, rotrsi3, rotlsi3): New expanders. (rotrsi3_sext): Expose generator. (rotlsi3 pattern): Hide generator. * config/riscv/riscv-protos.h (riscv_emit_binary): New function declaration. * config/riscv/riscv.cc (riscv_emit_binary): Removed static * config/riscv/riscv.md (addsi3, subsi3, negsi2): Hide generator. (mulsi3, si3): Likewise. (addsi3, subsi3, negsi2, mulsi3, si3): New expanders. (addv4, subv4, mulv4): Use riscv_emit_binary. (mulsidi3): Likewise. (addsi3_extended, subsi3_extended, negsi2_extended): Expose generator. (mulsi3_extended, si3_extended): Likewise. (splitter for shadd feeding divison): Update RTL pattern to account for changes in how 32 bit ops are expanded for TARGET_64BIT. * loop-iv.cc (get_biv_step_1): Process src of extension when it PLUS. gcc/testsuite/ChangeLog: * gcc.target/riscv/shift-and-2.c: New tests. * gcc.target/riscv/shift-shift-2.c: Adjust expected output. * gcc.target/riscv/sign-extend.c: New test. * gcc.target/riscv/zbb-rol-ror-03.c: Adjust expected output. Co-authored-by: Jeff Law Diff: --- gcc/config/riscv/bitmanip.md | 58 ++++++++-- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv.cc | 2 +- gcc/config/riscv/riscv.md | 147 ++++++++++++++++++++---- gcc/loop-iv.cc | 28 ++++- gcc/testsuite/gcc.target/riscv/shift-and-2.c | 19 +++ gcc/testsuite/gcc.target/riscv/shift-shift-2.c | 5 +- gcc/testsuite/gcc.target/riscv/sign-extend.c | 81 +++++++++++++ gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c | 3 +- 9 files changed, 309 insertions(+), 35 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 96d31d92670..c42e7b890db 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -47,10 +47,10 @@ ; implicit sign-extensions. (define_split [(set (match_operand:DI 0 "register_operand") - (sign_extend:DI (div:SI (plus:SI (subreg:SI (ashift:DI (match_operand:DI 1 "register_operand") - (match_operand:QI 2 "imm123_operand")) 0) - (subreg:SI (match_operand:DI 3 "register_operand") 0)) - (subreg:SI (match_operand:DI 4 "register_operand") 0)))) + (sign_extend:DI (div:SI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0) + (match_operand:QI 2 "imm123_operand")) + (subreg:SI (match_operand:DI 3 "register_operand") 0)) + (subreg:SI (match_operand:DI 4 "register_operand") 0)))) (clobber (match_operand:DI 5 "register_operand"))] "TARGET_64BIT && TARGET_ZBA" [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -304,11 +304,11 @@ [(set_attr "type" "bitmanip,load") (set_attr "mode" "HI")]) -(define_expand "rotr3" - [(set (match_operand:GPR 0 "register_operand") - (rotatert:GPR (match_operand:GPR 1 "register_operand") +(define_expand "rotrdi3" + [(set (match_operand:DI 0 "register_operand") + (rotatert:DI (match_operand:DI 1 "register_operand") (match_operand:QI 2 "arith_operand")))] - "TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB" + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)" { if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) FAIL; @@ -322,6 +322,26 @@ "ror%i2%~\t%0,%1,%2" [(set_attr "type" "bitmanip")]) +(define_expand "rotrsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (rotatert:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "arith_operand" "rI")))] + "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB" +{ + if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) + FAIL; + if (TARGET_64BIT && register_operand (operands[2], QImode)) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "*rotrdi3" [(set (match_operand:DI 0 "register_operand" "=r") (rotatert:DI (match_operand:DI 1 "register_operand" "r") @@ -330,7 +350,7 @@ "ror%i2\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "*rotrsi3_sext" +(define_insn "rotrsi3_sext" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "arith_operand" "rI"))))] @@ -338,7 +358,7 @@ "ror%i2%~\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "rotlsi3" +(define_insn "*rotlsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotate:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "register_operand" "r")))] @@ -346,6 +366,24 @@ "rol%~\t%0,%1,%2" [(set_attr "type" "bitmanip")]) +(define_expand "rotlsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "register_operand" "r")))] + "TARGET_ZBB || TARGET_ZBKB" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "rotldi3" [(set (match_operand:DI 0 "register_operand" "=r") (rotate:DI (match_operand:DI 1 "register_operand" "r") diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 9782f1794fb..38e4125424b 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -61,6 +61,7 @@ extern const char *riscv_output_return (); extern void riscv_expand_int_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_float_scc (rtx, enum rtx_code, rtx, rtx); extern void riscv_expand_conditional_branch (rtx, enum rtx_code, rtx, rtx); +extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y); #endif extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx); extern rtx riscv_legitimize_call_address (rtx); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 60ebd9903e5..de30bf4e567 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1415,7 +1415,7 @@ riscv_emit_set (rtx target, rtx src) /* Emit an instruction of the form (set DEST (CODE X Y)). */ -static rtx +rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y) { return riscv_emit_set (dest, gen_rtx_fmt_ee (code, GET_MODE (dest), x, y)); diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index be960583101..38b8fba2a53 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -513,7 +513,7 @@ [(set_attr "type" "fadd") (set_attr "mode" "")]) -(define_insn "addsi3" +(define_insn "*addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (plus:SI (match_operand:SI 1 "register_operand" " r,r") (match_operand:SI 2 "arith_operand" " r,I")))] @@ -522,6 +522,24 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_expand "addsi3" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (plus:SI (match_operand:SI 1 "register_operand" " r,r") + (match_operand:SI 2 "arith_operand" " r,I")))] + "" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_addsi3_extended (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (plus:DI (match_operand:DI 1 "register_operand" " r,r") @@ -545,7 +563,7 @@ rtx t5 = gen_reg_rtx (DImode); rtx t6 = gen_reg_rtx (DImode); - emit_insn (gen_addsi3 (operands[0], operands[1], operands[2])); + riscv_emit_binary (PLUS, operands[0], operands[1], operands[2]); if (GET_CODE (operands[1]) != CONST_INT) emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0)); else @@ -591,7 +609,7 @@ emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0)); else t3 = operands[1]; - emit_insn (gen_addsi3 (operands[0], operands[1], operands[2])); + riscv_emit_binary (PLUS, operands[0], operands[1], operands[2]); emit_insn (gen_extend_insn (t4, operands[0], DImode, SImode, 0)); riscv_expand_conditional_branch (operands[3], LTU, t4, t3); @@ -606,7 +624,7 @@ DONE; }) -(define_insn "*addsi3_extended" +(define_insn "addsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r,r") (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" " r,r") @@ -653,7 +671,7 @@ [(set_attr "type" "arith") (set_attr "mode" "DI")]) -(define_insn "subsi3" +(define_insn "*subsi3" [(set (match_operand:SI 0 "register_operand" "= r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ") (match_operand:SI 2 "register_operand" " r")))] @@ -662,6 +680,24 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_expand "subsi3" + [(set (match_operand:SI 0 "register_operand" "= r") + (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ") + (match_operand:SI 2 "register_operand" " r")))] + "" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_subsi3_extended (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_expand "subv4" [(set (match_operand:GPR 0 "register_operand" "= r") (minus:GPR (match_operand:GPR 1 "reg_or_0_operand" " rJ") @@ -676,7 +712,7 @@ rtx t5 = gen_reg_rtx (DImode); rtx t6 = gen_reg_rtx (DImode); - emit_insn (gen_subsi3 (operands[0], operands[1], operands[2])); + riscv_emit_binary (MINUS, operands[0], operands[1], operands[2]); if (GET_CODE (operands[1]) != CONST_INT) emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0)); else @@ -725,7 +761,7 @@ emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0)); else t3 = operands[1]; - emit_insn (gen_subsi3 (operands[0], operands[1], operands[2])); + riscv_emit_binary (MINUS, operands[0], operands[1], operands[2]); emit_insn (gen_extend_insn (t4, operands[0], DImode, SImode, 0)); riscv_expand_conditional_branch (operands[3], LTU, t3, t4); @@ -741,7 +777,7 @@ }) -(define_insn "*subsi3_extended" +(define_insn "subsi3_extended" [(set (match_operand:DI 0 "register_operand" "= r") (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" " rJ") @@ -770,7 +806,7 @@ [(set_attr "type" "arith") (set_attr "mode" "DI")]) -(define_insn "negsi2" +(define_insn "*negsi2" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "register_operand" " r")))] "" @@ -778,7 +814,24 @@ [(set_attr "type" "arith") (set_attr "mode" "SI")]) -(define_insn "*negsi2_extended" +(define_expand "negsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (neg:SI (match_operand:SI 1 "register_operand" " r")))] + "" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_negsi2_extended (t, operands[1])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + +(define_insn "negsi2_extended" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (neg:SI (match_operand:SI 1 "register_operand" " r"))))] @@ -814,7 +867,7 @@ [(set_attr "type" "fmul") (set_attr "mode" "")]) -(define_insn "mulsi3" +(define_insn "*mulsi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "register_operand" " r") (match_operand:SI 2 "register_operand" " r")))] @@ -823,6 +876,24 @@ [(set_attr "type" "imul") (set_attr "mode" "SI")]) +(define_expand "mulsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (mult:SI (match_operand:SI 1 "register_operand" " r") + (match_operand:SI 2 "register_operand" " r")))] + "TARGET_ZMMUL || TARGET_MUL" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_mulsi3_extended (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (match_operand:DI 1 "register_operand" " r") @@ -868,8 +939,8 @@ emit_insn (gen_smul3_highpart (hp, operands[1], operands[2])); emit_insn (gen_mul3 (operands[0], operands[1], operands[2])); - emit_insn (gen_ashr3 (lp, operands[0], - GEN_INT (BITS_PER_WORD - 1))); + riscv_emit_binary (ASHIFTRT, lp, operands[0], + GEN_INT (BITS_PER_WORD - 1)); riscv_expand_conditional_branch (operands[3], NE, hp, lp); } @@ -923,7 +994,7 @@ DONE; }) -(define_insn "*mulsi3_extended" +(define_insn "mulsi3_extended" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (mult:SI (match_operand:SI 1 "register_operand" " r") @@ -1024,7 +1095,7 @@ "(TARGET_ZMMUL || TARGET_MUL) && !TARGET_64BIT" { rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); + riscv_emit_binary (MULT, temp, operands[1], operands[2]); emit_insn (gen_mulsi3_highpart (riscv_subword (operands[0], true), operands[1], operands[2])); emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); @@ -1055,7 +1126,7 @@ "(TARGET_ZMMUL || TARGET_MUL) && !TARGET_64BIT" { rtx temp = gen_reg_rtx (SImode); - emit_insn (gen_mulsi3 (temp, operands[1], operands[2])); + riscv_emit_binary (MULT, temp, operands[1], operands[2]); emit_insn (gen_usmulsi3_highpart (riscv_subword (operands[0], true), operands[1], operands[2])); emit_insn (gen_movsi (riscv_subword (operands[0], false), temp)); @@ -1084,7 +1155,7 @@ ;; .................... ;; -(define_insn "si3" +(define_insn "*si3" [(set (match_operand:SI 0 "register_operand" "=r") (any_div:SI (match_operand:SI 1 "register_operand" " r") (match_operand:SI 2 "register_operand" " r")))] @@ -1093,6 +1164,24 @@ [(set_attr "type" "idiv") (set_attr "mode" "SI")]) +(define_expand "si3" + [(set (match_operand:SI 0 "register_operand" "=r") + (any_div:SI (match_operand:SI 1 "register_operand" " r") + (match_operand:SI 2 "register_operand" " r")))] + "TARGET_DIV" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_si3_extended (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "di3" [(set (match_operand:DI 0 "register_operand" "=r") (any_div:DI (match_operand:DI 1 "register_operand" " r") @@ -1118,7 +1207,7 @@ DONE; }) -(define_insn "*si3_extended" +(define_insn "si3_extended" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (any_div:SI (match_operand:SI 1 "register_operand" " r") @@ -2072,7 +2161,7 @@ ;; expand_shift_1 can do this automatically when SHIFT_COUNT_TRUNCATED is ;; defined, but use of that is discouraged. -(define_insn "si3" +(define_insn "*si3" [(set (match_operand:SI 0 "register_operand" "= r") (any_shift:SI (match_operand:SI 1 "register_operand" " r") @@ -2088,6 +2177,24 @@ [(set_attr "type" "shift") (set_attr "mode" "SI")]) +(define_expand "si3" + [(set (match_operand:SI 0 "register_operand" "= r") + (any_shift:SI (match_operand:SI 1 "register_operand" " r") + (match_operand:QI 2 "arith_operand" " rI")))] + "" +{ + if (TARGET_64BIT) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_si3_extend (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + (define_insn "di3" [(set (match_operand:DI 0 "register_operand" "= r") (any_shift:DI @@ -2122,7 +2229,7 @@ [(set_attr "type" "shift") (set_attr "mode" "")]) -(define_insn "*si3_extend" +(define_insn "si3_extend" [(set (match_operand:DI 0 "register_operand" "= r") (sign_extend:DI (any_shift:SI (match_operand:SI 1 "register_operand" " r") diff --git a/gcc/loop-iv.cc b/gcc/loop-iv.cc index 6c40db947f7..858c5ee84f2 100644 --- a/gcc/loop-iv.cc +++ b/gcc/loop-iv.cc @@ -637,7 +637,7 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg, { rtx set, rhs, op0 = NULL_RTX, op1 = NULL_RTX; rtx next, nextr; - enum rtx_code code; + enum rtx_code code, prev_code = UNKNOWN; rtx_insn *insn = DF_REF_INSN (def); df_ref next_def; enum iv_grd_result res; @@ -697,6 +697,27 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg, return false; op0 = XEXP (rhs, 0); + + /* rv64 wraps SImode arithmetic inside an extension to DImode. + This matches the actual hardware semantics. So peek inside + the extension and see if we have simple arithmetic that we + can analyze. */ + if (GET_CODE (op0) == PLUS) + { + rhs = op0; + op0 = XEXP (rhs, 0); + op1 = XEXP (rhs, 1); + + if (CONSTANT_P (op0)) + std::swap (op0, op1); + + if (!simple_reg_p (op0) || !CONSTANT_P (op1)) + return false; + + prev_code = code; + code = PLUS; + } + if (!simple_reg_p (op0)) return false; @@ -769,6 +790,11 @@ get_biv_step_1 (df_ref def, scalar_int_mode outer_mode, rtx reg, else *outer_step = simplify_gen_binary (code, outer_mode, *outer_step, op1); + + if (prev_code == SIGN_EXTEND) + *extend = IV_SIGN_EXTEND; + else if (prev_code == ZERO_EXTEND) + *extend = IV_ZERO_EXTEND; break; case SIGN_EXTEND: diff --git a/gcc/testsuite/gcc.target/riscv/shift-and-2.c b/gcc/testsuite/gcc.target/riscv/shift-and-2.c index bc01e8ef992..ee9925b7498 100644 --- a/gcc/testsuite/gcc.target/riscv/shift-and-2.c +++ b/gcc/testsuite/gcc.target/riscv/shift-and-2.c @@ -38,5 +38,24 @@ sub6 (long i, long j) { return i << (j & 0x3f); } + +/* Test for si3_extend. */ +int +sub7 (int i, int j) { + return (i << 10) & j; +} + +/* Test for si3_extend. */ +unsigned +sub8 (unsigned i, unsigned j) { + return (i << 10) & j; +} + +/* Test for si3_extend. */ +unsigned +sub9 (unsigned i, unsigned j) { + return (i >> 10) & j; +} + /* { dg-final { scan-assembler-not "andi" } } */ /* { dg-final { scan-assembler-not "sext.w" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c index 5f93be15ac5..bc8c4ef3828 100644 --- a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c +++ b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c @@ -38,5 +38,6 @@ sub5 (unsigned int i) } /* { dg-final { scan-assembler-times "slli" 5 } } */ /* { dg-final { scan-assembler-times "srli" 5 } } */ -/* { dg-final { scan-assembler-times "slliw" 1 } } */ -/* { dg-final { scan-assembler-times "srliw" 1 } } */ +/* { dg-final { scan-assembler-times ",40" 2 } } */ /* For sub5 test */ +/* { dg-final { scan-assembler-not "slliw" } } */ +/* { dg-final { scan-assembler-not "srliw" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/sign-extend.c b/gcc/testsuite/gcc.target/riscv/sign-extend.c new file mode 100644 index 00000000000..6f840194833 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/sign-extend.c @@ -0,0 +1,81 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-options "-march=rv64gc -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +unsigned +foo1 (unsigned x, unsigned y, unsigned z) +{ + return x & (y - z); +} + +int +foo2 (int x, int y, int z) +{ + return x & (y - z); +} + +unsigned +foo3 (unsigned x, unsigned y, unsigned z) +{ + return x & (y * z); +} + +int +foo4 (int x, int y, int z) +{ + return x & (y * z); +} + +unsigned +foo5 (unsigned x, unsigned y) +{ + return x & (y / x); +} + +int +foo6 (int x, int y) +{ + return x & (y / x); +} + +unsigned +foo7 (unsigned x, unsigned y) +{ + return x & (y % x); +} + +int +foo8 (int x, int y) +{ + return x & (y % x); +} + +int +foo9 (int x) +{ + return x & (-x); +} + +unsigned +foo10 (unsigned x, unsigned y) +{ + return x & (y + x); +} + + +unsigned +foo11 (unsigned x) +{ + return x & (15 + x); +} + +/* { dg-final { scan-assembler-times "subw" 2 } } */ +/* { dg-final { scan-assembler-times "addw" 1 } } */ +/* { dg-final { scan-assembler-times "addiw" 1 } } */ +/* { dg-final { scan-assembler-times "mulw" 2 } } */ +/* { dg-final { scan-assembler-times "divw" 1 } } */ +/* { dg-final { scan-assembler-times "divuw" 1 } } */ +/* { dg-final { scan-assembler-times "remw" 1 } } */ +/* { dg-final { scan-assembler-times "remuw" 1 } } */ +/* { dg-final { scan-assembler-times "negw" 1 } } */ +/* { dg-final { scan-assembler-not "sext.w" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c index b44d7fe8920..e7e5cbb9a1a 100644 --- a/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c +++ b/gcc/testsuite/gcc.target/riscv/zbb-rol-ror-03.c @@ -16,4 +16,5 @@ unsigned int ror(unsigned int rs1, unsigned int rs2) /* { dg-final { scan-assembler-times "rolw" 1 } } */ /* { dg-final { scan-assembler-times "rorw" 1 } } */ -/* { dg-final { scan-assembler-not "and" } } */ \ No newline at end of file +/* { dg-final { scan-assembler-not "and" } } */ +/* { dg-final { scan-assembler-not "sext.w" } } */