This peephole pattern combines the following instructions:
bswap8:
        rev8    a5,a0
        -> li      a4,-65536
        -> srai    a5,a5,32
        -> and     a5,a5,a4
        -> roriw   a5,a5,16
        and     a0,a0,a4
        or      a0,a0,a5
        sext.w  a0,a0
        ret

And emits this assembly:
bswap8:
        rev8    a5,a0
        -> li      a4,-65536
        -> srai    a5,a5,48
        and     a0,a0,a4
        or      a0,a0,a5
        sext.w  a0,a0
        ret

Since the load instruction is required for the rest of the test function
in the PR, the pattern conserves the load.

2025-07-10  Dusan Stojkovic  <dusan.stojko...@rt-rk.com>

        PR target/120920

gcc/ChangeLog:

        * config/riscv/peephole.md: New pattern.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zbb_bswap8.c: New test.


CONFIDENTIALITY: The contents of this e-mail are confidential and intended only 
for the above addressee(s). If you are not the intended recipient, or the 
person responsible for delivering it to the intended recipient, copying or 
delivering it to anyone else or using it in any unauthorized manner is 
prohibited and may be unlawful. If you receive this e-mail by mistake, please 
notify the sender and the systems administrator at straym...@rt-rk.com 
immediately.
---
 gcc/config/riscv/peephole.md                | 28 +++++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/zbb_bswap8.c | 10 ++++++++
 2 files changed, 38 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zbb_bswap8.c

diff --git a/gcc/config/riscv/peephole.md b/gcc/config/riscv/peephole.md
index b5cc1924c76..b07de8bf83e 100644
--- a/gcc/config/riscv/peephole.md
+++ b/gcc/config/riscv/peephole.md
@@ -66,3 +66,31 @@
               (set (match_dup 2)
                    (match_dup 3))])]
 )
+
+;; ZBB
+
+(define_peephole2
+  [(set (match_operand:DI 0 "register_operand")
+    (ashiftrt:DI (match_operand:DI 1 "register_operand")
+      (match_operand 2 "const_int_operand")))
+  (set (match_operand:DI 3 "register_operand")
+    (match_operand 4 "const_int_operand"))
+  (set (match_dup 1)
+    (and:DI (match_dup 1) (match_dup 3)))
+  (set (match_operand:SI 5 "register_operand")
+    (rotatert:SI (match_operand:SI 6 "register_operand")
+      (match_operand 7 "const_int_operand")))]
+  "TARGET_ZBB && TARGET_64BIT
+  && (REGNO (operands[0]) == REGNO (operands[5]))
+  && (REGNO (operands[1]) == REGNO (operands[6]))
+  && (ctz_hwi (INTVAL (operands[4])) == INTVAL (operands[7]))"
+  [(set (match_dup 3)
+    (match_operand 4))
+  (set (match_dup 0)
+    (ashiftrt:DI (match_dup 1)
+      (match_operand 7 "const_int_operand")))]
+{
+  unsigned HOST_WIDE_INT mask = INTVAL (operands[4]);
+  int trailing = ctz_hwi (mask);
+  operands[7] = GEN_INT (trailing + INTVAL (operands[2]));
+})
diff --git a/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c 
b/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c
new file mode 100644
index 00000000000..77441b720b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zbb -mabi=lp64d -O2" { target { rv64 } } } */
+
+unsigned int bswap8(unsigned int n)
+{
+  return (n & 0xffff0000) | ((n & 0xff00) >> 8) | ((n & 0xff) << 8);
+}
+
+/* { dg-final { scan-assembler {\mrev8} } } */
+/* { dg-final { scan-assembler {\msrai\s+[ax][0-9]+,\s*[ax][0-9]+,\s*48} } } */
-- 
2.43.0

Reply via email to