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 #define INF __builtin_inff()
22 #define I 1i
23 #define CPSGN(X,Y) __builtin_copysignf((X),(Y))
24 #define CIMAG(X) __builtin_cimagf(X)
25 #define CREAL(X) __builtin_crealf(X)
26 
27 /* Check that the signs of the real and/or imaginary parts of two
28    complex numbers match.  */
29 #define CKSGN(X,Y) (CKSGN_R(X,Y) || CKSGN_I(X,Y))
30 #define CKSGN_R(X,Y) (CPSGN(1,CREAL(X)) != CPSGN(1,CREAL(Y)))
31 #define CKSGN_I(X,Y) (CPSGN(1,CIMAG(X)) != CPSGN(1,CIMAG(Y)))
32 
33 /* Test that (cproj(X) == ZERO+Inf) and that the signs of the
34    imaginary parts match.  ZERO is +/- 0i.  */
35 #define TEST_CST_INF(X,ZERO) do { \
36   if (CPROJF(X) != ZERO+INF || CKSGN_I(CPROJF(X),ZERO+INF)) \
37     link_error(__LINE__); \
38   if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \
39     link_error(__LINE__); \
40   if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \
41     link_error(__LINE__); \
42 } while (0)
43 
44 /* Test that (cproj(X) == X) for all finite (X).  */
45 #define TEST_CST(X) do { \
46   if (CPROJF(X) != (X) || CKSGN(CPROJF(X),(X))) \
47     link_error(__LINE__); \
48 } while (0)
49 
50 /* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i.
51    NEG is either blank or a minus sign when ZERO is negative.  */
52 #define TEST_IMAG_INF(NEG,ZERO) do { \
53   if (CPROJF(f+I*NEG INF) != ZERO+INF \
54       || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \
55     link_error(__LINE__); \
56   if (CPROJ(d+I*NEG INF) != ZERO+INF \
57       || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \
58     link_error(__LINE__); \
59   if (CPROJL(ld+I*NEG INF) != ZERO+INF \
60       || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \
61     link_error(__LINE__); \
62 } while (0)
63 
64 /* Like TEST_IMAG_INF, but check that side effects are honored.  */
65 #define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \
66   int side = 4; \
67   if (CPROJF(++side+I*NEG INF) != ZERO+INF \
68       || CKSGN_I (CPROJF(++side+I*NEG INF), ZERO+INF)) \
69     link_error(__LINE__); \
70   if (CPROJ(++side+I*NEG INF) != ZERO+INF \
71       || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \
72     link_error(__LINE__); \
73   if (CPROJL(++side+I*NEG INF) != ZERO+INF \
74       || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \
75     link_error(__LINE__); \
76   if (side != 10) \
77     link_error(__LINE__); \
78 } while (0)
79 
80 /* Test that cproj(INF, POSITIVE) -> INF+0i.  NEG is either blank or a
81    minus sign to test negative INF.  */
82 #define TEST_REAL_INF(NEG) do { \
83   __real cf = NEG INF; \
84   __imag cf = (x ? 4 : 5); \
85   if (CPROJF(cf) != INF \
86       || CKSGN_I (CPROJF(cf), INF)) \
87     link_error(__LINE__); \
88   __real cd = NEG INF; \
89   __imag cd = (x ? 4 : 5); \
90   if (CPROJ(cd) != INF \
91       || CKSGN_I (CPROJ(cd), INF)) \
92     link_error(__LINE__); \
93   __real cld = NEG INF; \
94   __imag cld = (x ? 4 : 5); \
95   if (CPROJL(cld) != INF \
96       || CKSGN_I (CPROJL(cld), INF)) \
97     link_error(__LINE__); \
98 } while (0)
99 
100 /* Like TEST_REAL_INF, but check that side effects are honored.  */
101 #define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \
102   int side = -9; \
103   __real cf = NEG INF; \
104   __imag cf = (x ? 4 : 5); \
105   if (CPROJF((++side,cf)) != INF \
106       || CKSGN_I (CPROJF((++side,cf)), INF)) \
107     link_error(__LINE__); \
108   __real cd = NEG INF; \
109   __imag cd = (x ? 4 : 5); \
110   if (CPROJ((++side,cd)) != INF \
111       || CKSGN_I (CPROJ((++side,cd)), INF)) \
112     link_error(__LINE__); \
113   __real cld = NEG INF; \
114   __imag cld = (x ? 4 : 5); \
115   if (CPROJL((++side,cld)) != INF \
116       || CKSGN_I (CPROJL((++side,cld)), INF)) \
117     link_error(__LINE__); \
118   if (side != -3) \
119     link_error(__LINE__); \
120 } while (0)
121 
foo(_Complex long double cld,_Complex double cd,_Complex float cf,long double ld,double d,float f,int x)122 void foo (_Complex long double cld, _Complex double cd, _Complex float cf,
123 	  long double ld, double d, float f, int x)
124 {
125   TEST_CST_INF (INF+0I, 0);
126   TEST_CST_INF (INF-0I, -0.FI);
127   TEST_CST_INF (INF+4I, 0);
128   TEST_CST_INF (INF-4I, -0.FI);
129   TEST_CST_INF (-INF+0I, 0);
130   TEST_CST_INF (-INF-0I, -0.FI);
131   TEST_CST_INF (-INF+4I, 0);
132   TEST_CST_INF (-INF-4I, -0.FI);
133 
134   TEST_CST_INF (0+I*INF, 0);
135   TEST_CST_INF (0-I*INF, -0.FI);
136   TEST_CST_INF (23+I*INF, 0);
137   TEST_CST_INF (23-I*INF, -0.FI);
138   TEST_CST_INF (-0.F+I*INF, 0);
139   TEST_CST_INF (-0.F-I*INF, -0.FI);
140   TEST_CST_INF (-23+I*INF, 0);
141   TEST_CST_INF (-23-I*INF, -0.FI);
142 
143   TEST_CST_INF (INF+I*INF, 0);
144   TEST_CST_INF (INF-I*INF, -0.FI);
145   TEST_CST_INF (-INF+I*INF, 0);
146   TEST_CST_INF (-INF-I*INF, -0.FI);
147 
148   TEST_CST (0);
149   TEST_CST (-0.F);
150   TEST_CST (0-0.FI);
151   TEST_CST (-0.F-0.FI);
152 
153   TEST_CST (22+3I);
154   TEST_CST (22-3I);
155   TEST_CST (-22+3I);
156   TEST_CST (-22-3I);
157 
158   TEST_IMAG_INF (,0.FI);
159   TEST_IMAG_INF (-,-0.FI);
160 
161 #ifdef __OPTIMIZE__
162   TEST_REAL_INF( );
163   TEST_REAL_INF(-);
164 
165   TEST_IMAG_INF_SIDE_EFFECT (,0.FI);
166   TEST_IMAG_INF_SIDE_EFFECT (-,-0.FI);
167 
168   TEST_REAL_INF_SIDE_EFFECT( );
169   TEST_REAL_INF_SIDE_EFFECT(-);
170 #endif
171 
172   return;
173 }
174 
main(void)175 int main (void)
176 {
177   return 0;
178 }
179