(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
torture/
builtin-logb-1.c
       1  /* Copyright (C) 2007  Free Software Foundation.
       2  
       3     Verify that built-in folding of logb, ilogb and significand is
       4     correctly performed by the compiler.
       5  
       6     Origin: Kaveh R. Ghazi,  February 22, 2007.  */
       7  
       8  /* { dg-do link } */
       9  /* { dg-options "-fno-finite-math-only" { target sh*-*-* } } */
      10  /* In order to fold algebraic exprs below, targets with "composite"
      11     floating point formats need -funsafe-math-optimizations.  */
      12  /* { dg-require-effective-target inf } */
      13  /* { dg-options "-funsafe-math-optimizations" { target powerpc*-*-* } } */
      14  
      15  extern void link_error(int);
      16  
      17  /* Return TRUE if the sign of X != sign of Y.  This is important when
      18     comparing signed zeros.  */
      19  #define CKSGN_F(X,Y) \
      20    (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
      21  #define CKSGN(X,Y) \
      22    (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
      23  #define CKSGN_L(X,Y) \
      24    (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
      25  
      26  /* Test that FUNC(ARG) == RES.  Check the sign in case we get -0.0.  */
      27  #define TESTIT(FUNC,ARG,RES) do { \
      28    if (__builtin_##FUNC##f(ARG##f) != RES##f \
      29        || CKSGN_F(__builtin_##FUNC##f(ARG##f),RES##f)) \
      30      link_error(__LINE__); \
      31    if (__builtin_##FUNC(ARG) != RES \
      32        || CKSGN(__builtin_##FUNC(ARG),RES)) \
      33      link_error(__LINE__); \
      34    if (__builtin_##FUNC##l(ARG##l) != RES##l \
      35        || CKSGN_L(__builtin_##FUNC##l(ARG##l),RES##l)) \
      36      link_error(__LINE__); \
      37    } while (0)
      38  
      39  /* Test that FUNC(ARG) == RES.  RES is an int so it can't be -0.0.  */
      40  #define TESTIT2(FUNC,ARG,RES) do { \
      41    if (__builtin_##FUNC##f(ARG##f) != RES) \
      42      link_error(__LINE__); \
      43    if (__builtin_##FUNC(ARG) != RES) \
      44      link_error(__LINE__); \
      45    if (__builtin_##FUNC##l(ARG##l) != RES) \
      46      link_error(__LINE__); \
      47    } while (0)
      48  
      49  /* Test if FUNCRES(FUNC(NEG FUNCARG(ARGARG))) is false.  Check the
      50     sign as well.  */
      51  #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,FUNCRES,NEG2) do { \
      52    if (!__builtin_##FUNCRES##f(__builtin_##FUNC(NEG __builtin_##FUNCARG##f(ARGARG))) \
      53        || CKSGN_F(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG)), NEG2 __builtin_##FUNCARG##f(ARGARG))) \
      54      link_error(__LINE__); \
      55    if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG))) \
      56        || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG)), NEG2 __builtin_##FUNCARG(ARGARG))) \
      57      link_error(__LINE__); \
      58    if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG))) \
      59        || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG)), NEG2 __builtin_##FUNCARG##l(ARGARG))) \
      60      link_error(__LINE__); \
      61    } while (0)
      62  
      63  void __attribute__ ((__noinline__))
      64  foo(void)
      65  {
      66    /* If radix == 2, test that logb(ARG2) -> ARG3.  */
      67  #if __FLT_RADIX__ == 2
      68    TESTIT (logb, -0x1p40, 40.0);
      69    TESTIT (logb, -0x1p30, 30.0);
      70    TESTIT (logb, -0x1p20, 20.0);
      71    TESTIT (logb, -0x1p10, 10.0);
      72    TESTIT (logb, -0x1p5, 5.0);
      73    TESTIT (logb, -100/3.0, 5.0);
      74    TESTIT (logb, -2.0, 1.0);
      75    TESTIT (logb, -1.5, 0.0);
      76    TESTIT (logb, -1.0, 0.0);
      77    TESTIT (logb, -1/3.0, -2.0);
      78    TESTIT (logb, -1/9.0, -4.0);
      79    TESTIT (logb, -0x1p-5, -5.0);
      80    TESTIT (logb, -0x1p-10, -10.0);
      81    TESTIT (logb, -0x1p-20, -20.0);
      82    TESTIT (logb, -0x1p-30, -30.0);
      83    TESTIT (logb, -0x1p-40, -40.0);
      84  
      85    TESTIT (logb, 0x1p-40, -40.0);
      86    TESTIT (logb, 0x1p-30, -30.0);
      87    TESTIT (logb, 0x1p-20, -20.0);
      88    TESTIT (logb, 0x1p-10, -10.0);
      89    TESTIT (logb, 0x1p-5, -5.0);
      90    TESTIT (logb, 1/9.0, -4.0);
      91    TESTIT (logb, 1/3.0, -2.0);
      92    TESTIT (logb, 1.0, 0.0);
      93    TESTIT (logb, 1.5, 0.0);
      94    TESTIT (logb, 2.0, 1.0);
      95    TESTIT (logb, 100/3.0, 5.0);
      96    TESTIT (logb, 0x1p5, 5.0);
      97    TESTIT (logb, 0x1p10, 10.0);
      98    TESTIT (logb, 0x1p20, 20.0);
      99    TESTIT (logb, 0x1p30, 30.0);
     100    TESTIT (logb, 0x1p40, 40.0);
     101  #endif
     102  
     103    /* If radix == 2, test that ilogb(ARG2) -> ARG3.  */
     104  #if __FLT_RADIX__ == 2
     105    TESTIT2 (ilogb, -0x1p40, 40);
     106    TESTIT2 (ilogb, -0x1p30, 30);
     107    TESTIT2 (ilogb, -0x1p20, 20);
     108    TESTIT2 (ilogb, -0x1p10, 10);
     109    TESTIT2 (ilogb, -0x1p5, 5);
     110    TESTIT2 (ilogb, -100/3.0, 5);
     111    TESTIT2 (ilogb, -2.0, 1);
     112    TESTIT2 (ilogb, -1.5, 0);
     113    TESTIT2 (ilogb, -1.0, 0);
     114    TESTIT2 (ilogb, -1/3.0, -2);
     115    TESTIT2 (ilogb, -1/9.0, -4);
     116    TESTIT2 (ilogb, -0x1p-5, -5);
     117    TESTIT2 (ilogb, -0x1p-10, -10);
     118    TESTIT2 (ilogb, -0x1p-20, -20);
     119    TESTIT2 (ilogb, -0x1p-30, -30);
     120    TESTIT2 (ilogb, -0x1p-40, -40);
     121  
     122    TESTIT2 (ilogb, 0x1p-40, -40);
     123    TESTIT2 (ilogb, 0x1p-30, -30);
     124    TESTIT2 (ilogb, 0x1p-20, -20);
     125    TESTIT2 (ilogb, 0x1p-10, -10);
     126    TESTIT2 (ilogb, 0x1p-5, -5);
     127    TESTIT2 (ilogb, 1/9.0, -4);
     128    TESTIT2 (ilogb, 1/3.0, -2);
     129    TESTIT2 (ilogb, 1.0, 0);
     130    TESTIT2 (ilogb, 1.5, 0);
     131    TESTIT2 (ilogb, 2.0, 1);
     132    TESTIT2 (ilogb, 100/3.0, 5);
     133    TESTIT2 (ilogb, 0x1p5, 5);
     134    TESTIT2 (ilogb, 0x1p10, 10);
     135    TESTIT2 (ilogb, 0x1p20, 20);
     136    TESTIT2 (ilogb, 0x1p30, 30);
     137    TESTIT2 (ilogb, 0x1p40, 40);
     138  #endif
     139  
     140    /* If radix == 2, test that significand(ARG2) -> ARG3.  Zero always
     141       folds regardless of the radix.  */
     142    TESTIT (significand, -0.0, -0.0);
     143    TESTIT (significand, 0.0, 0.0);
     144  
     145  #if __FLT_RADIX__ == 2
     146    TESTIT (significand, -0x1p5, -1.0);
     147    TESTIT (significand, -100/3.0, -100/96.0);
     148    TESTIT (significand, -1.5, -1.5);
     149    TESTIT (significand, -1.0, -1.0);
     150    TESTIT (significand, -1/3.0, -4/3.0);
     151    TESTIT (significand, -1/9.0, -16/9.0);
     152    TESTIT (significand, -0x1p-5, -1.0);
     153  
     154    TESTIT (significand, 0x1p-5, 1.0);
     155    TESTIT (significand, 1/9.0, 16/9.0);
     156    TESTIT (significand, 1/3.0, 4/3.0);
     157    TESTIT (significand, 1.0, 1.0);
     158    TESTIT (significand, 1.5, 1.5);
     159    TESTIT (significand, 100/3.0, 100/96.0);
     160    TESTIT (significand, 0x1p5, 1.0);
     161  #endif
     162  
     163    /* Test for f(+-Inf) -> +-Inf and f(+-NaN) -> +-NaN, regardless of
     164       the radix.  */
     165    TESTIT3 (logb, ,inf, , isinf, );
     166    TESTIT3 (logb, - ,inf, , isinf, );
     167    TESTIT3 (logb,  ,nan, "", isnan, );
     168    TESTIT3 (logb, - ,nan, "", isnan, -);
     169  
     170    TESTIT3 (significand, ,inf, , isinf, );
     171    TESTIT3 (significand, - ,inf, , isinf, -);
     172    TESTIT3 (significand,  ,nan, "", isnan, );
     173    TESTIT3 (significand, - ,nan, "", isnan, -);
     174  }
     175  
     176  int main()
     177  {
     178    foo ();
     179    
     180    return 0;
     181  }