1 /* Test __builtin_tgmath: valid uses, standard floating-point types.  */
2 /* { dg-do run } */
3 /* { dg-options "" } */
4 
5 extern void abort (void);
6 extern void exit (int);
7 
8 #define CHECK_CALL(C, E, V)			\
9   do						\
10     {						\
11       if ((C) != (E))				\
12 	abort ();				\
13       extern __typeof (C) V;			\
14     }						\
15   while (0)
16 
17 extern float var_f;
18 extern double var_d;
19 extern long double var_ld;
20 extern _Complex float var_cf;
21 extern _Complex double var_cd;
22 extern _Complex long double var_cld;
23 extern int var_i;
24 
25 typedef float float_type;
26 typedef double double_type;
27 
28 /* Test simple case, real arguments and return type.  */
29 
t1f(float x)30 float_type t1f (float x) { return x + 1; }
t1d(double_type x)31 double t1d (double_type x) { return x + 2; }
t1l(volatile long double x)32 long double t1l (volatile long double x) { return x + 3; }
33 
34 #define t1v(x) __builtin_tgmath (t1f, t1d, t1l, x)
35 #define t1vr(x) __builtin_tgmath (t1l, t1d, t1f, x)
36 
37 static void
test_1(void)38 test_1 (void)
39 {
40   float_type f = 1;
41   volatile float vf = 2;
42   double d = 3;
43   long double ld = 4;
44   int i = 5;
45   long long ll = 6;
46   CHECK_CALL (t1v (f), 2, var_f);
47   CHECK_CALL (t1v (vf), 3, var_f);
48   CHECK_CALL (t1v (d), 5, var_d);
49   CHECK_CALL (t1v (ld), 7, var_ld);
50   CHECK_CALL (t1v (i), 7, var_d);
51   CHECK_CALL (t1v (ll), 8, var_d);
52   CHECK_CALL (t1vr (f), 2, var_f);
53   CHECK_CALL (t1vr (vf), 3, var_f);
54   CHECK_CALL (t1vr (d), 5, var_d);
55   CHECK_CALL (t1vr (ld), 7, var_ld);
56   CHECK_CALL (t1vr (i), 7, var_d);
57   CHECK_CALL (t1vr (ll), 8, var_d);
58 }
59 
60 /* Test first argument not type-generic.  */
61 
t2f(int a,float x)62 float t2f (int a, float x) { return a * x + 1; }
t2d(int a,double x)63 double t2d (int a, double x) { return a * x + 2; }
t2l(int a,long double x)64 long double t2l (int a, long double x) { return a * x + 3; }
65 
66 #define t2v(a, x) __builtin_tgmath (t2f, t2d, t2l, a, x)
67 
68 static void
test_2(void)69 test_2 (void)
70 {
71   float f = 1;
72   double d = 2;
73   long double ld = 3;
74   int i = 4;
75   unsigned long long ll = 5;
76   CHECK_CALL (t2v (1, f), 2, var_f);
77   CHECK_CALL (t2v (2, d), 6, var_d);
78   CHECK_CALL (t2v (3, ld), 12, var_ld);
79   CHECK_CALL (t2v (4, i), 18, var_d);
80   CHECK_CALL (t2v (5, ll), 27, var_d);
81 }
82 
83 /* Test return type not type-generic.  */
84 
t3f(float x)85 int t3f (float x) { return x + 1; }
t3d(double x)86 int t3d (double x) { return x + 2; }
t3l(long double x)87 int t3l (long double x) { return x + 3; }
88 
89 #define t3v(x) __builtin_tgmath (t3f, t3d, t3l, x)
90 
91 static void
test_3(void)92 test_3 (void)
93 {
94   float f = 1;
95   double d = 2;
96   long double ld = 3;
97   short s = 4;
98   CHECK_CALL (t3v (f), 2, var_i);
99   CHECK_CALL (t3v (d), 4, var_i);
100   CHECK_CALL (t3v (ld), 6, var_i);
101   CHECK_CALL (t3v (s), 6, var_i);
102 }
103 
104 /* Test multiple type-generic arguments.  */
105 
t4f(float x,float y)106 float t4f (float x, float y) { return 10 * x + y; }
t4d(double x,double y)107 double t4d (double x, double y) { return 100 * x + y; }
t4l(long double x,long double y)108 long double t4l (long double x, long double y) { return 1000 * x + y; }
109 
110 #define t4v(x, y) __builtin_tgmath (t4f, t4d, t4l, x, y)
111 
112 static void
test_4(void)113 test_4 (void)
114 {
115   float f1 = 1;
116   float f2 = 2;
117   double d1 = 3;
118   double d2 = 4;
119   long double ld = 5;
120   long int l = 6;
121   CHECK_CALL (t4v (f1, f2), 12, var_f);
122   CHECK_CALL (t4v (f2, f1), 21, var_f);
123   CHECK_CALL (t4v (f1, d1), 103, var_d);
124   CHECK_CALL (t4v (d2, f2), 402, var_d);
125   CHECK_CALL (t4v (f1, l), 106, var_d);
126   CHECK_CALL (t4v (ld, f1), 5001, var_ld);
127   CHECK_CALL (t4v (l, l), 606, var_d);
128   CHECK_CALL (t4v (l, ld), 6005, var_ld);
129 }
130 
131 /* Test complex argument, real return type.  */
132 
t5f(_Complex float x)133 float t5f (_Complex float x) { return 1 + __real__ x + 3 * __imag__ x; }
t5d(_Complex double x)134 double t5d (_Complex double x) { return 2 + __real__ x + 4 * __imag__ x; }
t5l(_Complex long double x)135 long double t5l (_Complex long double x) { return 3 + __real__ x + 5 * __imag__ x; }
136 
137 #define t5v(x) __builtin_tgmath (t5f, t5d, t5l, x)
138 
139 static void
test_5(void)140 test_5 (void)
141 {
142   float f = 1;
143   _Complex float cf = 2 + 3i;
144   double d = 4;
145   _Complex double cd = 5 + 6i;
146   long double ld = 7;
147   _Complex long double cld = 8 + 9i;
148   int i = 10;
149   _Complex int ci = 11 + 12i;
150   CHECK_CALL (t5v (f), 2, var_f);
151   CHECK_CALL (t5v (cf), 12, var_f);
152   CHECK_CALL (t5v (d), 6, var_d);
153   CHECK_CALL (t5v (cd), 31, var_d);
154   CHECK_CALL (t5v (ld), 10, var_ld);
155   CHECK_CALL (t5v (cld), 56, var_ld);
156   CHECK_CALL (t5v (i), 12, var_d);
157   CHECK_CALL (t5v (ci), 61, var_d);
158 }
159 
160 /* Test complex argument, complex return type.  */
161 
t6f(_Complex float x)162 _Complex float t6f (_Complex float x) { return 1 + x; }
t6d(_Complex double x)163 _Complex double t6d (_Complex double x) { return 2 + x; }
t6l(_Complex long double x)164 _Complex long double t6l (_Complex long double x) { return 3 + x; }
165 
166 #define t6v(x) __builtin_tgmath (t6f, t6d, t6l, x)
167 
168 static void
test_6(void)169 test_6 (void)
170 {
171   float f = 1;
172   _Complex float cf = 2 + 3i;
173   double d = 4;
174   _Complex double cd = 5 + 6i;
175   long double ld = 7;
176   _Complex long double cld = 8 + 9i;
177   int i = 10;
178   _Complex int ci = 11 + 12i;
179   CHECK_CALL (t6v (f), 2, var_cf);
180   CHECK_CALL (t6v (cf), 3 + 3i, var_cf);
181   CHECK_CALL (t6v (d), 6, var_cd);
182   CHECK_CALL (t6v (cd), 7 + 6i, var_cd);
183   CHECK_CALL (t6v (ld), 10, var_cld);
184   CHECK_CALL (t6v (cld), 11 + 9i, var_cld);
185   CHECK_CALL (t6v (i), 12, var_cd);
186   CHECK_CALL (t6v (ci), 13 + 12i, var_cd);
187 }
188 
189 /* Test real and complex argument, real return type.  */
190 
t7f(float x)191 float t7f (float x) { return 1 + x; }
t7cf(_Complex float x)192 float t7cf (_Complex float x) { return 2 + __real__ x; }
t7d(double x)193 double t7d (double x) { return 3 + x; }
t7cd(_Complex double x)194 double t7cd (_Complex double x) { return 4 + __real__ x; }
t7l(long double x)195 long double t7l (long double x) { return 5 + x; }
t7cl(_Complex long double x)196 long double t7cl (_Complex long double x) { return 6 + __real__ x; }
197 
198 #define t7v(x) __builtin_tgmath (t7f, t7d, t7l, t7cf, t7cd, t7cl, x)
199 
200 static void
test_7(void)201 test_7 (void)
202 {
203   float f = 1;
204   _Complex float cf = 2 + 3i;
205   double d = 4;
206   _Complex double cd = 5 + 6i;
207   long double ld = 7;
208   _Complex long double cld = 8 + 9i;
209   int i = 10;
210   _Complex int ci = 11 + 12i;
211   CHECK_CALL (t7v (f), 2, var_f);
212   CHECK_CALL (t7v (cf), 4, var_f);
213   CHECK_CALL (t7v (d), 7, var_d);
214   CHECK_CALL (t7v (cd), 9, var_d);
215   CHECK_CALL (t7v (ld), 12, var_ld);
216   CHECK_CALL (t7v (cld), 14, var_ld);
217   CHECK_CALL (t7v (i), 13, var_d);
218   CHECK_CALL (t7v (ci), 15, var_d);
219 }
220 
221 /* Test real and complex argument, real and complex return type.  */
222 
t8f(float x)223 float t8f (float x) { return 1 + x; }
t8cf(_Complex float x)224 _Complex float t8cf (_Complex float x) { return 2 + x; }
t8d(double x)225 double t8d (double x) { return 3 + x; }
t8cd(_Complex double x)226 _Complex double t8cd (_Complex double x) { return 4 + x; }
t8l(long double x)227 long double t8l (long double x) { return 5 + x; }
t8cl(_Complex long double x)228 _Complex long double t8cl (_Complex long double x) { return 6 + x; }
229 
230 #define t8v(x) __builtin_tgmath (t8f, t8d, t8l, t8cf, t8cd, t8cl, x)
231 
232 static void
test_8(void)233 test_8 (void)
234 {
235   float f = 1;
236   _Complex float cf = 2 + 3i;
237   double d = 4;
238   _Complex double cd = 5 + 6i;
239   long double ld = 7;
240   _Complex long double cld = 8 + 9i;
241   int i = 10;
242   _Complex int ci = 11 + 12i;
243   CHECK_CALL (t8v (f), 2, var_f);
244   CHECK_CALL (t8v (cf), 4 + 3i, var_cf);
245   CHECK_CALL (t8v (d), 7, var_d);
246   CHECK_CALL (t8v (cd), 9 + 6i, var_cd);
247   CHECK_CALL (t8v (ld), 12, var_ld);
248   CHECK_CALL (t8v (cld), 14 + 9i, var_cld);
249   CHECK_CALL (t8v (i), 13, var_d);
250   CHECK_CALL (t8v (ci), 15 + 12i, var_cd);
251 }
252 
253 /* Test multiple type-generic arguments, real and complex.  */
254 
t9f(float x,float y)255 float t9f (float x, float y) { return x + 10 * y; }
t9cf(_Complex float x,_Complex float y)256 _Complex float t9cf (_Complex float x, _Complex float y) { return x + 100 * y; }
t9d(double x,double y)257 double t9d (double x, double y) { return x + 1000 * y; }
t9cd(_Complex double x,_Complex double y)258 _Complex double t9cd (_Complex double x, _Complex double y) { return x + 10000 * y; }
t9l(long double x,long double y)259 long double t9l (long double x, long double y) { return x + 100000 * y; }
t9cl(_Complex long double x,_Complex long double y)260 _Complex long double t9cl (_Complex long double x, _Complex long double y) { return x + 1000000 * y; }
261 
262 #define t9v(x, y) __builtin_tgmath (t9f, t9d, t9l, t9cf, t9cd, t9cl, x, y)
263 
264 static void
test_9(void)265 test_9 (void)
266 {
267   float f = 1;
268   _Complex float cf = 2 + 3i;
269   double d = 4;
270   _Complex double cd = 5 + 6i;
271   long double ld = 7;
272   _Complex long double cld = 8 + 9i;
273   int i = 10;
274   _Complex int ci = 11 + 12i;
275   CHECK_CALL (t9v (f, f), 11, var_f);
276   CHECK_CALL (t9v (f, cf), 201 + 300i, var_cf);
277   CHECK_CALL (t9v (cf, f), 102 + 3i, var_cf);
278   CHECK_CALL (t9v (f, i), 10001, var_d);
279   CHECK_CALL (t9v (i, f), 1010, var_d);
280   CHECK_CALL (t9v (d, d), 4004, var_d);
281   CHECK_CALL (t9v (d, cd), 50004 + 60000i, var_cd);
282   CHECK_CALL (t9v (ld, i), 1000007, var_ld);
283   CHECK_CALL (t9v (cf, cld), 8000002 + 9000003i, var_cld);
284   CHECK_CALL (t9v (i, i), 10010, var_d);
285   CHECK_CALL (t9v (ci, i), 100011 + 12i, var_cd);
286 }
287 
288 /* Test functions rounding result to narrower type.  */
289 
t10d(double x)290 float t10d (double x) { return 1 + x; }
t10l(long double x)291 float t10l (long double x) { return 2 + x; }
292 
293 #define t10v(x) __builtin_tgmath (t10d, t10l, x)
294 
295 static void
test_10(void)296 test_10 (void)
297 {
298   float f = 1;
299   double d = 2;
300   long double ld = 3;
301   short s = 4;
302   CHECK_CALL (t10v (f), 2, var_f);
303   CHECK_CALL (t10v (d), 3, var_f);
304   CHECK_CALL (t10v (ld), 5, var_f);
305   CHECK_CALL (t10v (s), 5, var_f);
306 }
307 
308 int
main(void)309 main (void)
310 {
311   test_1 ();
312   test_2 ();
313   test_3 ();
314   test_4 ();
315   test_5 ();
316   test_6 ();
317   test_7 ();
318   test_8 ();
319   test_9 ();
320   test_10 ();
321   exit (0);
322 }
323