[PATCH] RISC-V: Fix wrong partial subreg check for bsetidisi
From: Lin Sinan The partial subreg check should be for subreg operand(operand 1) instead of the immediate operand(operand 2). This change also fix pr68648.c in zbs. gcc/ChangeLog: * config/riscv/bitmanip.md: Fix wrong index in the check. --- gcc/config/riscv/bitmanip.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 14d18edbe62..58a86bd929f 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -442,7 +442,7 @@ (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand 2 "single_bit_mask_operand" "i")))] "TARGET_ZBS && TARGET_64BIT - && !partial_subreg_p (operands[2])" + && !partial_subreg_p (operands[1])" "bseti\t%0,%1,%S2" [(set_attr "type" "bitmanip")]) -- 2.34.1
[PATCH RESEND] riscv: improve the cost model for loading a 64bit constant in rv32.
The motivation of this patch is to correct the wrong estimation of the number of instructions needed for loading a 64bit constant in rv32 in the current cost model(riscv_interger_cost). According to the current implementation, if a constant requires more than 3 instructions(riscv_const_insn and riscv_legitimate_constant_p), then the constant will be put into constant pool when expanding gimple to rtl(legitimate_constant_p hook and emit_move_insn). So the inaccurate cost model leads to the suboptimal codegen in rv32 and the wrong estimation part could be corrected through this fix. e.g. the current codegen for loading 0x839290001 in rv32 lui a5,%hi(.LC0) lw a0,%lo(.LC0)(a5) lw a1,%lo(.LC0+4)(a5) .LC0: .word 958988289 .word 8 output after this patch li a0,958988288 addi a0,a0,1 li a1,8 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_build_integer): Handle the case of loading 64bit constant in rv32. gcc/testsuite/ChangeLog: * gcc.target/riscv/rv32-load-64bit-constant.c: New test. Signed-off-by: Lin Sinan --- gcc/config/riscv/riscv.cc | 23 +++ .../riscv/rv32-load-64bit-constant.c | 38 +++ 2 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 32f9ef9ade9..9dffabdc5e3 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -618,6 +618,29 @@ riscv_build_integer (struct riscv_integer_op *codes, HOST_WIDE_INT value, } } + if ((value > INT32_MAX || value < INT32_MIN) && !TARGET_64BIT) +{ + unsigned HOST_WIDE_INT loval = sext_hwi (value, 32); + unsigned HOST_WIDE_INT hival = sext_hwi ((value - loval) >> 32, 32); + struct riscv_integer_op alt_codes[RISCV_MAX_INTEGER_OPS], + hicode[RISCV_MAX_INTEGER_OPS]; + int hi_cost, lo_cost; + + hi_cost = riscv_build_integer_1 (hicode, hival, mode); + if (hi_cost < cost) + { + lo_cost = riscv_build_integer_1 (alt_codes, loval, mode); + if (lo_cost + hi_cost < cost) + { + memcpy (codes, alt_codes, + lo_cost * sizeof (struct riscv_integer_op)); + memcpy (codes + lo_cost, hicode, + hi_cost * sizeof (struct riscv_integer_op)); + cost = lo_cost + hi_cost; + } + } +} + return cost; } diff --git a/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c new file mode 100644 index 000..61d482fb283 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rv32-load-64bit-constant.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32im -mabi=ilp32 -O1" } */ + +/* This test only applies to RV32. Some of 64bit constants in this test will be put +into the constant pool in RV64, since RV64 might need one extra instruction to load +64bit constant. */ + +unsigned long long +rv32_mov_64bit_int1 (void) +{ + return 0x739290001LL; +} + +unsigned long long +rv32_mov_64bit_int2 (void) +{ + return 0x839290001LL; +} + +unsigned long long +rv32_mov_64bit_int3 (void) +{ + return 0x392900013929LL; +} + +unsigned long long +rv32_mov_64bit_int4 (void) +{ + return 0x392900113929LL; +} + +unsigned long long +rv32_mov_64bit_int5 (void) +{ + return 0x14736def3929LL; +} + +/* { dg-final { scan-assembler-not "lw\t" } } */ -- 2.36.0
[PATCH] RISC-V: avoid splitting small constant in i_extrabit pattern
From: Sinan Lin there is no need to split an xori/ori with an small constant. take the test case `int foo(int idx) { return idx|3; }` as an example, rv64im_zba generates: ori a0,a0,3 ret but, rv64im_zba_zbs generates: ori a0,a0,1 ori a0,a0,2 ret with this change, insn `ori r2,r1,3` will not be splitted in zbs. --- gcc/config/riscv/predicates.md | 2 +- .../gcc.target/riscv/zbs-extra-bit-or-twobits.c| 14 ++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-extra-bit-or-twobits.c diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 0d9d7701c7e..8654dbc5943 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -399,7 +399,7 @@ (define_predicate "uimm_extra_bit_or_twobits" (and (match_code "const_int") (ior (match_operand 0 "uimm_extra_bit_operand") - (match_operand 0 "const_twobits_operand" + (match_operand 0 "const_twobits_not_arith_operand" ;; A CONST_INT operand that fits into the negative half of a ;; signed-immediate after a single cleared top bit has been diff --git a/gcc/testsuite/gcc.target/riscv/zbs-extra-bit-or-twobits.c b/gcc/testsuite/gcc.target/riscv/zbs-extra-bit-or-twobits.c new file mode 100644 index 000..ef7ed60461a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zbs-extra-bit-or-twobits.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zbs -mabi=lp64" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ + +int or_two_bit(int idx) { +return idx|3; +} + +int xor_two_bit(int idx) { +return idx^3; +} + +/* { dg-final { scan-assembler-times "\tori\t" 1 } } */ +/* { dg-final { scan-assembler-times "\txori\t" 1 } } */ -- 2.19.1.6.gb485710b
[PATCH] RISC-V: add TARGET_ZBKB to the condition of bswapsi2, bswapdi2 and rotr3 patterns
From: Sinan Lin tell gcc that zbkb has these two spn to enable some optimizations. e.g. 1) the rrotate_expr could match to rotrm3 during expand; 2) hook up __builtin_bswap64 with `rev8` in zbkb64. --- gcc/config/riscv/bitmanip.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index 7aa591689ba..3ed9f5d403a 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -297,7 +297,7 @@ [(set (match_operand:GPR 0 "register_operand") (rotatert:GPR (match_operand:GPR 1 "register_operand") (match_operand:QI 2 "arith_operand")))] - "TARGET_ZBB || TARGET_XTHEADBB" + "TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB" { if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) FAIL; @@ -362,12 +362,12 @@ (define_expand "bswapdi2" [(set (match_operand:DI 0 "register_operand") (bswap:DI (match_operand:DI 1 "register_operand")))] - "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)") + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)") (define_expand "bswapsi2" [(set (match_operand:SI 0 "register_operand") (bswap:SI (match_operand:SI 1 "register_operand")))] - "(!TARGET_64BIT && TARGET_ZBB) || TARGET_XTHEADBB") + "(!TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)) || TARGET_XTHEADBB") (define_insn "*bswap2" [(set (match_operand:X 0 "register_operand" "=r") -- 2.19.1.6.gb485710b