1  /* Copyright (C) 2003, 2005  Free Software Foundation.
       2  
       3     Verify that the `const' function attribute is applied to various
       4     builtins and that these functions are optimized away by the
       5     compiler under the appropriate circumstances.
       6  
       7     Written by Kaveh Ghazi, 2003-08-04.  */
       8  
       9  /* { dg-do link } */
      10  /* { dg-options "-ffast-math" } */
      11  
      12  /* These are helper macros to test combinations of functions.  We test
      13     foo() != foo() with the same arguments, and expect the compiler to
      14     optimize away these tests of const functions.  */
      15  
      16  /* Just test the __builtin_ functions.  */
      17  #define BUILTIN_TEST1(FN, TYPE) \
      18  extern void link_failure_builtin_##FN(void); \
      19  void test_builtin_##FN(TYPE x) \
      20  { if (__builtin_##FN(x) != __builtin_##FN(x)) link_failure_builtin_##FN(); }
      21  
      22  /* Just test the __builtin_ functions.  */
      23  #define BUILTIN_TEST2(FN, TYPE) \
      24  extern void link_failure_builtin_##FN(void); \
      25  void test_builtin_##FN(TYPE x, TYPE y) \
      26  { if (__builtin_##FN(x,y) != __builtin_##FN(x,y)) link_failure_builtin_##FN(); }
      27  
      28  /* Also test the regular (non-__builtin_) function.  */
      29  #define TEST1(FN, TYPE, RTYPE) \
      30  BUILTIN_TEST1(FN, TYPE) \
      31  extern void link_failure_##FN(void); \
      32  extern RTYPE FN(TYPE); \
      33  void test_##FN(TYPE x) { if (FN(x) != FN(x)) link_failure_##FN(); }
      34  
      35  /* Test the __builtin_ functions taking void arguments (with the "f"
      36     and "l" variants).  */
      37  #define BUILTIN_FPTEST0(FN) \
      38  extern void link_failure_builtin_##FN(void); \
      39  extern void link_failure_builtin_##FN##f(void); \
      40  extern void link_failure_builtin_##FN##l(void); \
      41  void test_builtin_##FN(void) \
      42  { if (__builtin_##FN() != __builtin_##FN()) link_failure_builtin_##FN(); } \
      43  void test_builtin_##FN##f(void) \
      44  { if (__builtin_##FN##f() != __builtin_##FN##f()) link_failure_builtin_##FN##f(); } \
      45  void test_builtin_##FN##l(void) \
      46  { if (__builtin_##FN##l() != __builtin_##FN##l()) link_failure_builtin_##FN##l(); }
      47  
      48  /* Test the __builtin_ functions taking one FP argument (with the "f"
      49     and "l" variants).  */
      50  #define BUILTIN_FPTEST1(FN) \
      51  extern void link_failure_builtin_##FN(void); \
      52  extern void link_failure_builtin_##FN##f(void); \
      53  extern void link_failure_builtin_##FN##l(void); \
      54  void test_builtin_##FN(double d) \
      55  { if (__builtin_##FN(d) != __builtin_##FN(d)) link_failure_builtin_##FN(); } \
      56  void test_builtin_##FN##f(float f) \
      57  { if (__builtin_##FN##f(f) != __builtin_##FN##f(f)) link_failure_builtin_##FN##f(); } \
      58  void test_builtin_##FN##l(long double ld) \
      59  { if (__builtin_##FN##l(ld) != __builtin_##FN##l(ld)) link_failure_builtin_##FN##l(); }
      60  
      61  /* Test the __builtin_ functions taking one argument of supplied type
      62     (with the "f" and "l" variants).  */
      63  #define BUILTIN_FPTEST1ARG(FN, TYPE) \
      64  extern void link_failure_builtin_##FN(void); \
      65  extern void link_failure_builtin_##FN##f(void); \
      66  extern void link_failure_builtin_##FN##l(void); \
      67  void test_builtin_##FN(TYPE x) \
      68  { if (__builtin_##FN(x) != __builtin_##FN(x)) link_failure_builtin_##FN(); } \
      69  void test_builtin_##FN##f(TYPE x) \
      70  { if (__builtin_##FN##f(x) != __builtin_##FN##f(x)) link_failure_builtin_##FN##f(); } \
      71  void test_builtin_##FN##l(TYPE x) \
      72  { if (__builtin_##FN##l(x) != __builtin_##FN##l(x)) link_failure_builtin_##FN##l(); }
      73  
      74  /* Test the __builtin_ functions taking two FP arguments (with the "f"
      75     and "l" variants).  */
      76  #define BUILTIN_FPTEST2(FN) \
      77  extern void link_failure_builtin_##FN(void); \
      78  extern void link_failure_builtin_##FN##f(void); \
      79  extern void link_failure_builtin_##FN##l(void); \
      80  void test_builtin_##FN(double d1, double d2) \
      81  { if (__builtin_##FN(d1,d2) != __builtin_##FN(d1,d2)) link_failure_builtin_##FN(); } \
      82  void test_builtin_##FN##f(float f1, float f2) \
      83  { if (__builtin_##FN##f(f1,f2) != __builtin_##FN##f(f1,f2)) link_failure_builtin_##FN##f(); } \
      84  void test_builtin_##FN##l(long double ld1, long double ld2) \
      85  { if (__builtin_##FN##l(ld1,ld2) != __builtin_##FN##l(ld1,ld2)) link_failure_builtin_##FN##l(); }
      86  
      87  /* Test the __builtin_ functions taking two arguments, the first one
      88     is of a supplied type and the second one one is of FP type (with
      89     the "f" and "l" variants).  */
      90  #define BUILTIN_FPTEST2ARG1(FN, TYPE) \
      91  extern void link_failure_builtin_##FN(void); \
      92  extern void link_failure_builtin_##FN##f(void); \
      93  extern void link_failure_builtin_##FN##l(void); \
      94  void test_builtin_##FN(TYPE x, double d) \
      95  { if (__builtin_##FN(x,d) != __builtin_##FN(x,d)) link_failure_builtin_##FN(); } \
      96  void test_builtin_##FN##f(TYPE x, float f) \
      97  { if (__builtin_##FN##f(x,f) != __builtin_##FN##f(x,f)) link_failure_builtin_##FN##f(); } \
      98  void test_builtin_##FN##l(TYPE x, long double ld) \
      99  { if (__builtin_##FN##l(x,ld) != __builtin_##FN##l(x,ld)) link_failure_builtin_##FN##l(); }
     100  
     101  /* Test the __builtin_ functions taking two arguments, the first one
     102     is of FP type and the second one one is of a supplied type (with
     103     the "f" and "l" variants).  */
     104  #define BUILTIN_FPTEST2ARG2(FN, TYPE) \
     105  extern void link_failure_builtin_##FN(void); \
     106  extern void link_failure_builtin_##FN##f(void); \
     107  extern void link_failure_builtin_##FN##l(void); \
     108  void test_builtin_##FN(double d, TYPE x) \
     109  { if (__builtin_##FN(d,x) != __builtin_##FN(d,x)) link_failure_builtin_##FN(); } \
     110  void test_builtin_##FN##f(float f, TYPE x) \
     111  { if (__builtin_##FN##f(f,x) != __builtin_##FN##f(f,x)) link_failure_builtin_##FN##f(); } \
     112  void test_builtin_##FN##l(long double ld, TYPE x) \
     113  { if (__builtin_##FN##l(ld,x) != __builtin_##FN##l(ld,x)) link_failure_builtin_##FN##l(); }
     114  
     115  /* Test the __builtin_ functions taking three FP arguments (with the
     116     "f" and "l" variants).  */
     117  #define BUILTIN_FPTEST3(FN) \
     118  extern void link_failure_builtin_##FN(void); \
     119  extern void link_failure_builtin_##FN##f(void); \
     120  extern void link_failure_builtin_##FN##l(void); \
     121  void test_builtin_##FN(double d1, double d2, double d3) \
     122  { if (__builtin_##FN(d1,d2,d3) != __builtin_##FN(d1,d2,d3)) link_failure_builtin_##FN(); } \
     123  void test_builtin_##FN##f(float f1, float f2, float f3) \
     124  { if (__builtin_##FN##f(f1,f2,f3) != __builtin_##FN##f(f1,f2,f3)) link_failure_builtin_##FN##f(); } \
     125  void test_builtin_##FN##l(long double ld1, long double ld2, long double ld3) \
     126  { if (__builtin_##FN##l(ld1,ld2,ld3) != __builtin_##FN##l(ld1,ld2,ld3)) link_failure_builtin_##FN##l(); }
     127  
     128  /* Test the __builtin_ functions taking one complex argument (with the
     129     "f" and "l" variants).  */
     130  #define BUILTIN_CPTEST1(FN) \
     131  extern void link_failure_builtin_##FN(void); \
     132  extern void link_failure_builtin_##FN##f(void); \
     133  extern void link_failure_builtin_##FN##l(void); \
     134  void test_builtin_##FN(_Complex double d) \
     135  { if (__builtin_##FN(d) != __builtin_##FN(d)) link_failure_builtin_##FN(); } \
     136  void test_builtin_##FN##f(_Complex float f) \
     137  { if (__builtin_##FN##f(f) != __builtin_##FN##f(f)) link_failure_builtin_##FN##f(); } \
     138  void test_builtin_##FN##l(_Complex long double ld) \
     139  { if (__builtin_##FN##l(ld) != __builtin_##FN##l(ld)) link_failure_builtin_##FN##l(); }
     140  
     141  /* Test the __builtin_ functions taking two complex arguments (with
     142     the "f" and "l" variants).  */
     143  #define BUILTIN_CPTEST2(FN) \
     144  extern void link_failure_builtin_##FN(void); \
     145  extern void link_failure_builtin_##FN##f(void); \
     146  extern void link_failure_builtin_##FN##l(void); \
     147  void test_builtin_##FN(_Complex double d1, _Complex double d2) \
     148  { if (__builtin_##FN(d1,d2) != __builtin_##FN(d1,d2)) link_failure_builtin_##FN(); } \
     149  void test_builtin_##FN##f(_Complex float f1, _Complex float f2) \
     150  { if (__builtin_##FN##f(f1,f2) != __builtin_##FN##f(f1,f2)) link_failure_builtin_##FN##f(); } \
     151  void test_builtin_##FN##l(_Complex long double ld1, _Complex long double ld2) \
     152  { if (__builtin_##FN##l(ld1,ld2) != __builtin_##FN##l(ld1,ld2)) link_failure_builtin_##FN##l(); }
     153  
     154  /* These macros additionally test the non-__builtin_ functions.  */
     155  
     156  /* Test the functions taking one FP argument (with the "f" and "l"
     157     variants) and returning that type.  */
     158  #define FPTEST1(FN) \
     159  BUILTIN_FPTEST1(FN) \
     160  extern void link_failure_##FN(void); \
     161  extern void link_failure_##FN##f(void); \
     162  extern void link_failure_##FN##l(void); \
     163  extern double FN(double); \
     164  extern float FN##f(float); \
     165  extern long double FN##l(long double); \
     166  void test_##FN(double d) \
     167  { if (FN(d) != FN(d)) link_failure_##FN(); } \
     168  void test_##FN##f(float f) \
     169  { if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
     170  void test_##FN##l(long double ld) \
     171  { if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
     172  
     173  /* Test the functions taking one FP argument (with the "f" and "l"
     174     variants) and returning TYPE.  */
     175  #define FPTEST1T(FN, TYPE) \
     176  BUILTIN_FPTEST1(FN) \
     177  extern void link_failure_##FN(void); \
     178  extern void link_failure_##FN##f(void); \
     179  extern void link_failure_##FN##l(void); \
     180  extern TYPE FN(double); \
     181  extern TYPE FN##f(float); \
     182  extern TYPE FN##l(long double); \
     183  void test_##FN(double d) \
     184  { if (FN(d) != FN(d)) link_failure_##FN(); } \
     185  void test_##FN##f(float f) \
     186  { if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
     187  void test_##FN##l(long double ld) \
     188  { if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
     189  
     190  /* Test the functions taking two FP arguments (with the "f" and "l"
     191     variants).  */
     192  #define FPTEST2(FN) \
     193  BUILTIN_FPTEST2(FN) \
     194  extern void link_failure_##FN(void); \
     195  extern void link_failure_##FN##f(void); \
     196  extern void link_failure_##FN##l(void); \
     197  extern double FN(double, double); \
     198  extern float FN##f(float, float); \
     199  extern long double FN##l(long double, long double); \
     200  void test_##FN(double d1, double d2) \
     201  { if (FN(d1,d2) != FN(d1,d2)) link_failure_##FN(); } \
     202  void test_##FN##f(float f1, float f2) \
     203  { if (FN##f(f1,f2) != FN##f(f1,f2)) link_failure_##FN##f(); } \
     204  void test_##FN##l(long double ld1, long double ld2) \
     205  { if (FN##l(ld1,ld2) != FN##l(ld1,ld2)) link_failure_##FN##l(); }
     206  
     207  /* Test the functions taking two arguments, the first one is of a
     208     supplied type and the second one one is of FP type (with the "f"
     209     and "l" variants).  */
     210  #define FPTEST2ARG1(FN, TYPE) \
     211  BUILTIN_FPTEST2ARG1(FN, TYPE) \
     212  extern void link_failure_##FN(void); \
     213  extern void link_failure_##FN##f(void); \
     214  extern void link_failure_##FN##l(void); \
     215  extern double FN(TYPE, double); \
     216  extern float FN##f(TYPE, float); \
     217  extern long double FN##l(TYPE, long double); \
     218  void test_##FN(TYPE x, double d) \
     219  { if (FN(x,d) != FN(x,d)) link_failure_##FN(); } \
     220  void test_##FN##f(TYPE x, float f) \
     221  { if (FN##f(x,f) != FN##f(x,f)) link_failure_##FN##f(); } \
     222  void test_##FN##l(TYPE x, long double ld) \
     223  { if (FN##l(x,ld) != FN##l(x,ld)) link_failure_##FN##l(); }
     224  
     225  /* Test the functions taking two arguments, the first one is of FP
     226     type and the second one one is of a supplied type (with the "f" and
     227     "l" variants).  */
     228  #define FPTEST2ARG2(FN, TYPE) \
     229  BUILTIN_FPTEST2ARG2(FN, TYPE) \
     230  extern void link_failure_##FN(void); \
     231  extern void link_failure_##FN##f(void); \
     232  extern void link_failure_##FN##l(void); \
     233  extern double FN(double, TYPE); \
     234  extern float FN##f(float, TYPE); \
     235  extern long double FN##l(long double, TYPE); \
     236  void test_##FN(double d, TYPE x) \
     237  { if (FN(d,x) != FN(d,x)) link_failure_##FN(); } \
     238  void test_##FN##f(float f, TYPE x) \
     239  { if (FN##f(f,x) != FN##f(f,x)) link_failure_##FN##f(); } \
     240  void test_##FN##l(long double ld, TYPE x) \
     241  { if (FN##l(ld,x) != FN##l(ld,x)) link_failure_##FN##l(); }
     242  
     243  /* Test the functions taking three FP arguments (with the "f" and "l"
     244     variants).  */
     245  #define FPTEST3(FN) \
     246  BUILTIN_FPTEST3(FN) \
     247  extern void link_failure_##FN(void); \
     248  extern void link_failure_##FN##f(void); \
     249  extern void link_failure_##FN##l(void); \
     250  extern double FN(double, double, double); \
     251  extern float FN##f(float, float, float); \
     252  extern long double FN##l(long double, long double, long double); \
     253  void test_##FN(double d1, double d2, double d3) \
     254  { if (FN(d1,d2,d3) != FN(d1,d2,d3)) link_failure_##FN(); } \
     255  void test_##FN##f(float f1, float f2, float f3) \
     256  { if (FN##f(f1,f2,f3) != FN##f(f1,f2,f3)) link_failure_##FN##f(); } \
     257  void test_##FN##l(long double ld1, long double ld2, long double ld3) \
     258  { if (FN##l(ld1,ld2,ld3) != FN##l(ld1,ld2,ld3)) link_failure_##FN##l(); }
     259  
     260  /* Test the functions taking one complex argument (with the "f" and
     261     "l" variants) and returning that type.  */
     262  #define CPTEST1(FN) \
     263  BUILTIN_CPTEST1(FN) \
     264  extern void link_failure_##FN(void); \
     265  extern void link_failure_##FN##f(void); \
     266  extern void link_failure_##FN##l(void); \
     267  extern _Complex double FN(_Complex double); \
     268  extern _Complex float FN##f(_Complex float); \
     269  extern _Complex long double FN##l(_Complex long double); \
     270  void test_##FN(_Complex double d) \
     271  { if (FN(d) != FN(d)) link_failure_##FN(); } \
     272  void test_##FN##f(_Complex float f) \
     273  { if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
     274  void test_##FN##l(_Complex long double ld) \
     275  { if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
     276  
     277  /* Test the functions taking one complex argument (with the "f" and
     278     "l" variants) and returning the real type.  */
     279  #define CPTEST1R(FN) \
     280  BUILTIN_CPTEST1(FN) \
     281  extern void link_failure_##FN(void); \
     282  extern void link_failure_##FN##f(void); \
     283  extern void link_failure_##FN##l(void); \
     284  extern double FN(_Complex double); \
     285  extern float FN##f(_Complex float); \
     286  extern long double FN##l(_Complex long double); \
     287  void test_##FN(_Complex double d) \
     288  { if (FN(d) != FN(d)) link_failure_##FN(); } \
     289  void test_##FN##f(_Complex float f) \
     290  { if (FN##f(f) != FN##f(f)) link_failure_##FN##f(); } \
     291  void test_##FN##l(_Complex long double ld) \
     292  { if (FN##l(ld) != FN##l(ld)) link_failure_##FN##l(); }
     293  
     294  /* Test the functions taking two complex arguments (with the "f" and
     295     "l" variants).  */
     296  #define CPTEST2(FN) \
     297  BUILTIN_CPTEST2(FN) \
     298  extern void link_failure_##FN(void); \
     299  extern void link_failure_##FN##f(void); \
     300  extern void link_failure_##FN##l(void); \
     301  extern _Complex double FN(_Complex double, _Complex double); \
     302  extern _Complex float FN##f(_Complex float, _Complex float); \
     303  extern _Complex long double FN##l(_Complex long double, _Complex long double); \
     304  void test_##FN(_Complex double d1, _Complex double d2) \
     305  { if (FN(d1,d2) != FN(d1,d2)) link_failure_##FN(); } \
     306  void test_##FN##f(_Complex float f1, _Complex float f2) \
     307  { if (FN##f(f1,f2) != FN##f(f1,f2)) link_failure_##FN##f(); } \
     308  void test_##FN##l(_Complex long double ld1, _Complex long double ld2) \
     309  { if (FN##l(ld1,ld2) != FN##l(ld1,ld2)) link_failure_##FN##l(); }
     310  
     311  
     312  /* Test the math builtins.  */
     313  FPTEST1            (acos)
     314  FPTEST1            (acosh)
     315  FPTEST1            (asin)
     316  FPTEST1            (asinh)
     317  FPTEST1            (atan)
     318  FPTEST2            (atan2)
     319  FPTEST1            (atanh)
     320  FPTEST1            (cbrt)
     321  FPTEST1            (ceil)
     322  FPTEST2            (copysign)
     323  FPTEST1            (cos)
     324  FPTEST1            (cosh)
     325  FPTEST2            (drem)
     326  FPTEST1            (erf)
     327  FPTEST1            (erfc)
     328  FPTEST1            (exp)
     329  FPTEST1            (exp10)
     330  FPTEST1            (exp2)
     331  FPTEST1            (expm1)
     332  FPTEST1            (fabs)
     333  FPTEST2            (fdim)
     334  FPTEST1            (floor)
     335  FPTEST3            (fma)
     336  FPTEST2            (fmax)
     337  FPTEST2            (fmin)
     338  FPTEST2            (fmod)
     339  BUILTIN_FPTEST0    (huge_val)
     340  FPTEST2            (hypot)
     341  FPTEST1T           (ilogb, int)
     342  BUILTIN_FPTEST0    (inf) /* { dg-warning "does not support infinity" "INF unsupported" { target vax-*-* pdp11-*-* } } */
     343  FPTEST1            (j0)
     344  FPTEST1            (j1)
     345  FPTEST2ARG1        (jn, int)
     346  FPTEST2ARG2        (ldexp, int)
     347  BUILTIN_FPTEST1    (llceil)
     348  BUILTIN_FPTEST1    (llfloor)
     349  FPTEST1T           (llrint, long long)
     350  FPTEST1T           (llround, long long)
     351  FPTEST1            (log)
     352  FPTEST1            (log10)
     353  FPTEST1            (log1p)
     354  FPTEST1            (log2)
     355  FPTEST1            (logb)
     356  BUILTIN_FPTEST1    (lceil)
     357  BUILTIN_FPTEST1    (lfloor)
     358  FPTEST1T           (lrint, long)
     359  FPTEST1T           (lround, long)
     360  BUILTIN_FPTEST1ARG (nan, char *)
     361  BUILTIN_FPTEST1ARG (nans, char *)
     362  FPTEST1            (nearbyint)
     363  FPTEST2            (nextafter)
     364  FPTEST2ARG2        (nexttoward, long double)
     365  FPTEST2            (pow)
     366  FPTEST1            (pow10)
     367  FPTEST2            (remainder)
     368  FPTEST1            (rint)
     369  FPTEST1            (round)
     370  FPTEST2            (scalb)
     371  FPTEST2ARG2        (scalbn, int)
     372  FPTEST2ARG2        (scalbln, long int)
     373  FPTEST1            (significand)
     374  FPTEST1            (sin)
     375  FPTEST1            (sinh)
     376  FPTEST1            (sqrt)
     377  FPTEST1            (tan)
     378  FPTEST1            (tanh)
     379  FPTEST1            (tgamma)
     380  FPTEST1            (trunc)
     381  FPTEST1            (y0)
     382  FPTEST1            (y1)
     383  FPTEST2ARG1        (yn, int)
     384  
     385  /* Test the complex math builtins.  */
     386  /*CPTEST1 (cabs) See http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00040.html */
     387  CPTEST1 (cacos)
     388  CPTEST1 (cacosh)
     389  CPTEST1R (carg)
     390  CPTEST1 (casin)
     391  CPTEST1 (casinh)
     392  CPTEST1 (catan)
     393  CPTEST1 (catanh)
     394  CPTEST1 (ccos)
     395  CPTEST1 (ccosh)
     396  CPTEST1 (cexp)
     397  CPTEST1R (cimag)
     398  CPTEST1 (clog)
     399  CPTEST1 (conj)
     400  CPTEST2 (cpow)
     401  CPTEST1 (cproj)
     402  CPTEST1R (creal)
     403  CPTEST1 (csin)
     404  CPTEST1 (csinh)
     405  CPTEST1 (csqrt)
     406  CPTEST1 (ctan)
     407  CPTEST1 (ctanh)
     408  
     409  typedef __INTMAX_TYPE__ intmax_t;
     410  
     411  /* Various other const builtins.  */
     412  TEST1         (abs, int, int)
     413  BUILTIN_TEST1 (clz, int)
     414  BUILTIN_TEST1 (clzl, long)
     415  BUILTIN_TEST1 (clzll, long long)
     416  BUILTIN_TEST1 (ctz, int)
     417  BUILTIN_TEST1 (ctzl, long)
     418  BUILTIN_TEST1 (ctzll, long long)
     419  BUILTIN_TEST1 (clrsb, int)
     420  BUILTIN_TEST1 (clrsbl, long)
     421  BUILTIN_TEST1 (clrsbll, long long)
     422  TEST1         (ffs, int, int)
     423  TEST1         (ffsl, long, int)
     424  TEST1         (ffsll, long long, int)
     425  TEST1         (imaxabs, intmax_t, intmax_t)
     426  TEST1         (labs, long, long)
     427  TEST1         (llabs, long long, long long)
     428  BUILTIN_TEST1 (parity, int)
     429  BUILTIN_TEST1 (parityl, long)
     430  BUILTIN_TEST1 (parityll, long long)
     431  BUILTIN_TEST1 (popcount, int)
     432  BUILTIN_TEST1 (popcountl, long)
     433  BUILTIN_TEST1 (popcountll, long long)
     434  
     435  int main(void)
     436  {
     437    return 0;
     438  }