Hi Jeff,

>> So I'm not sure this transformation is correct.
>>
>> Let's consider the case where a5 has the value 0xffff000000000000 at the
>>"li" instruction.
>>
>> a5 = 0xff00000000000000
>>
>> li a4, -65536 // a4 = 0xffffffffffff0000
>> srai a5,a5,32 // a5 = 0xffffffffff000000
>> and a5,a5,a4 // a5 = 0xffffffffff000000
>> roriw a5,a5,16 // a5 = 0x000000000000ff00
>>
>> So with your change:
>> a5 = 0xff00000000000000
>> li a4, -65536 // a4 = 0xffffffffffff0000
>> srai a5,a5,48 // a5 = 0xfffffffffffff000
>>
>> Am I missing something?
>>
>> Jeff

Thank you for the review.

You are correct, I mistakenly used an arithmetic shift instead of a logical
right shift. There were also testsuite failures with rv32 but the test should
be executed on rv64 only.

This was addressed. The peephole pattern transforms:
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
        -> srli    a5,a5,48
        and     a0,a0,a4
        or      a0,a0,a5
        sext.w  a0,a0
        ret

Basically if after rev8 a5 has it's MSB set to 1 then the arithmetic right
shift will set all other bits to the value of MSB as per your example.

The logical shift here ensures that this is not the case.
# after rev8:
a5 = 0xff00000000000000
...
srli a5,a5,48  # a5 := 0x00000000ff00
...

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

        PR target/120920

gcc/ChangeLog:

        * config/riscv/peephole.md: New bswap8 zbb 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..ee156e95027 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)
+       (lshiftrt: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..0a6c4dda3ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zbb_bswap8.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-march=rv64gc_zbb -mabi=lp64d -O2" } */
+
+unsigned int foo(unsigned int n)
+{
+  return (n & 0xffff0000) | ((n & 0xff00) >> 8) | ((n & 0xff) << 8);
+}
+
+/* { dg-final { scan-assembler {\mrev8} } } */
+/* { dg-final { scan-assembler {\msrli\s+[ax][0-9]+,\s*[ax][0-9]+,\s*48} } } */
-- 
2.43.0

Reply via email to