1 /* Copyright (C) 2009  Free Software Foundation.
2 
3    Verify that folding of built-in complex math functions with
4    constant arguments is correctly performed by the compiler.
5 
6    Origin: Kaveh R. Ghazi,  January 28, 2009.  */
7 
8 /* { dg-do link } */
9 
10 /* All references to link_error should go away at compile-time.  The
11    first number is the line number and the second is the value number
12    among several tests.  These appear in the tree dump file and aid in
13    debugging.  */
14 extern void link_error(int, int);
15 
16 #define CONJ(X) __builtin_conjf(X)
17 
18 /* Return TRUE if the signs of floating point values X and Y are not
19    equal.  This is important when comparing signed zeros.  */
20 #define CKSGN_F(X,Y) \
21   (__builtin_copysignf(1,(X)) != __builtin_copysignf(1,(Y)))
22 #define CKSGN(X,Y) \
23   (__builtin_copysign(1,(X)) != __builtin_copysign(1,(Y)))
24 #define CKSGN_L(X,Y) \
25   (__builtin_copysignl(1,(X)) != __builtin_copysignl(1,(Y)))
26 
27 /* Return TRUE if signs of the real parts, and the signs of the
28    imaginary parts, of X and Y are not equal.  */
29 #define COMPLEX_CKSGN_F(X,Y) \
30   (CKSGN_F(__real__ (X), __real__ (Y)) || CKSGN_F (__imag__ (X), __imag__ (Y)))
31 #define COMPLEX_CKSGN(X,Y) \
32   (CKSGN(__real__ (X), __real__ (Y)) || CKSGN (__imag__ (X), __imag__ (Y)))
33 #define COMPLEX_CKSGN_L(X,Y) \
34   (CKSGN_L(__real__ (X), __real__ (Y)) || CKSGN_L (__imag__ (X), __imag__ (Y)))
35 
36 /* For complex numbers, test that FUNC(ARG) == (RES).  */
37 #define TESTIT_COMPLEX(VAL_NUM, FUNC, ARG, RES) do { \
38   if (__builtin_##FUNC##f(ARG) != (RES) \
39     || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG), (RES))) \
40       link_error(__LINE__, VAL_NUM); \
41   if (__builtin_##FUNC(ARG) != (RES) \
42     || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
43       link_error(__LINE__, VAL_NUM); \
44   if (__builtin_##FUNC##l(ARG) != (RES) \
45     || COMPLEX_CKSGN_L(__builtin_##FUNC##l(ARG), (RES))) \
46       link_error(__LINE__, VAL_NUM); \
47   } while (0)
48 
49 /* For complex numbers, call the TESTIT_COMPLEX macro for all
50    combinations of neg and conj.  */
51 #define TESTIT_COMPLEX_ALLNEG(FUNC, ARG, RES1, RES2, RES3, RES4) do { \
52   TESTIT_COMPLEX(1, FUNC, (_Complex float)(ARG), RES1); \
53   TESTIT_COMPLEX(2, FUNC, -CONJ(ARG), RES2); \
54   TESTIT_COMPLEX(3, FUNC, CONJ(ARG), RES3); \
55   TESTIT_COMPLEX(4, FUNC, -(_Complex float)(ARG), RES4); \
56 } while (0)
57 
58 /* For complex numbers, call the TESTIT_COMPLEX_R macro for all
59    combinations of neg and conj.  */
60 #define TESTIT_COMPLEX_R_ALLNEG(FUNC, ARG, RES1, RES2, RES3, RES4) do { \
61   TESTIT_COMPLEX_R(1, FUNC, (_Complex float)(ARG), RES1); \
62   TESTIT_COMPLEX_R(2, FUNC, -CONJ(ARG), RES2); \
63   TESTIT_COMPLEX_R(3, FUNC, CONJ(ARG), RES3); \
64   TESTIT_COMPLEX_R(4, FUNC, -(_Complex float)(ARG), RES4); \
65 } while (0)
66 
67 /* For complex numbers, test that FUNC(ARG0, ARG1) == (RES).  */
68 #define TESTIT_COMPLEX2(VAL_NUM, FUNC, ARG0, ARG1, RES) do { \
69   if (__builtin_##FUNC##f(ARG0, ARG1) != (RES) \
70     || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG0, ARG1), (RES))) \
71       link_error(__LINE__, VAL_NUM); \
72   if (__builtin_##FUNC(ARG0, ARG1) != (RES) \
73     || COMPLEX_CKSGN(__builtin_##FUNC(ARG0, ARG1), (RES))) \
74       link_error(__LINE__, VAL_NUM); \
75   if (__builtin_##FUNC##l(ARG0, ARG1) != (RES) \
76     || COMPLEX_CKSGN_L(__builtin_##FUNC##l(ARG0, ARG1), (RES))) \
77       link_error(__LINE__, VAL_NUM); \
78   } while (0)
79 
80 /* For complex numbers, call the TESTIT_COMPLEX2 macro for all
81    combinations of neg and conj.  */
82 #define TESTIT_COMPLEX2_ALLNEG(FUNC, ARG0, ARG1, RES1, RES2, RES3, RES4, RES5,\
83  RES6, RES7, RES8, RES9, RES10, RES11, RES12, RES13, RES14, RES15, RES16) do{ \
84   TESTIT_COMPLEX2(1, FUNC, (_Complex float)(ARG0),(_Complex float)(ARG1), RES1);\
85   TESTIT_COMPLEX2(2, FUNC, (_Complex float)(ARG0),CONJ(ARG1), RES2); \
86   TESTIT_COMPLEX2(3, FUNC, (_Complex float)(ARG0),-(_Complex float)(ARG1), RES3); \
87   TESTIT_COMPLEX2(4, FUNC, (_Complex float)(ARG0),-CONJ(ARG1), RES4); \
88   TESTIT_COMPLEX2(5, FUNC, -(_Complex float)(ARG0),(_Complex float)(ARG1), RES5); \
89   TESTIT_COMPLEX2(6, FUNC, -(_Complex float)(ARG0),CONJ(ARG1), RES6); \
90   TESTIT_COMPLEX2(7, FUNC, -(_Complex float)(ARG0),-(_Complex float)(ARG1), RES7); \
91   TESTIT_COMPLEX2(8, FUNC, -(_Complex float)(ARG0),-CONJ(ARG1), RES8); \
92   TESTIT_COMPLEX2(9, FUNC, CONJ(ARG0),(_Complex float)(ARG1), RES9); \
93   TESTIT_COMPLEX2(10, FUNC, CONJ(ARG0),CONJ(ARG1), RES10); \
94   TESTIT_COMPLEX2(11, FUNC, CONJ(ARG0),-(_Complex float)(ARG1), RES11); \
95   TESTIT_COMPLEX2(12, FUNC, CONJ(ARG0),-CONJ(ARG1), RES12); \
96   TESTIT_COMPLEX2(13, FUNC, -CONJ(ARG0),(_Complex float)(ARG1), RES13); \
97   TESTIT_COMPLEX2(14, FUNC, -CONJ(ARG0),CONJ(ARG1), RES14); \
98   TESTIT_COMPLEX2(15, FUNC, -CONJ(ARG0),-(_Complex float)(ARG1), RES15); \
99   TESTIT_COMPLEX2(16, FUNC, -CONJ(ARG0),-CONJ(ARG1), RES16); \
100 } while (0)
101 
102 /* Return TRUE if X differs from EXPECTED by more than 1%.  If
103    EXPECTED is zero, then any difference may return TRUE.  We don't
104    worry about signed zeros.  */
105 #define DIFF1PCT_F(X,EXPECTED) \
106   (__builtin_fabsf((X)-(EXPECTED)) * 100 > __builtin_fabsf(EXPECTED))
107 #define DIFF1PCT(X,EXPECTED) \
108   (__builtin_fabs((X)-(EXPECTED)) * 100 > __builtin_fabs(EXPECTED))
109 #define DIFF1PCT_L(X,EXPECTED) \
110   (__builtin_fabsl((X)-(EXPECTED)) * 100 > __builtin_fabsl(EXPECTED))
111 
112 /* Return TRUE if complex value X differs from EXPECTED by more than
113    1% in either the real or imaginary parts.  */
114 #define COMPLEX_DIFF1PCT_F(X,EXPECTED) \
115   (DIFF1PCT_F(__real__ (X), __real__ (EXPECTED)) \
116    || DIFF1PCT_F(__imag__ (X), __imag__ (EXPECTED)))
117 #define COMPLEX_DIFF1PCT(X,EXPECTED) \
118   (DIFF1PCT(__real__ (X), __real__ (EXPECTED)) \
119    || DIFF1PCT(__imag__ (X), __imag__ (EXPECTED)))
120 #define COMPLEX_DIFF1PCT_L(X,EXPECTED) \
121   (DIFF1PCT_L(__real__ (X), __real__ (EXPECTED)) \
122    || DIFF1PCT_L(__imag__ (X), __imag__ (EXPECTED)))
123 
124 /* Range test, for complex numbers check that FUNC(ARG) is within 1%
125    of RES.  This is NOT a test for accuracy to the last-bit, we're
126    merely checking that we get relatively sane results.  I.e. the GCC
127    builtin is hooked up to the correct MPC function call.  We first
128    check the magnitude and then the sign.  */
129 #define TESTIT_COMPLEX_R(VAL_NUM, FUNC, ARG, RES) do { \
130   if (COMPLEX_DIFF1PCT_F (__builtin_##FUNC##f(ARG), (RES)) \
131       || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG), (RES))) \
132     link_error(__LINE__, VAL_NUM); \
133   if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG), (RES)) \
134       || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
135     link_error(__LINE__, VAL_NUM); \
136   if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG), (RES)) \
137       || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
138     link_error(__LINE__, VAL_NUM); \
139   } while (0)
140 
141 /* Range test, for complex numbers check that FUNC(ARG0, ARG1) is
142    within 1% of RES.  This is NOT a test for accuracy to the last-bit,
143    we're merely checking that we get relatively sane results.
144    I.e. the GCC builtin is hooked up to the correct MPC function call.
145    We first check the magnitude and then the sign.  */
146 #define TESTIT_COMPLEX_R2(VAL_NUM, FUNC, ARG0, ARG1, RES) do { \
147   if (COMPLEX_DIFF1PCT_F (__builtin_##FUNC##f(ARG0, ARG1), (RES)) \
148       || COMPLEX_CKSGN_F (__builtin_##FUNC##f(ARG0, ARG1), (RES))) \
149     link_error(__LINE__, VAL_NUM); \
150   if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG0, ARG1), (RES)) \
151       || COMPLEX_CKSGN (__builtin_##FUNC(ARG0, ARG1), (RES))) \
152     link_error(__LINE__, VAL_NUM); \
153   if (COMPLEX_DIFF1PCT_L (__builtin_##FUNC##l(ARG0, ARG1), (RES)) \
154       || COMPLEX_CKSGN_L (__builtin_##FUNC##l(ARG0, ARG1), (RES))) \
155     link_error(__LINE__, VAL_NUM); \
156   } while (0)
157 
158 /* For complex numbers, call the TESTIT_COMPLEX_R2 macro for all
159    combinations of neg and conj.  */
160 #define TESTIT_COMPLEX_R2_ALLNEG(FUNC, ARG0, ARG1, RES1, RES2, RES3, RES4, RES5,\
161  RES6, RES7, RES8, RES9, RES10, RES11, RES12, RES13, RES14, RES15, RES16) do{ \
162   TESTIT_COMPLEX_R2(1, FUNC, (_Complex float)(ARG0),(_Complex float)(ARG1), RES1);\
163   TESTIT_COMPLEX_R2(2, FUNC, (_Complex float)(ARG0),CONJ(ARG1), RES2); \
164   TESTIT_COMPLEX_R2(3, FUNC, (_Complex float)(ARG0),-(_Complex float)(ARG1), RES3); \
165   TESTIT_COMPLEX_R2(4, FUNC, (_Complex float)(ARG0),-CONJ(ARG1), RES4); \
166   TESTIT_COMPLEX_R2(5, FUNC, -(_Complex float)(ARG0),(_Complex float)(ARG1), RES5); \
167   TESTIT_COMPLEX_R2(6, FUNC, -(_Complex float)(ARG0),CONJ(ARG1), RES6); \
168   TESTIT_COMPLEX_R2(7, FUNC, -(_Complex float)(ARG0),-(_Complex float)(ARG1), RES7); \
169   TESTIT_COMPLEX_R2(8, FUNC, -(_Complex float)(ARG0),-CONJ(ARG1), RES8); \
170   TESTIT_COMPLEX_R2(9, FUNC, CONJ(ARG0),(_Complex float)(ARG1), RES9); \
171   TESTIT_COMPLEX_R2(10, FUNC, CONJ(ARG0),CONJ(ARG1), RES10); \
172   TESTIT_COMPLEX_R2(11, FUNC, CONJ(ARG0),-(_Complex float)(ARG1), RES11); \
173   TESTIT_COMPLEX_R2(12, FUNC, CONJ(ARG0),-CONJ(ARG1), RES12); \
174   TESTIT_COMPLEX_R2(13, FUNC, -CONJ(ARG0),(_Complex float)(ARG1), RES13); \
175   TESTIT_COMPLEX_R2(14, FUNC, -CONJ(ARG0),CONJ(ARG1), RES14); \
176   TESTIT_COMPLEX_R2(15, FUNC, -CONJ(ARG0),-(_Complex float)(ARG1), RES15); \
177   TESTIT_COMPLEX_R2(16, FUNC, -CONJ(ARG0),-CONJ(ARG1), RES16); \
178 } while (0)
179 
main(void)180 int main (void)
181 {
182   TESTIT_COMPLEX (1, cacos, 1, CONJ(0));
183   TESTIT_COMPLEX_R (1, cacos, -1, CONJ(3.141593F));
184   TESTIT_COMPLEX (1, cacos, CONJ(1), 0);
185   TESTIT_COMPLEX_R (1, cacos, CONJ(-1), 3.141593F);
186   TESTIT_COMPLEX_R_ALLNEG (cacos, 3.45678F + 2.34567FI,
187 			   0.60971F - 2.11780FI, 2.531875F - 2.117800FI,
188 			   0.60971F + 2.11780FI, 2.531875F + 2.117800FI);
189 
190   TESTIT_COMPLEX_ALLNEG (casin, 0,
191 			 0, -CONJ(0), CONJ(0), CONJ(-0.F));
192   TESTIT_COMPLEX_R_ALLNEG (casin, 3.45678F + 2.34567FI,
193 			   0.96107F + 2.11780FI, -0.96107F + 2.11780FI,
194 			   0.96107F - 2.11780FI, -0.96107F - 2.11780FI);
195 
196   TESTIT_COMPLEX_ALLNEG (catan, 0,
197 			 0, -CONJ(0), CONJ(0), CONJ(-0.F));
198   TESTIT_COMPLEX_R_ALLNEG (catan, 3.45678F + 2.34567FI,
199 			   1.37188F + 0.12997FI, -1.37188F + 0.12997FI,
200 			   1.37188F - 0.12997FI, -1.37188F - 0.12997FI);
201 
202   TESTIT_COMPLEX (1, cacosh, 1, 0);
203   TESTIT_COMPLEX_R (1, cacosh, -1, 3.141593FI);
204   TESTIT_COMPLEX (1, cacosh, CONJ(1), CONJ(0));
205   TESTIT_COMPLEX_R (1, cacosh, CONJ(-1), CONJ(3.141593FI));
206   TESTIT_COMPLEX_R_ALLNEG (cacosh, 3.45678F + 2.34567FI,
207 			   2.11780F + 0.60971FI, 2.11780F + 2.531875FI,
208 			   2.11780F - 0.60971FI, 2.11780F - 2.531875FI);
209 
210   TESTIT_COMPLEX_ALLNEG (casinh, 0,
211 			 0, -CONJ(0), CONJ(0), CONJ(-0.F));
212   TESTIT_COMPLEX_R_ALLNEG (casinh, 3.45678F + 2.34567FI,
213 			   2.12836F + 0.58310FI, -2.12836F + 0.58310FI,
214 			   2.12836F - 0.58310FI, -2.12836F - 0.58310FI);
215 
216   TESTIT_COMPLEX_ALLNEG (catanh, 0,
217 			 0, -CONJ(0), CONJ(0), CONJ(-0.F));
218   TESTIT_COMPLEX_R_ALLNEG (catanh, 3.45678F + 2.34567FI,
219 			   0.19693F + 1.43190FI, -0.19693F + 1.43190FI,
220 			   0.19693F - 1.43190FI, -0.19693F - 1.43190FI);
221 
222   TESTIT_COMPLEX_ALLNEG (csin, 0,
223 			 0, -0.F, CONJ(0), CONJ(-0.F));
224   TESTIT_COMPLEX_R_ALLNEG (csin, 3.45678F + 2.34567FI,
225 			   -1.633059F - 4.917448FI, 1.633059F - 4.917448FI,
226 			   -1.633059F + 4.917448FI, 1.633059F + 4.917448FI);
227 
228   TESTIT_COMPLEX_ALLNEG (ccos, 0,
229 			 CONJ(1), 1, 1, CONJ(1));
230   TESTIT_COMPLEX_R_ALLNEG (ccos, 3.45678F + 2.34567FI,
231 			   -5.008512F + 1.603367FI, -5.008512F - 1.603367FI,
232 			   -5.008512F - 1.603367FI, -5.008512F + 1.603367FI);
233 
234   TESTIT_COMPLEX_ALLNEG (ctan, 0,
235 			 0, -0.F, CONJ(0), CONJ(-0.F));
236   TESTIT_COMPLEX_R_ALLNEG (ctan, 3.45678F + 2.34567FI,
237 			   0.010657F + 0.985230FI, -0.010657F + 0.985230FI,
238 			   0.010657F - 0.985230FI, -0.010657F - 0.985230FI);
239 
240   TESTIT_COMPLEX_ALLNEG (csinh, 0,
241 			 0, -0.F, CONJ(0), CONJ(-0.F));
242   TESTIT_COMPLEX_R_ALLNEG (csinh, 3.45678F + 2.34567FI,
243 			   -11.083178F + 11.341487FI, 11.083178F +11.341487FI,
244 			   -11.083178F - 11.341487FI, 11.083178F -11.341487FI);
245 
246   TESTIT_COMPLEX_ALLNEG (ccosh, 0,
247 			 1, CONJ(1), CONJ(1), 1);
248   TESTIT_COMPLEX_R_ALLNEG (ccosh, 3.45678F + 2.34567FI,
249 			   -11.105238F + 11.318958FI,-11.105238F -11.318958FI,
250 			   -11.105238F - 11.318958FI,-11.105238F +11.318958FI);
251 
252   TESTIT_COMPLEX_ALLNEG (ctanh, 0,
253 			 0, -0.F, CONJ(0), CONJ(-0.F));
254   TESTIT_COMPLEX_R_ALLNEG (ctanh, 3.45678F + 2.34567FI,
255 			   1.000040F - 0.001988FI, -1.000040F - 0.001988FI,
256 			   1.000040F + 0.001988FI, -1.000040F + 0.001988FI);
257 
258   TESTIT_COMPLEX (1, clog, 1, 0);
259   TESTIT_COMPLEX_R (1, clog, -1, 3.141593FI);
260   TESTIT_COMPLEX (1, clog, CONJ(1), CONJ(0));
261   TESTIT_COMPLEX_R (1, clog, CONJ(-1), CONJ(3.141593FI));
262   TESTIT_COMPLEX_R_ALLNEG (clog, 3.45678F + 2.34567FI,
263 			   1.429713F + 0.596199FI, 1.429713F + 2.545394FI,
264 			   1.429713F - 0.596199FI, 1.429713F - 2.545394FI);
265 
266   TESTIT_COMPLEX_ALLNEG (csqrt, 0,
267 			 0, 0, CONJ(0), CONJ(0));
268   TESTIT_COMPLEX_R_ALLNEG (csqrt, 3.45678F + 2.34567FI,
269 			   1.953750F + 0.600299FI, 0.600299F + 1.953750FI,
270 			   1.953750F - 0.600299FI, 0.600299F - 1.953750FI);
271 
272   TESTIT_COMPLEX2_ALLNEG (cpow, 1, 0,
273 			  1, 1, CONJ(1), CONJ(1), CONJ(1), CONJ(1), 1, 1,
274 			  CONJ(1), CONJ(1), 1, 1, 1, 1, CONJ(1), CONJ(1));
275   TESTIT_COMPLEX2_ALLNEG (cpow, 1.FI, 0,
276 			  1, 1, CONJ(1), CONJ(1), CONJ(1), CONJ(1), 1, 1,
277 			  CONJ(1), CONJ(1), 1, 1, 1, 1, CONJ(1), CONJ(1));
278   TESTIT_COMPLEX_R2_ALLNEG (cpow, 2, 3,
279 			    8, 8, CONJ(1/8.F), CONJ(1/8.F), CONJ(-8), CONJ(-8), -1/8.F, -1/8.F,
280 			    CONJ(8), CONJ(8), 1/8.F, 1/8.F, -8, -8, CONJ(-1/8.F), CONJ(-1/8.F));
281   TESTIT_COMPLEX_R2_ALLNEG (cpow, 3, 4,
282 			    81, 81, CONJ(1/81.F), CONJ(1/81.F), CONJ(81), CONJ(81), 1/81.F, 1/81.F,
283 			    CONJ(81), CONJ(81), 1/81.F, 1/81.F, 81, 81, CONJ(1/81.F), CONJ(1/81.F));
284   TESTIT_COMPLEX_R2_ALLNEG (cpow, 3, 5,
285 			    243, 243, CONJ(1/243.F), CONJ(1/243.F), CONJ(-243), CONJ(-243), -1/243.F, -1/243.F,
286 			    CONJ(243), CONJ(243), 1/243.F, 1/243.F, -243, -243, CONJ(-1/243.F), CONJ(-1/243.F));
287   TESTIT_COMPLEX_R2_ALLNEG (cpow, 4, 2,
288 			    16, 16, CONJ(1/16.F), CONJ(1/16.F), CONJ(16), CONJ(16), 1/16.F, 1/16.F,
289 			    CONJ(16), CONJ(16), 1/16.F, 1/16.F, 16, 16, CONJ(1/16.F), CONJ(1/16.F));
290   TESTIT_COMPLEX_R2_ALLNEG (cpow, 1.5, 3,
291 			    3.375F, 3.375F, CONJ(1/3.375F), CONJ(1/3.375F), CONJ(-3.375F), CONJ(-3.375F), -1/3.375F, -1/3.375F,
292 			    CONJ(3.375F), CONJ(3.375F), 1/3.375F, 1/3.375F, -3.375F, -3.375F, CONJ(-1/3.375F), CONJ(-1/3.375F));
293 
294   TESTIT_COMPLEX2 (1, cpow, 16, 0.25F, 2);
295 
296   TESTIT_COMPLEX_R2 (1, cpow, 3.45678F + 2.34567FI, 1.23456 + 4.56789FI, 0.212485F + 0.319304FI);
297   TESTIT_COMPLEX_R2 (1, cpow, 3.45678F - 2.34567FI, 1.23456 + 4.56789FI, 78.576402F + -41.756208FI);
298   TESTIT_COMPLEX_R2 (1, cpow, -1.23456F + 2.34567FI, 2.34567 - 1.23456FI, -110.629847F + -57.021655FI);
299   TESTIT_COMPLEX_R2 (1, cpow, -1.23456F - 2.34567FI, 2.34567 - 1.23456FI, 0.752336F + 0.199095FI);
300 
301   return 0;
302 }
303