OSDN Git Service

2010-02-10 Joost VandeVondele <jv244@cam.ac.uk>
[pf3gnuchains/gcc-fork.git] / 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-options "-funsafe-math-optimizations" { target mips*-*-irix6* powerpc*-*-* } } */
13
14 extern void link_error(int);
15
16 /* Return TRUE if the sign of X != sign of Y.  This is important when
17    comparing signed zeros.  */
18 #define CKSGN_F(X,Y) \
19   (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
20 #define CKSGN(X,Y) \
21   (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
22 #define CKSGN_L(X,Y) \
23   (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
24
25 /* Test that FUNC(ARG) == RES.  Check the sign in case we get -0.0.  */
26 #define TESTIT(FUNC,ARG,RES) do { \
27   if (__builtin_##FUNC##f(ARG##f) != RES##f \
28       || CKSGN_F(__builtin_##FUNC##f(ARG##f),RES##f)) \
29     link_error(__LINE__); \
30   if (__builtin_##FUNC(ARG) != RES \
31       || CKSGN(__builtin_##FUNC(ARG),RES)) \
32     link_error(__LINE__); \
33   if (__builtin_##FUNC##l(ARG##l) != RES##l \
34       || CKSGN_L(__builtin_##FUNC##l(ARG##l),RES##l)) \
35     link_error(__LINE__); \
36   } while (0)
37
38 /* Test that FUNC(ARG) == RES.  RES is an int so it can't be -0.0.  */
39 #define TESTIT2(FUNC,ARG,RES) do { \
40   if (__builtin_##FUNC##f(ARG##f) != RES) \
41     link_error(__LINE__); \
42   if (__builtin_##FUNC(ARG) != RES) \
43     link_error(__LINE__); \
44   if (__builtin_##FUNC##l(ARG##l) != RES) \
45     link_error(__LINE__); \
46   } while (0)
47
48 /* Test if FUNCRES(FUNC(NEG FUNCARG(ARGARG))) is false.  Check the
49    sign as well.  */
50 #ifndef __SPU__
51 #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,FUNCRES) do { \
52   if (!__builtin_##FUNCRES##f(__builtin_##FUNC(NEG __builtin_##FUNCARG##f(ARGARG))) \
53       || CKSGN_F(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG)), NEG __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)), NEG __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)), NEG __builtin_##FUNCARG##l(ARGARG))) \
60     link_error(__LINE__); \
61   } while (0)
62 #else
63 #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,FUNCRES) do { \
64   /* SPU single-precision floating point format does not support Inf or Nan.  */ \
65   if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG))) \
66       || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG)), NEG __builtin_##FUNCARG(ARGARG))) \
67     link_error(__LINE__); \
68   if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG))) \
69       || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG)), NEG __builtin_##FUNCARG##l(ARGARG))) \
70     link_error(__LINE__); \
71   } while (0)
72 #endif
73
74 void __attribute__ ((__noinline__))
75 foo(void)
76 {
77   /* If radix == 2, test that logb(ARG2) -> ARG3.  */
78 #if __FLT_RADIX__ == 2
79   TESTIT (logb, -0x1p40, 40.0);
80   TESTIT (logb, -0x1p30, 30.0);
81   TESTIT (logb, -0x1p20, 20.0);
82   TESTIT (logb, -0x1p10, 10.0);
83   TESTIT (logb, -0x1p5, 5.0);
84   TESTIT (logb, -100/3.0, 5.0);
85   TESTIT (logb, -2.0, 1.0);
86   TESTIT (logb, -1.5, 0.0);
87   TESTIT (logb, -1.0, 0.0);
88   TESTIT (logb, -1/3.0, -2.0);
89   TESTIT (logb, -1/9.0, -4.0);
90   TESTIT (logb, -0x1p-5, -5.0);
91   TESTIT (logb, -0x1p-10, -10.0);
92   TESTIT (logb, -0x1p-20, -20.0);
93   TESTIT (logb, -0x1p-30, -30.0);
94   TESTIT (logb, -0x1p-40, -40.0);
95
96   TESTIT (logb, 0x1p-40, -40.0);
97   TESTIT (logb, 0x1p-30, -30.0);
98   TESTIT (logb, 0x1p-20, -20.0);
99   TESTIT (logb, 0x1p-10, -10.0);
100   TESTIT (logb, 0x1p-5, -5.0);
101   TESTIT (logb, 1/9.0, -4.0);
102   TESTIT (logb, 1/3.0, -2.0);
103   TESTIT (logb, 1.0, 0.0);
104   TESTIT (logb, 1.5, 0.0);
105   TESTIT (logb, 2.0, 1.0);
106   TESTIT (logb, 100/3.0, 5.0);
107   TESTIT (logb, 0x1p5, 5.0);
108   TESTIT (logb, 0x1p10, 10.0);
109   TESTIT (logb, 0x1p20, 20.0);
110   TESTIT (logb, 0x1p30, 30.0);
111   TESTIT (logb, 0x1p40, 40.0);
112 #endif
113
114   /* If radix == 2, test that ilogb(ARG2) -> ARG3.  */
115 #if __FLT_RADIX__ == 2
116   TESTIT2 (ilogb, -0x1p40, 40);
117   TESTIT2 (ilogb, -0x1p30, 30);
118   TESTIT2 (ilogb, -0x1p20, 20);
119   TESTIT2 (ilogb, -0x1p10, 10);
120   TESTIT2 (ilogb, -0x1p5, 5);
121   TESTIT2 (ilogb, -100/3.0, 5);
122   TESTIT2 (ilogb, -2.0, 1);
123   TESTIT2 (ilogb, -1.5, 0);
124   TESTIT2 (ilogb, -1.0, 0);
125   TESTIT2 (ilogb, -1/3.0, -2);
126   TESTIT2 (ilogb, -1/9.0, -4);
127   TESTIT2 (ilogb, -0x1p-5, -5);
128   TESTIT2 (ilogb, -0x1p-10, -10);
129   TESTIT2 (ilogb, -0x1p-20, -20);
130   TESTIT2 (ilogb, -0x1p-30, -30);
131   TESTIT2 (ilogb, -0x1p-40, -40);
132
133   TESTIT2 (ilogb, 0x1p-40, -40);
134   TESTIT2 (ilogb, 0x1p-30, -30);
135   TESTIT2 (ilogb, 0x1p-20, -20);
136   TESTIT2 (ilogb, 0x1p-10, -10);
137   TESTIT2 (ilogb, 0x1p-5, -5);
138   TESTIT2 (ilogb, 1/9.0, -4);
139   TESTIT2 (ilogb, 1/3.0, -2);
140   TESTIT2 (ilogb, 1.0, 0);
141   TESTIT2 (ilogb, 1.5, 0);
142   TESTIT2 (ilogb, 2.0, 1);
143   TESTIT2 (ilogb, 100/3.0, 5);
144   TESTIT2 (ilogb, 0x1p5, 5);
145   TESTIT2 (ilogb, 0x1p10, 10);
146   TESTIT2 (ilogb, 0x1p20, 20);
147   TESTIT2 (ilogb, 0x1p30, 30);
148   TESTIT2 (ilogb, 0x1p40, 40);
149 #endif
150
151   /* If radix == 2, test that significand(ARG2) -> ARG3.  Zero always
152      folds regardless of the radix.  */
153   TESTIT (significand, -0.0, -0.0);
154   TESTIT (significand, 0.0, 0.0);
155
156 #if __FLT_RADIX__ == 2
157   TESTIT (significand, -0x1p5, -1.0);
158   TESTIT (significand, -100/3.0, -100/96.0);
159   TESTIT (significand, -1.5, -1.5);
160   TESTIT (significand, -1.0, -1.0);
161   TESTIT (significand, -1/3.0, -4/3.0);
162   TESTIT (significand, -1/9.0, -16/9.0);
163   TESTIT (significand, -0x1p-5, -1.0);
164
165   TESTIT (significand, 0x1p-5, 1.0);
166   TESTIT (significand, 1/9.0, 16/9.0);
167   TESTIT (significand, 1/3.0, 4/3.0);
168   TESTIT (significand, 1.0, 1.0);
169   TESTIT (significand, 1.5, 1.5);
170   TESTIT (significand, 100/3.0, 100/96.0);
171   TESTIT (significand, 0x1p5, 1.0);
172 #endif
173
174   /* Test for f(+-Inf) -> +-Inf and f(+-NaN) -> +-NaN, regardless of
175      the radix.  */
176   TESTIT3 (logb, ,inf, , isinf);
177   TESTIT3 (logb, - ,inf, , isinf);
178   TESTIT3 (logb,  ,nan, "", isnan);
179   TESTIT3 (logb, - ,nan, "", isnan);
180
181   TESTIT3 (significand, ,inf, , isinf);
182   TESTIT3 (significand, - ,inf, , isinf);
183   TESTIT3 (significand,  ,nan, "", isnan);
184   TESTIT3 (significand, - ,nan, "", isnan);
185 }
186
187 int main()
188 {
189   foo ();
190   
191   return 0;
192 }