1 /* Test vneg works correctly.  */
2 /* { dg-do run } */
3 /* { dg-options "--save-temps" } */
4 
5 #include <arm_neon.h>
6 
7 #define FLT_EPSILON __FLT_EPSILON__
8 #define DBL_EPSILON __DBL_EPSILON__
9 #define FLT_MAX __FLT_MAX__
10 #define FLT_MIN __FLT_MIN__
11 #define DBL_MAX __DBL_MAX__
12 #define DBL_MIN __DBL_MIN__
13 
14 #define TEST0 0
15 /* 6 digits of pi.  */
16 #define TEST1 3.14159
17 /* 6 digits of -e.  */
18 #define TEST2 -2.71828
19 /* 2^25, float has 24 significand bits
20    according to Single-precision floating-point format.  */
21 #define TEST3_FLT 33554432
22 /* 2^54, double has 53 significand bits
23    according to Double-precision floating-point format.  */
24 #define TEST3_DBL 18014398509481984
25 
26 extern void abort (void);
27 
28 #define FLT_INFINITY (__builtin_inff ())
29 #define DBL_INFINITY (__builtin_inf ())
30 
31 #ifndef NAN
32 #define NAN (0.0 / 0.0)
33 #endif
34 
35 #define CONCAT(a, b) a##b
36 #define CONCAT1(a, b) CONCAT (a, b)
37 #define REG_INFEX64 _
38 #define REG_INFEX128 q_
39 #define REG_INFEX(reg_len) REG_INFEX##reg_len
40 #define POSTFIX(reg_len, data_len) \
41   CONCAT1 (REG_INFEX (reg_len), f##data_len)
42 
43 #define DATA_TYPE_32 float
44 #define DATA_TYPE_64 double
45 #define DATA_TYPE(data_len) DATA_TYPE_##data_len
46 
47 #define STORE_INST(reg_len, data_len) \
48   CONCAT1 (vst1, POSTFIX (reg_len, data_len))
49 #define LOAD_INST(reg_len, data_len) \
50   CONCAT1 (vld1, POSTFIX (reg_len, data_len))
51 #define NEG_INST(reg_len, data_len) \
52   CONCAT1 (vneg, POSTFIX (reg_len, data_len))
53 
54 #define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
55 #define RUN_TEST(test_set, reg_len, data_len, n, a, b, c) \
56   {						       \
57     int i;					       \
58     (a) = LOAD_INST (reg_len, data_len) (test_set);    \
59     (b) = NEG_INST (reg_len, data_len) (a);	       \
60     STORE_INST (reg_len, data_len) (c, b);	       \
61     for (i = 0; i < n; i++)			       \
62       {						       \
63 	DATA_TYPE (data_len) diff;		       \
64 	INHIB_OPTIMIZATION;			       \
65 	diff = test_set[i] + c[i];		       \
66 	if (diff > EPSILON)			       \
67 	    return 1;				       \
68       }						       \
69   }
70 
71 #define TEST3 TEST3_FLT
72 #define EPSILON FLT_EPSILON
73 #define VAR_MIN FLT_MIN
74 #define VAR_MAX FLT_MAX
75 #define INFINITY FLT_INFINITY
76 
77 int
test_vneg_f32()78 test_vneg_f32 ()
79 {
80   float32x2_t a;
81   float32x2_t b;
82   float32_t c[2];
83 
84   float32_t test_set0[2] = { TEST0, TEST1 };
85   float32_t test_set1[2] = { TEST2, TEST3 };
86   float32_t test_set2[2] = { VAR_MAX, VAR_MIN };
87   float32_t test_set3[2] = { INFINITY, NAN };
88 
89   RUN_TEST (test_set0, 64, 32, 2, a, b, c);
90   RUN_TEST (test_set1, 64, 32, 2, a, b, c);
91   RUN_TEST (test_set2, 64, 32, 2, a, b, c);
92   RUN_TEST (test_set3, 64, 32, 0, a, b, c);
93 
94   /* Since last test cannot be checked in a uniform way by adding
95      negation result to original value, the number of lanes to be
96      checked in RUN_TEST is 0 (last argument).  Instead, result
97      will be checked manually.  */
98 
99   if (c[0] != -INFINITY)
100     return 1;
101 
102   if (!__builtin_isnan (c[1]))
103     return 1;
104 
105   return 0;
106 }
107 
108 /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 4 } } */
109 
110 #undef TEST3
111 #undef EPSILON
112 #undef VAR_MIN
113 #undef VAR_MAX
114 #undef INFINITY
115 
116 #define TEST3 TEST3_DBL
117 #define EPSILON DBL_EPSILON
118 #define VAR_MIN DBL_MIN
119 #define VAR_MAX DBL_MAX
120 #define INFINITY DBL_INFINITY
121 
122 int
test_vneg_f64()123 test_vneg_f64 ()
124 {
125   float64x1_t a;
126   float64x1_t b;
127   float64_t c[1];
128 
129   float64_t test_set0[1] = { TEST0 };
130   float64_t test_set1[1] = { TEST1 };
131   float64_t test_set2[1] = { TEST2 };
132   float64_t test_set3[1] = { TEST3 };
133   float64_t test_set4[1] = { VAR_MAX };
134   float64_t test_set5[1] = { VAR_MIN };
135   float64_t test_set6[1] = { INFINITY };
136   float64_t test_set7[1] = { NAN };
137 
138   RUN_TEST (test_set0, 64, 64, 1, a, b, c);
139   RUN_TEST (test_set1, 64, 64, 1, a, b, c);
140   RUN_TEST (test_set2, 64, 64, 1, a, b, c);
141   RUN_TEST (test_set3, 64, 64, 1, a, b, c);
142   RUN_TEST (test_set4, 64, 64, 1, a, b, c);
143   RUN_TEST (test_set5, 64, 64, 1, a, b, c);
144   RUN_TEST (test_set6, 64, 64, 0, a, b, c);
145 
146   /* Since last test cannot be checked in a uniform way by adding
147      negation result to original value, the number of lanes to be
148      checked in RUN_TEST is 0 (last argument).  Instead, result
149      will be checked manually.  */
150 
151   if (c[0] != -INFINITY)
152     return 1;
153 
154   /* Same as above.  */
155 
156   RUN_TEST (test_set7, 64, 64, 0, a, b, c);
157 
158   if (!__builtin_isnan (c[0]))
159     return 1;
160 
161   return 0;
162 }
163 
164 /* { dg-final { scan-assembler-times "fneg\\td\[0-9\]+, d\[0-9\]+" 8 } } */
165 
166 #undef TEST3
167 #undef EPSILON
168 #undef VAR_MIN
169 #undef VAR_MAX
170 #undef INFINITY
171 
172 #define TEST3 TEST3_FLT
173 #define EPSILON FLT_EPSILON
174 #define VAR_MIN FLT_MIN
175 #define VAR_MAX FLT_MAX
176 #define INFINITY FLT_INFINITY
177 
178 int
test_vnegq_f32()179 test_vnegq_f32 ()
180 {
181   float32x4_t a;
182   float32x4_t b;
183   float32_t c[4];
184 
185   float32_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
186   float32_t test_set1[4] = { FLT_MAX, FLT_MIN, INFINITY, NAN };
187 
188   RUN_TEST (test_set0, 128, 32, 4, a, b, c);
189   RUN_TEST (test_set1, 128, 32, 2, a, b, c);
190 
191   /* Since last test cannot be fully checked in a uniform way by
192      adding negation result to original value, the number of lanes
193      to be checked in RUN_TEST is 0 (last argument).  Instead, result
194      will be checked manually.  */
195 
196   if (c[2] != -INFINITY)
197     return 1;
198 
199   if (!__builtin_isnan (c[3]))
200     return 1;
201 
202   return 0;
203 }
204 
205 /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 2 } } */
206 
207 #undef TEST3
208 #undef EPSILON
209 #undef VAR_MIN
210 #undef VAR_MAX
211 #undef INFINITY
212 
213 #define TEST3 TEST3_DBL
214 #define EPSILON DBL_EPSILON
215 #define VAR_MIN DBL_MIN
216 #define VAR_MAX DBL_MAX
217 #define INFINITY DBL_INFINITY
218 
219 int
test_vnegq_f64()220 test_vnegq_f64 ()
221 {
222   float64x2_t a;
223   float64x2_t b;
224   float64_t c[2];
225 
226   float64_t test_set0[2] = { TEST0, TEST1 };
227   float64_t test_set1[2] = { TEST2, TEST3 };
228   float64_t test_set2[2] = { FLT_MAX, FLT_MIN };
229   float64_t test_set3[2] = { INFINITY, NAN };
230 
231   RUN_TEST (test_set0, 128, 64, 2, a, b, c);
232   RUN_TEST (test_set1, 128, 64, 2, a, b, c);
233   RUN_TEST (test_set2, 128, 64, 2, a, b, c);
234   RUN_TEST (test_set3, 128, 64, 0, a, b, c);
235 
236   /* Since last test cannot be checked in a uniform way by adding
237      negation result to original value, the number of lanes to be
238      checked in RUN_TEST is 0 (last argument).  Instead, result
239      will be checked manually.  */
240 
241   if (c[0] != -INFINITY)
242     return 1;
243 
244   if (!__builtin_isnan (c[1]))
245     return 1;
246 
247   return 0;
248 }
249 
250 /* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 4 } } */
251 
252 int
main(int argc,char ** argv)253 main (int argc, char **argv)
254 {
255   if (test_vneg_f32 ())
256     abort ();
257 
258   if (test_vneg_f64 ())
259     abort ();
260 
261   if (test_vnegq_f32 ())
262     abort ();
263 
264   if (test_vnegq_f64 ())
265     abort ();
266 
267   return 0;
268 }
269 
270