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__))
foo(void)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
main()176 int main()
177 {
178 foo ();
179
180 return 0;
181 }
182