diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2014-04-24 08:05:07 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2014-04-24 08:05:07 +0000 |
commit | c7f28cd58e12391f8e4e5c50968ed1c76ddbddb0 (patch) | |
tree | d75eb1689e288d18f6af7502ba97ab07a3ee2e05 /gcc | |
parent | b041949151f3ba686dc6e8fe0ced121aef9347f2 (diff) | |
download | gcc-c7f28cd58e12391f8e4e5c50968ed1c76ddbddb0.zip gcc-c7f28cd58e12391f8e4e5c50968ed1c76ddbddb0.tar.gz gcc-c7f28cd58e12391f8e4e5c50968ed1c76ddbddb0.tar.bz2 |
[AArch64] Vectorise bswap[16,32,64]
* config/aarch64/aarch64-builtins.c
(aarch64_builtin_vectorized_function): Handle BUILT_IN_BSWAP16,
BUILT_IN_BSWAP32, BUILT_IN_BSWAP64.
* config/aarch64/aarch64-simd.md (bswap<mode>): New pattern.
* config/aarch64/aarch64-simd-builtins.def: Define vector bswap
builtins.
* config/aarch64/iterator.md (VDQHSD): New mode iterator.
(Vrevsuff): New mode attribute.
* lib/target-supports.exp (check_effective_target_vect_bswap): New.
* gcc.dg/vect/vect-bswap16: New test.
* gcc.dg/vect/vect-bswap32: Likewise.
* gcc.dg/vect/vect-bswap64: Likewise.
From-SVN: r209736
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-builtins.c | 24 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd-builtins.def | 2 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 8 | ||||
-rw-r--r-- | gcc/config/aarch64/iterators.md | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-bswap16.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-bswap32.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-bswap64.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 18 |
10 files changed, 207 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db6d73f..6b419f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2014-04-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * config/aarch64/aarch64-builtins.c + (aarch64_builtin_vectorized_function): Handle BUILT_IN_BSWAP16, + BUILT_IN_BSWAP32, BUILT_IN_BSWAP64. + * config/aarch64/aarch64-simd.md (bswap<mode>): New pattern. + * config/aarch64/aarch64-simd-builtins.def: Define vector bswap + builtins. + * config/aarch64/iterator.md (VDQHSD): New mode iterator. + (Vrevsuff): New mode attribute. + 2014-04-24 Terry Guo <terry.guo@arm.com> * config/arm/arm.h (machine_function): Define variable diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 591260f..4616ad2 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -1104,7 +1104,29 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in) return aarch64_builtin_decls[builtin]; } - + case BUILT_IN_BSWAP16: +#undef AARCH64_CHECK_BUILTIN_MODE +#define AARCH64_CHECK_BUILTIN_MODE(C, N) \ + (out_mode == N##Imode && out_n == C \ + && in_mode == N##Imode && in_n == C) + if (AARCH64_CHECK_BUILTIN_MODE (4, H)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4hi]; + else if (AARCH64_CHECK_BUILTIN_MODE (8, H)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi]; + else + return NULL_TREE; + case BUILT_IN_BSWAP32: + if (AARCH64_CHECK_BUILTIN_MODE (2, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2si]; + else if (AARCH64_CHECK_BUILTIN_MODE (4, S)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4si]; + else + return NULL_TREE; + case BUILT_IN_BSWAP64: + if (AARCH64_CHECK_BUILTIN_MODE (2, D)) + return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di]; + else + return NULL_TREE; default: return NULL_TREE; } diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index bfd2b75..fa332ae 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -341,6 +341,8 @@ VAR1 (UNOP, floatunsv4si, 2, v4sf) VAR1 (UNOP, floatunsv2di, 2, v2df) + VAR5 (UNOPU, bswap, 10, v4hi, v8hi, v2si, v4si, v2di) + /* Implemented by aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>. */ BUILTIN_VALL (BINOP, zip1, 0) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 285d839..c05767b 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -286,6 +286,14 @@ [(set_attr "type" "neon_mul_<Vetype><q>")] ) +(define_insn "bswap<mode>" + [(set (match_operand:VDQHSD 0 "register_operand" "=w") + (bswap:VDQHSD (match_operand:VDQHSD 1 "register_operand" "w")))] + "TARGET_SIMD" + "rev<Vrevsuff>\\t%0.<Vbtype>, %1.<Vbtype>" + [(set_attr "type" "neon_rev<q>")] +) + (define_insn "*aarch64_mul3_elt<mode>" [(set (match_operand:VMUL 0 "register_operand" "=w") (mult:VMUL diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 03b1889..fd1eb48 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -150,6 +150,9 @@ ;; Vector modes for H and S types. (define_mode_iterator VDQHS [V4HI V8HI V2SI V4SI]) +;; Vector modes for H, S and D types. +(define_mode_iterator VDQHSD [V4HI V8HI V2SI V4SI V2DI]) + ;; Vector modes for Q, H and S types. (define_mode_iterator VDQQHS [V8QI V16QI V4HI V8HI V2SI V4SI]) @@ -356,6 +359,9 @@ (V2DI "2d") (V2SF "2s") (V4SF "4s") (V2DF "2d")]) +(define_mode_attr Vrevsuff [(V4HI "16") (V8HI "16") (V2SI "32") + (V4SI "32") (V2DI "64")]) + (define_mode_attr Vmtype [(V8QI ".8b") (V16QI ".16b") (V4HI ".4h") (V8HI ".8h") (V2SI ".2s") (V4SI ".4s") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62b07f4..40df580 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-04-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * lib/target-supports.exp (check_effective_target_vect_bswap): New. + * gcc.dg/vect/vect-bswap16: New test. + * gcc.dg/vect/vect-bswap32: Likewise. + * gcc.dg/vect/vect-bswap64: Likewise. + 2014-04-23 Jeff Law <law@redhat.com> PR tree-optimization/60902 diff --git a/gcc/testsuite/gcc.dg/vect/vect-bswap16.c b/gcc/testsuite/gcc.dg/vect/vect-bswap16.c new file mode 100644 index 0000000..c562718 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bswap16.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_bswap } */ + +#include "tree-vect.h" + +#define N 128 + +volatile int y = 0; + +static inline void +vfoo16 (unsigned short int* a) +{ + int i = 0; + for (i = 0; i < N; ++i) + a[i] = __builtin_bswap16 (a[i]); +} + +int +main (void) +{ + unsigned short arr[N]; + unsigned short expect[N]; + int i; + + for (i = 0; i < N; ++i) + { + arr[i] = i; + expect[i] = __builtin_bswap16 (i); + if (y) /* Avoid vectorisation. */ + abort (); + } + + vfoo16 (arr); + + for (i = 0; i < N; ++i) + { + if (arr[i] != expect[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bswap32.c b/gcc/testsuite/gcc.dg/vect/vect-bswap32.c new file mode 100644 index 0000000..9596677 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bswap32.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_bswap } */ + +#include "tree-vect.h" + +#define N 128 + +volatile int y = 0; + +static inline void +vfoo32 (unsigned int* a) +{ + int i = 0; + for (i = 0; i < N; ++i) + a[i] = __builtin_bswap32 (a[i]); +} + +int +main (void) +{ + unsigned int arr[N]; + unsigned int expect[N]; + int i; + + for (i = 0; i < N; ++i) + { + arr[i] = i; + expect[i] = __builtin_bswap32 (i); + if (y) /* Avoid vectorisation. */ + abort (); + } + + vfoo32 (arr); + + for (i = 0; i < N; ++i) + { + if (arr[i] != expect[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bswap64.c b/gcc/testsuite/gcc.dg/vect/vect-bswap64.c new file mode 100644 index 0000000..088c8c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bswap64.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_bswap } */ + +#include "tree-vect.h" + +#define N 128 + +volatile int y = 0; + +static inline void +vfoo64 (unsigned long long* a) +{ + int i = 0; + for (i = 0; i < N; ++i) + a[i] = __builtin_bswap64 (a[i]); +} + +int +main (void) +{ + unsigned long long arr[N]; + unsigned long long expect[N]; + int i; + + for (i = 0; i < N; ++i) + { + arr[i] = i; + expect[i] = __builtin_bswap64 (i); + if (y) /* Avoid vectorisation. */ + abort (); + } + + vfoo64 (arr); + + for (i = 0; i < N; ++i) + { + if (arr[i] != expect[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 541a428..badfac3 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3271,6 +3271,24 @@ proc check_effective_target_vect_shift { } { return $et_vect_shift_saved } +# Return 1 if the target supports vector bswap operations. + +proc check_effective_target_vect_bswap { } { + global et_vect_bswap_saved + + if [info exists et_vect_bswap_saved] { + verbose "check_effective_target_vect_bswap: using cached result" 2 + } else { + set et_vect_bswap_saved 0 + if { [istarget aarch64*-*-*] } { + set et_vect_bswap_saved 1 + } + } + + verbose "check_effective_target_vect_bswap: returning $et_vect_bswap_saved" 2 + return $et_vect_bswap_saved +} + # Return 1 if the target supports hardware vector shift operation for char. proc check_effective_target_vect_shift_char { } { |