[PATCH v5 16/18] RISC-V: Add descending integer load/store pair fusion
Jin Ma <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Recognize the descending-address counterpart of the integer load/store pair fusion. Reuse the common pair matcher and select the reversed one-access-size offset 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_ldst_pair_dec): New function. (riscv_fusion_table): Add RISCV_FUSE_LDST_PAIR_DEC. * config/riscv/riscv-protos.h (enum riscv_fusion_pairs): Add RISCV_FUSE_LDST_PAIR_DEC. gcc/testsuite/ChangeLog: * gcc.target/riscv/fusion-ldst-pair-dec.c: New test. Signed-off-by: Jin Ma <[email protected]> --- gcc/config/riscv/riscv-fusion.cc | 22 +++++++++++++ gcc/config/riscv/riscv-protos.h | 1 + .../gcc.target/riscv/fusion-ldst-pair-dec.c | 33 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/fusion-ldst-pair-dec.c diff --git a/gcc/config/riscv/riscv-fusion.cc b/gcc/config/riscv/riscv-fusion.cc index 419628a5038..e150b53c63b 100644 --- a/gcc/config/riscv/riscv-fusion.cc +++ b/gcc/config/riscv/riscv-fusion.cc @@ -1533,6 +1533,26 @@ riscv_fuse_ldst_pair_inc (rtx_insn *prev, rtx_insn *curr) return riscv_fuse_ldst_pair_p (prev, curr, true, false); } +/* Check for RISCV_FUSE_LDST_PAIR_DEC fusion. + prev/curr (one of the following pairs): + prev (lw/ld) == (set (reg rd1) (mem (rs1, offset1))) + curr (lw/ld) == (set (reg rd2) (mem (rs1, offset2))) + + prev (sw/sd) == (set (mem (rs1, offset1)) (reg rs2)) + curr (sw/sd) == (set (mem (rs1, offset2)) (reg rs3)) + + Constraints: + access size is 4 or 8 bytes + offset1 - offset2 equals the access size + loads are not zero-extending + for loads, rd1 != rd2 and rd1 != rs1. */ + +static bool +riscv_fuse_ldst_pair_dec (rtx_insn *prev, rtx_insn *curr) +{ + return riscv_fuse_ldst_pair_p (prev, curr, false, false); +} + /* Check for RISCV_FUSE_BFEXT fusion. prev (slli) == (set (reg rd1) (ashift (reg rs1) (const_int shamt1))) @@ -1878,6 +1898,8 @@ static const struct riscv_fusion_entry riscv_fusion_table[] = riscv_fuse_aligned_std, "RISCV_FUSE_ALIGNED_STD" }, { RISCV_FUSE_LDST_PAIR_INC, riscv_fuse_ldst_pair_inc, "RISCV_FUSE_LDST_PAIR_INC" }, + { RISCV_FUSE_LDST_PAIR_DEC, + riscv_fuse_ldst_pair_dec, "RISCV_FUSE_LDST_PAIR_DEC" }, { RISCV_FUSE_BFEXT, riscv_fuse_bfext, "RISCV_FUSE_BFEXT" }, { RISCV_FUSE_SLLI_SRLI, diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index de4476a2d66..3a14108ef19 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -877,6 +877,7 @@ enum riscv_fusion_pairs RISCV_FUSE_POSTINDEX_LD = HOST_WIDE_INT_1U << 21, RISCV_FUSE_POSTINDEX_ST = HOST_WIDE_INT_1U << 22, RISCV_FUSE_LDST_PAIR_INC = HOST_WIDE_INT_1U << 23, + RISCV_FUSE_LDST_PAIR_DEC = HOST_WIDE_INT_1U << 24, }; extern bool riscv_macro_fusion_p (void); diff --git a/gcc/testsuite/gcc.target/riscv/fusion-ldst-pair-dec.c b/gcc/testsuite/gcc.target/riscv/fusion-ldst-pair-dec.c new file mode 100644 index 00000000000..1a9373cd2d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/fusion-ldst-pair-dec.c @@ -0,0 +1,33 @@ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-flto" } } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -mtune=xt-c9501fdvt -O2 -fdump-rtl-sched2-details" } */ +/* { dg-final { scan-rtl-dump-times "RISCV_FUSE_LDST_PAIR_DEC" 4 "sched2" { xfail *-*-* } } } */ + +typedef int int32_t; +typedef long int64_t; + +int64_t +test_ld_pair_dec (int64_t *p) +{ + return p[1] + p[0]; +} + +int64_t +test_lw_pair_dec (int32_t *p) +{ + return (int64_t) p[1] + p[0]; +} + +void +test_sd_pair_dec (int64_t *p, int64_t a, int64_t b) +{ + p[1] = b; + p[0] = a; +} + +void +test_sw_pair_dec (int32_t *p, int32_t a, int32_t b) +{ + p[1] = b; + p[0] = a; +} -- 2.52.0