https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50481
--- Comment #39 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Untested
--- gcc/config/aarch64/aarch64.md.jj 2026-05-23 01:23:05.065826858 +0200
+++ gcc/config/aarch64/aarch64.md 2026-05-23 11:59:11.578144774 +0200
@@ -5790,6 +5790,48 @@ (define_expand "bitreverse<mode>2"
(bitreverse:GPI (match_operand:GPI 1 "register_operand")))]
)
+;; Peephole2s to get rid of useless zero extension from
+;; __builtin_bitreverse{8,16}.
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (zero_extend:SI (match_operand:SHORT 1 "register_operand")))
+ (set (match_operand:SI 2 "register_operand")
+ (bitreverse:SI (match_dup 0)))
+ (set (match_operand:SI 3 "register_operand")
+ (lshiftrt:SI (match_dup 2) (match_operand:SI 4 "const_int_operand")))]
+ "INTVAL (operands[4]) == 32 - GET_MODE_BITSIZE (<MODE>mode)
+ && (REGNO (operands[0]) == REGNO (operands[2])
+ || peep2_reg_dead_p (2, operands[0]))
+ && (REGNO (operands[3]) == REGNO (operands[2])
+ || peep2_reg_dead_p (3, operands[2]))"
+ [(set (match_dup 2) (bitreverse:SI (match_dup 1)))
+ (set (match_dup 3) (lshiftrt:SI (match_dup 2) (match_dup 4)))]
+ {
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }
+)
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand")
+ (zero_extend:SI (match_operand:SHORT 1 "register_operand")))
+ (set (match_operand:SI 2 "register_operand")
+ (bitreverse:SI (match_dup 0)))
+ (set (match_operand:DI 3 "register_operand")
+ (zero_extend:DI (lshiftrt:SI (match_dup 2)
+ (match_operand:SI 4
"const_int_operand"))))]
+ "INTVAL (operands[4]) == 32 - GET_MODE_BITSIZE (<MODE>mode)
+ && (REGNO (operands[0]) == REGNO (operands[2])
+ || peep2_reg_dead_p (2, operands[0]))
+ && (REGNO (operands[3]) == REGNO (operands[2])
+ || peep2_reg_dead_p (3, operands[2]))"
+ [(set (match_dup 2) (bitreverse:SI (match_dup 1)))
+ (set (match_dup 3) (zero_extend:DI (lshiftrt:SI (match_dup 2)
+ (match_dup 4))))]
+ {
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ }
+)
+
(define_expand "ffs<mode>2"
[(match_operand:GPI 0 "register_operand")
(match_operand:GPI 1 "register_operand")]
removes the zero extensions from
unsigned char foo (unsigned char x) { return __builtin_bitreverse8 (x); }
unsigned short bar (unsigned short x) { return __builtin_bitreverse16 (x); }
unsigned char a;
void baz (unsigned char x) { a = __builtin_bitreverse8 (x); }
unsigned short b;
void qux (unsigned short x) { b = __builtin_bitreverse16 (x); }