1 /* Copyright (C) 2010  Free Software Foundation.
2 
3    Verify that folding of built-in cproj is correctly performed by the
4    compiler.
5 
6    Origin: Kaveh R. Ghazi,  April 9, 2010.  */
7 
8 /* { dg-do link } */
9 /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
10 /* { dg-require-effective-target inf } */
11 /* { dg-add-options ieee } */
12 
13 /* All references to link_error should go away at compile-time.  The
14    argument is the __LINE__ number.  It appears in the tree dump file
15    and aids in debugging should any of the tests fail.  */
16 extern void link_error(int);
17 
18 #define CPROJ(X) __builtin_cproj(X)
19 #define CPROJF(X) __builtin_cprojf(X)
20 #define CPROJL(X) __builtin_cprojl(X)
21 #ifndef __SPU__
22 #define INF __builtin_inff()
23 #else
24 #define INF __builtin_inf()
25 #endif
26 #define I 1i
27 #define CPSGN(X,Y) __builtin_copysignf((X),(Y))
28 #define CIMAG(X) __builtin_cimagf(X)
29 #define CREAL(X) __builtin_crealf(X)
30 
31 /* Check that the signs of the real and/or imaginary parts of two
32    complex numbers match.  */
33 #define CKSGN(X,Y) (CKSGN_R(X,Y) || CKSGN_I(X,Y))
34 #define CKSGN_R(X,Y) (CPSGN(1,CREAL(X)) != CPSGN(1,CREAL(Y)))
35 #define CKSGN_I(X,Y) (CPSGN(1,CIMAG(X)) != CPSGN(1,CIMAG(Y)))
36 
37 /* Test that (cproj(X) == ZERO+Inf) and that the signs of the
38    imaginary parts match.  ZERO is +/- 0i.  */
39 #ifndef __SPU__
40 #define TEST_CST_INF(X,ZERO) do { \
41   if (CPROJF(X) != ZERO+INF || CKSGN_I(CPROJF(X),ZERO+INF)) \
42     link_error(__LINE__); \
43   if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \
44     link_error(__LINE__); \
45   if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \
46     link_error(__LINE__); \
47 } while (0)
48 #else
49 #define TEST_CST_INF(X,ZERO) do { \
50   if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \
51     link_error(__LINE__); \
52   if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \
53     link_error(__LINE__); \
54 } while (0)
55 #endif
56 
57 /* Test that (cproj(X) == X) for all finite (X).  */
58 #define TEST_CST(X) do { \
59   if (CPROJF(X) != (X) || CKSGN(CPROJF(X),(X))) \
60     link_error(__LINE__); \
61 } while (0)
62 
63 /* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i.
64    NEG is either blank or a minus sign when ZERO is negative.  */
65 #ifndef __SPU__
66 #define TEST_IMAG_INF(NEG,ZERO) do { \
67   if (CPROJF(f+I*NEG INF) != ZERO+INF \
68       || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \
69     link_error(__LINE__); \
70   if (CPROJ(d+I*NEG INF) != ZERO+INF \
71       || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \
72     link_error(__LINE__); \
73   if (CPROJL(ld+I*NEG INF) != ZERO+INF \
74       || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \
75     link_error(__LINE__); \
76 } while (0)
77 #else
78 #define TEST_IMAG_INF(NEG,ZERO) do { \
79   if (CPROJ(d+I*NEG INF) != ZERO+INF \
80       || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \
81     link_error(__LINE__); \
82   if (CPROJL(ld+I*NEG INF) != ZERO+INF \
83       || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \
84     link_error(__LINE__); \
85 } while (0)
86 #endif
87 
88 /* Like TEST_IMAG_INF, but check that side effects are honored.  */
89 #ifndef __SPU__
90 #define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \
91   int side = 4; \
92   if (CPROJF(++side+I*NEG INF) != ZERO+INF \
93       || CKSGN_I (CPROJF(++side+I*NEG INF), ZERO+INF)) \
94     link_error(__LINE__); \
95   if (CPROJ(++side+I*NEG INF) != ZERO+INF \
96       || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \
97     link_error(__LINE__); \
98   if (CPROJL(++side+I*NEG INF) != ZERO+INF \
99       || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \
100     link_error(__LINE__); \
101   if (side != 10) \
102     link_error(__LINE__); \
103 } while (0)
104 #else
105 #define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \
106   int side = 4; \
107   if (CPROJ(++side+I*NEG INF) != ZERO+INF \
108       || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \
109     link_error(__LINE__); \
110   if (CPROJL(++side+I*NEG INF) != ZERO+INF \
111       || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \
112     link_error(__LINE__); \
113   if (side != 8) \
114     link_error(__LINE__); \
115 } while (0)
116 #endif
117 
118 /* Test that cproj(INF, POSITIVE) -> INF+0i.  NEG is either blank or a
119    minus sign to test negative INF.  */
120 #ifndef __SPU__
121 #define TEST_REAL_INF(NEG) do { \
122   __real cf = NEG INF; \
123   __imag cf = (x ? 4 : 5); \
124   if (CPROJF(cf) != INF \
125       || CKSGN_I (CPROJF(cf), INF)) \
126     link_error(__LINE__); \
127   __real cd = NEG INF; \
128   __imag cd = (x ? 4 : 5); \
129   if (CPROJ(cd) != INF \
130       || CKSGN_I (CPROJ(cd), INF)) \
131     link_error(__LINE__); \
132   __real cld = NEG INF; \
133   __imag cld = (x ? 4 : 5); \
134   if (CPROJL(cld) != INF \
135       || CKSGN_I (CPROJL(cld), INF)) \
136     link_error(__LINE__); \
137 } while (0)
138 #else
139 #define TEST_REAL_INF(NEG) do { \
140   __real cd = NEG INF; \
141   __imag cd = (x ? 4 : 5); \
142   if (CPROJ(cd) != INF \
143       || CKSGN_I (CPROJ(cd), INF)) \
144     link_error(__LINE__); \
145   __real cld = NEG INF; \
146   __imag cld = (x ? 4 : 5); \
147   if (CPROJL(cld) != INF \
148       || CKSGN_I (CPROJL(cld), INF)) \
149     link_error(__LINE__); \
150 } while (0)
151 #endif
152 
153 /* Like TEST_REAL_INF, but check that side effects are honored.  */
154 #ifndef __SPU__
155 #define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \
156   int side = -9; \
157   __real cf = NEG INF; \
158   __imag cf = (x ? 4 : 5); \
159   if (CPROJF((++side,cf)) != INF \
160       || CKSGN_I (CPROJF((++side,cf)), INF)) \
161     link_error(__LINE__); \
162   __real cd = NEG INF; \
163   __imag cd = (x ? 4 : 5); \
164   if (CPROJ((++side,cd)) != INF \
165       || CKSGN_I (CPROJ((++side,cd)), INF)) \
166     link_error(__LINE__); \
167   __real cld = NEG INF; \
168   __imag cld = (x ? 4 : 5); \
169   if (CPROJL((++side,cld)) != INF \
170       || CKSGN_I (CPROJL((++side,cld)), INF)) \
171     link_error(__LINE__); \
172   if (side != -3) \
173     link_error(__LINE__); \
174 } while (0)
175 #else
176 #define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \
177   int side = -9; \
178   __real cd = NEG INF; \
179   __imag cd = (x ? 4 : 5); \
180   if (CPROJ((++side,cd)) != INF \
181       || CKSGN_I (CPROJ((++side,cd)), INF)) \
182     link_error(__LINE__); \
183   __real cld = NEG INF; \
184   __imag cld = (x ? 4 : 5); \
185   if (CPROJL((++side,cld)) != INF \
186       || CKSGN_I (CPROJL((++side,cld)), INF)) \
187     link_error(__LINE__); \
188   if (side != -5) \
189     link_error(__LINE__); \
190 } while (0)
191 #endif
192 
foo(_Complex long double cld,_Complex double cd,_Complex float cf,long double ld,double d,float f,int x)193 void foo (_Complex long double cld, _Complex double cd, _Complex float cf,
194 	  long double ld, double d, float f, int x)
195 {
196   TEST_CST_INF (INF+0I, 0);
197   TEST_CST_INF (INF-0I, -0.FI);
198   TEST_CST_INF (INF+4I, 0);
199   TEST_CST_INF (INF-4I, -0.FI);
200   TEST_CST_INF (-INF+0I, 0);
201   TEST_CST_INF (-INF-0I, -0.FI);
202   TEST_CST_INF (-INF+4I, 0);
203   TEST_CST_INF (-INF-4I, -0.FI);
204 
205   TEST_CST_INF (0+I*INF, 0);
206   TEST_CST_INF (0-I*INF, -0.FI);
207   TEST_CST_INF (23+I*INF, 0);
208   TEST_CST_INF (23-I*INF, -0.FI);
209   TEST_CST_INF (-0.F+I*INF, 0);
210   TEST_CST_INF (-0.F-I*INF, -0.FI);
211   TEST_CST_INF (-23+I*INF, 0);
212   TEST_CST_INF (-23-I*INF, -0.FI);
213 
214   TEST_CST_INF (INF+I*INF, 0);
215   TEST_CST_INF (INF-I*INF, -0.FI);
216   TEST_CST_INF (-INF+I*INF, 0);
217   TEST_CST_INF (-INF-I*INF, -0.FI);
218 
219   TEST_CST (0);
220   TEST_CST (-0.F);
221   TEST_CST (0-0.FI);
222   TEST_CST (-0.F-0.FI);
223 
224   TEST_CST (22+3I);
225   TEST_CST (22-3I);
226   TEST_CST (-22+3I);
227   TEST_CST (-22-3I);
228 
229   TEST_IMAG_INF (,0.FI);
230   TEST_IMAG_INF (-,-0.FI);
231 
232 #ifdef __OPTIMIZE__
233   TEST_REAL_INF( );
234   TEST_REAL_INF(-);
235 
236   TEST_IMAG_INF_SIDE_EFFECT (,0.FI);
237   TEST_IMAG_INF_SIDE_EFFECT (-,-0.FI);
238 
239   TEST_REAL_INF_SIDE_EFFECT( );
240   TEST_REAL_INF_SIDE_EFFECT(-);
241 #endif
242 
243   return;
244 }
245 
main(void)246 int main (void)
247 {
248   return 0;
249 }
250