[PATCH v5 12/18] RISC-V: Add PREINDEX_ST macro-fusion recognition

Jin Ma <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Recognize a non-word ADDI-type in-place address update followed by a
scalar integer or floating-point store.  Reuse the indexed-memory helper
shared with LDPREINCREMENT, including its store-source constraint.

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_preindex_st): New
	function.
	(riscv_fusion_table): Add RISCV_FUSE_PREINDEX_ST.
	* config/riscv/riscv-protos.h (enum riscv_fusion_pairs): Add
	RISCV_FUSE_PREINDEX_ST.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/fusion-memory-rtl-shapes-preindex-st.c: New test.
	* gcc.target/riscv/fusion-preindex-st.c: Likewise.

Signed-off-by: Jin Ma <[email protected]>
---
 gcc/config/riscv/riscv-fusion.cc              | 25 ++++++++++++++
 gcc/config/riscv/riscv-protos.h               |  1 +
 .../fusion-memory-rtl-shapes-preindex-st.c    | 33 +++++++++++++++++++
 .../gcc.target/riscv/fusion-preindex-st.c     | 27 +++++++++++++++
 4 files changed, 86 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/fusion-memory-rtl-shapes-preindex-st.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/fusion-preindex-st.c

diff --git a/gcc/config/riscv/riscv-fusion.cc b/gcc/config/riscv/riscv-fusion.cc
index c6e7073cb23..b8d3c6d7fa6 100644
--- a/gcc/config/riscv/riscv-fusion.cc
+++ b/gcc/config/riscv/riscv-fusion.cc
@@ -1194,6 +1194,29 @@ riscv_fuse_ldpreincrement (rtx_insn *prev, rtx_insn *curr)
   return riscv_fuse_indexed_mem_p (prev, curr, true, true);
 }
 
+/* Check for RISCV_FUSE_PREINDEX_ST fusion.
+   prev (one of the following):
+     (addi) == (set (reg rd1) (plus (reg rd1) (const_int imm12)))
+     (self-mv) == (set (reg rd1) (reg rd1))
+     (addi) == (set (reg rd1) (lo_sum (reg rd1) symbol1))
+   curr (one of the following):
+     (store) == (set (mem addr) (reg rs1))
+     (store) == (set (mem addr) (const_int 0))
+     (fpstore) == (set (mem addr) (reg frs1))
+   addr (one of the following):
+     (rd1, offset)
+     (lo_sum (reg rd1) symbol2)
+
+   Constraints:
+     the ADDI-type instruction is not a word form
+     for a register-source integer store, rd1 != rs1.  */
+
+static bool
+riscv_fuse_preindex_st (rtx_insn *prev, rtx_insn *curr)
+{
+  return riscv_fuse_indexed_mem_p (prev, curr, false, true);
+}
+
 /* Check for RISCV_FUSE_LUI_ADDI fusion.
    prev (one of the following):
      (lui) == (set (reg rd1) (const_int imm20))
@@ -1713,6 +1736,8 @@ static const struct riscv_fusion_entry riscv_fusion_table[] =
     riscv_fuse_expanded_ld, "RISCV_FUSE_EXPANDED_LD" },
   { RISCV_FUSE_LDPREINCREMENT,
     riscv_fuse_ldpreincrement, "RISCV_FUSE_LDPREINCREMENT" },
+  { RISCV_FUSE_PREINDEX_ST,
+    riscv_fuse_preindex_st, "RISCV_FUSE_PREINDEX_ST" },
   { 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 c107a574ad6..a40c7d56233 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -873,6 +873,7 @@ enum riscv_fusion_pairs
   RISCV_FUSE_LOGIC_LOGIC = HOST_WIDE_INT_1U << 17,
   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,
 };
 
 extern bool riscv_macro_fusion_p (void);
diff --git a/gcc/testsuite/gcc.target/riscv/fusion-memory-rtl-shapes-preindex-st.c b/gcc/testsuite/gcc.target/riscv/fusion-memory-rtl-shapes-preindex-st.c
new file mode 100644
index 00000000000..b490927e2df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/fusion-memory-rtl-shapes-preindex-st.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" } */
+/* { dg-final { scan-rtl-dump-times "RISCV_FUSE_PREINDEX_ST" 1 "sched2" { xfail *-*-* } } } */
+
+/* Pre-index update followed by a store of the zero register should fuse.  */
+long __RTL (startwith ("sched2"))
+test_preindex_store_zero (void)
+{
+(function "test_preindex_store_zero"
+  (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)
+                    (plus:DI (reg:DI a0)
+                             (const_int 8))))
+      (cinsn 4 (set (mem:DI (reg:DI a0) [0  S8 A64])
+                    (const_int 0)))
+      (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_preindex_store_zero"
+}
diff --git a/gcc/testsuite/gcc.target/riscv/fusion-preindex-st.c b/gcc/testsuite/gcc.target/riscv/fusion-preindex-st.c
new file mode 100644
index 00000000000..4979154e654
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/fusion-preindex-st.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O3" "-O[sgz]" "-funroll-loops" "-flto" } } */
+/* { dg-options "-march=rv64gc_zfh -mabi=lp64d -mtune=xt-c9501fdvt -O2 -fdump-rtl-sched2-details" } */
+/* { dg-final { scan-rtl-dump-times "RISCV_FUSE_PREINDEX_ST" 2 "sched2" { xfail *-*-* } } } */
+
+typedef signed char int8_t;
+/* Pre-increment store of a byte should fuse.  */
+void
+test_preindex_sb (int8_t *p, int8_t value, int n)
+{
+  for (int i = 0; i < n; ++i)
+    {
+      p += 2;
+      *p = value;
+    }
+}
+
+/* Pre-increment store of a double should fuse.  */
+void
+test_preindex_fsd (double *p, double value, int n)
+{
+  for (int i = 0; i < n; ++i)
+    {
+      p += 2;
+      *p = value;
+    }
+}
-- 
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.