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