Add missing AArch64 bitreverse expanders so __builtin_bitreverse* can lower to existing rbit patterns.
gcc/testsuite/ChangeLog: - * gcc.target/aarch64/bitreverse.c: New test. gcc/ChangeLog: - * config/aarch64/aarch64.md (bitreverse<mode>2, bitreverseqi2, bitreversehi2): New expanders. - * config/aarch64/aarch64-simd.md (bitreverse<mode>2): New expander. Signed-off-by: Disservin <[email protected]> --- gcc/config/aarch64/aarch64-simd.md | 6 +++ gcc/config/aarch64/aarch64.md | 5 ++ gcc/testsuite/gcc.target/aarch64/bitreverse.c | 50 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/bitreverse.c diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 2e142b1e1ee..f73ff353a6f 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -400,6 +400,12 @@ [(set_attr "type" "neon_rev<q>")] ) +(define_expand "bitreverse<mode>2" + [(set (match_operand:VB 0 "register_operand") + (bitreverse:VB (match_operand:VB 1 "register_operand")))] + "TARGET_SIMD" + "") + (define_insn "aarch64_rbit<mode><vczle><vczbe>" [(set (match_operand:VB 0 "register_operand" "=w") (bitreverse:VB (match_operand:VB 1 "register_operand" "w")))] diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f7e2e4be10e..9441e9d1eae 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -5785,6 +5785,11 @@ [(set_attr "type" "rbit")] ) +(define_expand "bitreverse<mode>2" + [(set (match_operand:GPI 0 "register_operand") + (bitreverse:GPI (match_operand:GPI 1 "register_operand")))] +) + (define_expand "ffs<mode>2" [(match_operand:GPI 0 "register_operand") (match_operand:GPI 1 "register_operand")] diff --git a/gcc/testsuite/gcc.target/aarch64/bitreverse.c b/gcc/testsuite/gcc.target/aarch64/bitreverse.c new file mode 100644 index 00000000000..c6a66d801b1 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/bitreverse.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* +** br8: +** and w0, w0, 255 +** rbit w0, w0 +** lsr w0, w0, 24 +** ret +*/ +[[gnu::noipa]] unsigned char +br8 (unsigned char x) +{ + return __builtin_bitreverse8 (x); +} + +/* +** br16: +** and w0, w0, 65535 +** rbit w0, w0 +** lsr w0, w0, 16 +** ret +*/ +[[gnu::noipa]] unsigned short +br16 (unsigned short x) +{ + return __builtin_bitreverse16 (x); +} + +/* +** br32: +** rbit w0, w0 +** ret +*/ +[[gnu::noipa]] unsigned int +br32 (unsigned int x) +{ + return __builtin_bitreverse32 (x); +} + +/* +** br64: +** rbit x0, x0 +** ret +*/ +[[gnu::noipa]] unsigned long long +br64 (unsigned long long x) +{ + return __builtin_bitreverse64 (x); +} -- 2.34.1
