[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.