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 <[email protected]>
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 [email protected]
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