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