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  
     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  
     175  int main (void)
     176  {
     177    return 0;
     178  }