| // REQUIRES: aarch64-registered-target |
| // -fopemp and -fopenmp-simd behavior are expected to be the same. |
| |
| // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s --check-prefix=AARCH64 |
| // RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -fopenmp-simd -x c -emit-llvm %s -o - -femit-all-decls | FileCheck %s --check-prefix=AARCH64 |
| |
| #pragma omp declare simd |
| #pragma omp declare simd simdlen(2) |
| #pragma omp declare simd simdlen(6) |
| #pragma omp declare simd simdlen(8) |
| double foo(float x); |
| |
| // AARCH64: "_ZGVnM2v_foo" "_ZGVnM4v_foo" "_ZGVnM8v_foo" "_ZGVnN2v_foo" "_ZGVnN4v_foo" "_ZGVnN8v_foo" |
| // AARCH64-NOT: _ZGVnN6v_foo |
| |
| void foo_loop(double *x, float *y, int N) { |
| for (int i = 0; i < N; ++i) { |
| x[i] = foo(y[i]); |
| } |
| } |
| |
| // make sure that the following two function by default gets generated |
| // with 4 and 2 lanes, as descrived in the vector ABI |
| #pragma omp declare simd notinbranch |
| float bar(double x); |
| #pragma omp declare simd notinbranch |
| double baz(float x); |
| |
| // AARCH64: "_ZGVnN2v_baz" "_ZGVnN4v_baz" |
| // AARCH64-NOT: baz |
| // AARCH64: "_ZGVnN2v_bar" "_ZGVnN4v_bar" |
| // AARCH64-NOT: bar |
| |
| void baz_bar_loop(double *x, float *y, int N) { |
| for (int i = 0; i < N; ++i) { |
| x[i] = baz(y[i]); |
| y[i] = bar(x[i]); |
| } |
| } |
| |
| /***************************/ |
| /* 32-bit integer tests */ |
| /***************************/ |
| |
| #pragma omp declare simd |
| #pragma omp declare simd simdlen(2) |
| #pragma omp declare simd simdlen(6) |
| #pragma omp declare simd simdlen(8) |
| long foo_int(int x); |
| |
| // AARCH64: "_ZGVnN2v_foo_int" "_ZGVnN4v_foo_int" "_ZGVnN8v_foo_int" |
| // No non power of two |
| // AARCH64-NOT: _ZGVnN6v_foo_int |
| |
| void foo_int_loop(long *x, int *y, int N) { |
| for (int i = 0; i < N; ++i) { |
| x[i] = foo_int(y[i]); |
| } |
| } |
| |
| #pragma omp declare simd |
| char simple_8bit(char); |
| // AARCH64: "_ZGVnM16v_simple_8bit" "_ZGVnM8v_simple_8bit" "_ZGVnN16v_simple_8bit" "_ZGVnN8v_simple_8bit" |
| #pragma omp declare simd |
| short simple_16bit(short); |
| // AARCH64: "_ZGVnM4v_simple_16bit" "_ZGVnM8v_simple_16bit" "_ZGVnN4v_simple_16bit" "_ZGVnN8v_simple_16bit" |
| #pragma omp declare simd |
| int simple_32bit(int); |
| // AARCH64: "_ZGVnM2v_simple_32bit" "_ZGVnM4v_simple_32bit" "_ZGVnN2v_simple_32bit" "_ZGVnN4v_simple_32bit" |
| #pragma omp declare simd |
| long simple_64bit(long); |
| // AARCH64: "_ZGVnM2v_simple_64bit" "_ZGVnN2v_simple_64bit" |
| |
| #pragma omp declare simd |
| #pragma omp declare simd simdlen(32) |
| char a01(int x); |
| // AARCH64: "_ZGVnN16v_a01" "_ZGVnN32v_a01" "_ZGVnN8v_a01" |
| // AARCH64-NOT: a01 |
| |
| #pragma omp declare simd |
| #pragma omp declare simd simdlen(2) |
| long a02(short x); |
| // AARCH64: "_ZGVnN2v_a02" "_ZGVnN4v_a02" "_ZGVnN8v_a02" |
| |
| // AARCH64-NOT: a02 |
| /************/ |
| /* pointers */ |
| /************/ |
| |
| #pragma omp declare simd |
| int b01(int *x); |
| // AARCH64: "_ZGVnN4v_b01" |
| // AARCH64-NOT: b01 |
| |
| #pragma omp declare simd |
| char b02(char *); |
| // AARCH64: "_ZGVnN16v_b02" "_ZGVnN8v_b02" |
| // AARCH64-NOT: b02 |
| |
| #pragma omp declare simd |
| double *b03(double *); |
| // AARCH64: "_ZGVnN2v_b03" |
| // AARCH64-NOT: b03 |
| |
| /***********/ |
| /* masking */ |
| /***********/ |
| |
| #pragma omp declare simd inbranch |
| int c01(double *x, short y); |
| // AARCH64: "_ZGVnM8vv_c01" |
| // AARCH64-NOT: c01 |
| |
| #pragma omp declare simd inbranch uniform(x) |
| double c02(double *x, char y); |
| // AARCH64: "_ZGVnM16uv_c02" "_ZGVnM8uv_c02" |
| // AARCH64-NOT: c02 |
| |
| /*************************/ |
| /* sincos-like signature */ |
| /*************************/ |
| #pragma omp declare simd linear(sin) linear(cos) |
| void sincos(double in, double *sin, double *cos); |
| // AARCH64: "_ZGVnN2vll_sincos" |
| // AARCH64-NOT: sincos |
| |
| #pragma omp declare simd linear(sin : 1) linear(cos : 2) |
| void SinCos(double in, double *sin, double *cos); |
| // AARCH64: "_ZGVnN2vll2_SinCos" |
| // AARCH64-NOT: SinCos |
| |
| // Selection of tests based on the examples provided in chapter 5 of |
| // the Vector Function ABI specifications for AArch64, at |
| // https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi. |
| |
| // Listing 2, p. 18 |
| #pragma omp declare simd inbranch uniform(x) linear(val(i) : 4) |
| int foo2(int *x, int i); |
| // AARCH64: "_ZGVnM2ul4_foo2" "_ZGVnM4ul4_foo2" |
| // AARCH64-NOT: foo2 |
| |
| // Listing 3, p. 18 |
| #pragma omp declare simd inbranch uniform(x, c) linear(i \ |
| : c) |
| int foo3(int *x, int i, unsigned char c); |
| // AARCH64: "_ZGVnM16uls2u_foo3" "_ZGVnM8uls2u_foo3" |
| // AARCH64-NOT: foo3 |
| |
| // Listing 6, p. 19 |
| #pragma omp declare simd linear(x) aligned(x : 16) simdlen(4) |
| int foo4(int *x, float y); |
| // AARCH64: "_ZGVnM4la16v_foo4" "_ZGVnN4la16v_foo4" |
| // AARCH64-NOT: foo4 |
| |
| static int *I; |
| static char *C; |
| static short *S; |
| static long *L; |
| static float *F; |
| static double *D; |
| void do_something() { |
| simple_8bit(*C); |
| simple_16bit(*S); |
| simple_32bit(*I); |
| simple_64bit(*L); |
| *C = a01(*I); |
| *L = a02(*S); |
| *I = b01(I); |
| *C = b02(C); |
| D = b03(D); |
| *I = c01(D, *S); |
| *D = c02(D, *S); |
| sincos(*D, D, D); |
| SinCos(*D, D, D); |
| foo2(I, *I); |
| foo3(I, *I, *C); |
| foo4(I, *F); |
| } |
| |
| typedef struct S { |
| char R, G, B; |
| } STy; |
| #pragma omp declare simd notinbranch |
| STy DoRGB(STy x); |
| // AARCH64: "_ZGVnN2v_DoRGB" |
| |
| static STy *RGBData; |
| |
| void do_rgb_stuff() { |
| DoRGB(*RGBData); |
| } |