1 // REQUIRES: aarch64-registered-target
2 // -fopemp and -fopenmp-simd behavior are expected to be the same.
3 
4 // 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
5 // 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
6 
7 #pragma omp declare simd
8 #pragma omp declare simd simdlen(2)
9 #pragma omp declare simd simdlen(6)
10 #pragma omp declare simd simdlen(8)
11 double foo(float x);
12 
13 // AARCH64: "_ZGVnM2v_foo" "_ZGVnM4v_foo" "_ZGVnM8v_foo" "_ZGVnN2v_foo" "_ZGVnN4v_foo" "_ZGVnN8v_foo"
14 // AARCH64-NOT: _ZGVnN6v_foo
15 
foo_loop(double * x,float * y,int N)16 void foo_loop(double *x, float *y, int N) {
17   for (int i = 0; i < N; ++i) {
18     x[i] = foo(y[i]);
19   }
20 }
21 
22 // make sure that the following two function by default gets generated
23 // with 4 and 2 lanes, as descrived in the vector ABI
24 #pragma omp declare simd notinbranch
25 float bar(double x);
26 #pragma omp declare simd notinbranch
27 double baz(float x);
28 
29 // AARCH64: "_ZGVnN2v_baz" "_ZGVnN4v_baz"
30 // AARCH64-NOT: baz
31 // AARCH64: "_ZGVnN2v_bar" "_ZGVnN4v_bar"
32 // AARCH64-NOT: bar
33 
baz_bar_loop(double * x,float * y,int N)34 void baz_bar_loop(double *x, float *y, int N) {
35   for (int i = 0; i < N; ++i) {
36     x[i] = baz(y[i]);
37     y[i] = bar(x[i]);
38   }
39 }
40 
41   /***************************/
42   /*  32-bit integer tests   */
43   /***************************/
44 
45 #pragma omp declare simd
46 #pragma omp declare simd simdlen(2)
47 #pragma omp declare simd simdlen(6)
48 #pragma omp declare simd simdlen(8)
49 long foo_int(int x);
50 
51 // AARCH64: "_ZGVnN2v_foo_int" "_ZGVnN4v_foo_int" "_ZGVnN8v_foo_int"
52 // No non power of two
53 // AARCH64-NOT: _ZGVnN6v_foo_int
54 
foo_int_loop(long * x,int * y,int N)55 void foo_int_loop(long *x, int *y, int N) {
56   for (int i = 0; i < N; ++i) {
57     x[i] = foo_int(y[i]);
58   }
59 }
60 
61 #pragma omp declare simd
62 char simple_8bit(char);
63 // AARCH64: "_ZGVnM16v_simple_8bit" "_ZGVnM8v_simple_8bit" "_ZGVnN16v_simple_8bit" "_ZGVnN8v_simple_8bit"
64 #pragma omp declare simd
65 short simple_16bit(short);
66 // AARCH64: "_ZGVnM4v_simple_16bit" "_ZGVnM8v_simple_16bit" "_ZGVnN4v_simple_16bit" "_ZGVnN8v_simple_16bit"
67 #pragma omp declare simd
68 int simple_32bit(int);
69 // AARCH64: "_ZGVnM2v_simple_32bit" "_ZGVnM4v_simple_32bit" "_ZGVnN2v_simple_32bit" "_ZGVnN4v_simple_32bit"
70 #pragma omp declare simd
71 long simple_64bit(long);
72 // AARCH64: "_ZGVnM2v_simple_64bit" "_ZGVnN2v_simple_64bit"
73 
74 #pragma omp declare simd
75 #pragma omp declare simd simdlen(32)
76 char a01(int x);
77 // AARCH64: "_ZGVnN16v_a01" "_ZGVnN32v_a01" "_ZGVnN8v_a01"
78 // AARCH64-NOT: a01
79 
80 #pragma omp declare simd
81 #pragma omp declare simd simdlen(2)
82 long a02(short x);
83 // AARCH64:  "_ZGVnN2v_a02" "_ZGVnN4v_a02" "_ZGVnN8v_a02"
84 
85 // AARCH64-NOT: a02
86 /************/
87 /* pointers */
88 /************/
89 
90 #pragma omp declare simd
91 int b01(int *x);
92 // AARCH64: "_ZGVnN4v_b01"
93 // AARCH64-NOT: b01
94 
95 #pragma omp declare simd
96 char b02(char *);
97 // AARCH64: "_ZGVnN16v_b02" "_ZGVnN8v_b02"
98 // AARCH64-NOT: b02
99 
100 #pragma omp declare simd
101 double *b03(double *);
102 // AARCH64: "_ZGVnN2v_b03"
103 // AARCH64-NOT: b03
104 
105 /***********/
106 /* masking */
107 /***********/
108 
109 #pragma omp declare simd inbranch
110 int c01(double *x, short y);
111 // AARCH64: "_ZGVnM8vv_c01"
112 // AARCH64-NOT: c01
113 
114 #pragma omp declare simd inbranch uniform(x)
115 double c02(double *x, char y);
116 // AARCH64: "_ZGVnM16uv_c02" "_ZGVnM8uv_c02"
117 // AARCH64-NOT: c02
118 
119 /************************************/
120 /* Linear with a constant parameter */
121 /************************************/
122 
123 #pragma omp declare simd notinbranch linear(i)
124 double constlinear(const int i);
125 // AARCH64: "_ZGVnN2l_constlinear" "_ZGVnN4l_constlinear"
126 // AARCH64-NOT: constlinear
127 
128 /*************************/
129 /* sincos-like signature */
130 /*************************/
131 #pragma omp declare simd linear(sin) linear(cos)
132 void sincos(double in, double *sin, double *cos);
133 // AARCH64: "_ZGVnN2vl8l8_sincos"
134 // AARCH64-NOT: sincos
135 
136 #pragma omp declare simd linear(sin : 1) linear(cos : 2)
137 void SinCos(double in, double *sin, double *cos);
138 // AARCH64: "_ZGVnN2vl8l16_SinCos"
139 // AARCH64-NOT: SinCos
140 
141 // Selection of tests based on the examples provided in chapter 5 of
142 // the Vector Function ABI specifications for AArch64, at
143 // https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
144 
145 // Listing 2, p. 18
146 #pragma omp declare simd inbranch uniform(x) linear(val(i) : 4)
147 int foo2(int *x, int i);
148 // AARCH64: "_ZGVnM2ul4_foo2" "_ZGVnM4ul4_foo2"
149 // AARCH64-NOT: foo2
150 
151 // Listing 3, p. 18
152 #pragma omp declare simd inbranch uniform(x, c) linear(i \
153                                                        : c)
154 int foo3(int *x, int i, unsigned char c);
155 // AARCH64: "_ZGVnM16uls2u_foo3" "_ZGVnM8uls2u_foo3"
156 // AARCH64-NOT: foo3
157 
158 // Listing 6, p. 19
159 #pragma omp declare simd linear(x) aligned(x : 16) simdlen(4)
160 int foo4(int *x, float y);
161 // AARCH64: "_ZGVnM4l4a16v_foo4" "_ZGVnN4l4a16v_foo4"
162 // AARCH64-NOT: foo4
163 
164 static int *I;
165 static char *C;
166 static short *S;
167 static long *L;
168 static float *F;
169 static double *D;
do_something()170 void do_something() {
171   simple_8bit(*C);
172   simple_16bit(*S);
173   simple_32bit(*I);
174   simple_64bit(*L);
175   *C = a01(*I);
176   *L = a02(*S);
177   *I = b01(I);
178   *C = b02(C);
179   D = b03(D);
180   *I = c01(D, *S);
181   *D = c02(D, *S);
182   constlinear(*I);
183   sincos(*D, D, D);
184   SinCos(*D, D, D);
185   foo2(I, *I);
186   foo3(I, *I, *C);
187   foo4(I, *F);
188 }
189 
190 typedef struct S {
191   char R, G, B;
192 } STy;
193 #pragma omp declare simd notinbranch
194 STy DoRGB(STy x);
195 // AARCH64: "_ZGVnN2v_DoRGB"
196 
197 static STy *RGBData;
198 
do_rgb_stuff()199 void do_rgb_stuff() {
200   DoRGB(*RGBData);
201 }
202