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); }

Reply via email to