[PATCH v5 13/18] RISC-V: Add POSTINDEX_LD macro-fusion recognition
Jin Ma <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Recognize a scalar integer or floating-point load followed by a non-word ADDI-type in-place update of its base register. Reuse the indexed-memory helper shared with the pre-index rules and accept either load-destination relationship. Leave the fusion disabled by default and XFAIL its positive dump checks until a CPU enables it. gcc/ChangeLog: * config/riscv/riscv-fusion.cc (riscv_fuse_postindex_ld): New function. (riscv_fusion_table): Add RISCV_FUSE_POSTINDEX_LD. * config/riscv/riscv-protos.h (enum riscv_fusion_pairs): Add RISCV_FUSE_POSTINDEX_LD. gcc/testsuite/ChangeLog: * gcc.target/riscv/fusion-load-dest-equal-rtl-postindex.c: New test. * gcc.target/riscv/fusion-postindex-ldst.c: Likewise. Signed-off-by: Jin Ma <[email protected]> --- gcc/config/riscv/riscv-fusion.cc | 24 +++++++++++++ gcc/config/riscv/riscv-protos.h | 1 + .../fusion-load-dest-equal-rtl-postindex.c | 34 +++++++++++++++++++ .../gcc.target/riscv/fusion-postindex-ldst.c | 34 +++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/fusion-load-dest-equal-rtl-postindex.c create mode 100644 gcc/testsuite/gcc.target/riscv/fusion-postindex-ldst.c diff --git a/gcc/config/riscv/riscv-fusion.cc b/gcc/config/riscv/riscv-fusion.cc index b8d3c6d7fa6..0d9870d4b1e 100644 --- a/gcc/config/riscv/riscv-fusion.cc +++ b/gcc/config/riscv/riscv-fusion.cc @@ -1217,6 +1217,28 @@ riscv_fuse_preindex_st (rtx_insn *prev, rtx_insn *curr) return riscv_fuse_indexed_mem_p (prev, curr, false, true); } +/* Check for RISCV_FUSE_POSTINDEX_LD fusion. + prev (one of the following): + (load) == (set (reg rd1) (mem addr)) + (load) == (set (reg rd1) (any_extend (mem addr))) + (fpload) == (set (reg frd) (mem addr)) + addr (one of the following): + (rd2, offset) + (lo_sum (reg rd2) symbol1) + curr (one of the following): + (addi) == (set (reg rd2) (plus (reg rd2) (const_int imm12))) + (self-mv) == (set (reg rd2) (reg rd2)) + (addi) == (set (reg rd2) (lo_sum (reg rd2) symbol2)) + + Constraints: + the ADDI-type instruction is not a word form. */ + +static bool +riscv_fuse_postindex_ld (rtx_insn *prev, rtx_insn *curr) +{ + return riscv_fuse_indexed_mem_p (prev, curr, true, false); +} + /* Check for RISCV_FUSE_LUI_ADDI fusion. prev (one of the following): (lui) == (set (reg rd1) (const_int imm20)) @@ -1738,6 +1760,8 @@ static const struct riscv_fusion_entry riscv_fusion_table[] = riscv_fuse_ldpreincrement, "RISCV_FUSE_LDPREINCREMENT" }, { RISCV_FUSE_PREINDEX_ST, riscv_fuse_preindex_st, "RISCV_FUSE_PREINDEX_ST" }, + { RISCV_FUSE_POSTINDEX_LD, + riscv_fuse_postindex_ld, "RISCV_FUSE_POSTINDEX_LD" }, { RISCV_FUSE_LUI_ADDI, riscv_fuse_lui_addi, "RISCV_FUSE_LUI_ADDI" }, { RISCV_FUSE_AUIPC_ADDI, diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index a40c7d56233..557c8db9111 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -874,6 +874,7 @@ enum riscv_fusion_pairs RISCV_FUSE_SLLI_SRLI = HOST_WIDE_INT_1U << 18, RISCV_FUSE_SRLI_ADD = HOST_WIDE_INT_1U << 19, RISCV_FUSE_PREINDEX_ST = HOST_WIDE_INT_1U << 20, + RISCV_FUSE_POSTINDEX_LD = HOST_WIDE_INT_1U << 21, }; extern bool riscv_macro_fusion_p (void); diff --git a/gcc/testsuite/gcc.target/riscv/fusion-load-dest-equal-rtl-postindex.c b/gcc/testsuite/gcc.target/riscv/fusion-load-dest-equal-rtl-postindex.c new file mode 100644 index 00000000000..72eb79e1ad9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fusion-load-dest-equal-rtl-postindex.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-flto" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O2 -mtune=xt-c9501fdvt -fdump-rtl-sched2-details" } */ +/* { dg-final { scan-rtl-dump-times "RISCV_FUSE_POSTINDEX_LD" 1 "sched2" { xfail *-*-* } } } */ + +/* An unsigned load and update writing the same register should fuse. */ +long __RTL (startwith ("sched2")) +test_postindex_load_same_destination (void) +{ +(function "test_postindex_load_same_destination" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cnote 2 NOTE_INSN_FUNCTION_BEG) + (cinsn 3 (set (reg:DI a0) + (zero_extend:DI + (mem:QI (reg:DI a0) [0 S1 A8])))) + (cinsn 4 (set (reg:DI a0) + (plus:DI (reg:DI a0) + (const_int 1)))) + (cinsn 5 (use (reg:DI a0))) + (cjump_insn 6 (simple_return)) + (edge-to exit) + ) ;; block 2 + (cbarrier 7) + ) ;; insn-chain + (crtl + (return_rtx + (reg/i:DI a0) + ) ;; return_rtx + ) ;; crtl +) ;; function "test_postindex_load_same_destination" +} diff --git a/gcc/testsuite/gcc.target/riscv/fusion-postindex-ldst.c b/gcc/testsuite/gcc.target/riscv/fusion-postindex-ldst.c new file mode 100644 index 00000000000..6e45da46a95 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fusion-postindex-ldst.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-funroll-loops" "-flto" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -mtune=xt-c9501fdvt -O2 -fno-tree-vectorize -fno-unroll-loops -fdump-rtl-sched2-details" } */ +/* { dg-final { scan-rtl-dump-times "RISCV_FUSE_POSTINDEX_LD" 2 "sched2" { xfail *-*-* } } } */ + +typedef signed char int8_t; + +extern void use_ptr (void *); + +int8_t +post_lb (int8_t *src, int n) +{ + int8_t sum = 0; + for (int i = 0; i < n; ++i) + { + sum += *src; + ++src; + } + use_ptr (src); + return sum; +} + +double +post_fld (double *src, int n) +{ + double sum = 0; + for (int i = 0; i < n; ++i) + { + sum += *src; + ++src; + } + use_ptr (src); + return sum; +} -- 2.52.0