1 |
689 |
jeremybenn |
/* Copyright (C) 2003, 2004 Free Software Foundation.
|
2 |
|
|
|
3 |
|
|
Verify that built-in math function constant folding of log & exp is
|
4 |
|
|
correctly performed by the compiler.
|
5 |
|
|
|
6 |
|
|
Written by Kaveh Ghazi, 2003-09-05. */
|
7 |
|
|
|
8 |
|
|
/* { dg-do link } */
|
9 |
|
|
/* { dg-options "-ffast-math" } */
|
10 |
|
|
|
11 |
|
|
/* Define "e" with as many bits as found in builtins.c:dconste. */
|
12 |
|
|
#define M_E 2.7182818284590452353602874713526624977572470936999595749669676277241
|
13 |
|
|
#define M_EF 2.7182818284590452353602874713526624977572470936999595749669676277241F
|
14 |
|
|
#define M_EL 2.7182818284590452353602874713526624977572470936999595749669676277241L
|
15 |
|
|
/* Precision for comparison tests. */
|
16 |
|
|
#define PREC (sizeof (float) < sizeof (double) ? 0.0000001 : PRECF)
|
17 |
|
|
#define PRECF 0.0001F
|
18 |
|
|
#define PRECL (sizeof (float) < sizeof (long double) \
|
19 |
|
|
? 0.0000000000001L : PRECF)
|
20 |
|
|
#define PROTOTYPE(FN) extern double FN(double); extern float FN##f(float); \
|
21 |
|
|
extern long double FN##l(long double);
|
22 |
|
|
#define PROTOTYPE2(FN) extern double FN(double, double); \
|
23 |
|
|
extern float FN##f(float, float); \
|
24 |
|
|
extern long double FN##l(long double, long double);
|
25 |
|
|
|
26 |
|
|
PROTOTYPE(exp)
|
27 |
|
|
PROTOTYPE(exp2)
|
28 |
|
|
PROTOTYPE(exp10)
|
29 |
|
|
PROTOTYPE(log)
|
30 |
|
|
PROTOTYPE(log2)
|
31 |
|
|
PROTOTYPE(log10)
|
32 |
|
|
PROTOTYPE(pow10)
|
33 |
|
|
PROTOTYPE(sqrt)
|
34 |
|
|
PROTOTYPE(cbrt)
|
35 |
|
|
PROTOTYPE2(pow)
|
36 |
|
|
|
37 |
|
|
void test(double d1, double d2, float f1, float f2,
|
38 |
|
|
long double ld1, long double ld2)
|
39 |
|
|
{
|
40 |
|
|
/* Test logN(1) -> 0. */
|
41 |
|
|
#define LOG_1(LOG) \
|
42 |
|
|
extern void link_failure_##LOG##_1(void); \
|
43 |
|
|
if (LOG(1.0) != 0.0 || LOG##f(1.0F) != 0.0F || LOG##l(1.0L) != 0.0L) \
|
44 |
|
|
link_failure_##LOG##_1()
|
45 |
|
|
|
46 |
|
|
LOG_1(log);
|
47 |
|
|
LOG_1(log2);
|
48 |
|
|
LOG_1(log10);
|
49 |
|
|
|
50 |
|
|
/* Test logN(N) -> 1. */
|
51 |
|
|
#define LOG_N(LOG, BASE) \
|
52 |
|
|
extern void link_failure_##LOG##_N(void); \
|
53 |
|
|
if (LOG(BASE) != 1.0 || LOG##f(BASE##F) != 1.0F || LOG##l(BASE##L) != 1.0L) \
|
54 |
|
|
link_failure_##LOG##_N()
|
55 |
|
|
|
56 |
|
|
LOG_N(log2, 2.0);
|
57 |
|
|
LOG_N(log10, 10.0);
|
58 |
|
|
|
59 |
|
|
/* Test logN(expN(x)) -> x. */
|
60 |
|
|
#define LOGEXP_SAME(LOG, EXP) \
|
61 |
|
|
extern void link_failure_##LOG##_##EXP##_same(void); \
|
62 |
|
|
if (LOG(EXP(d1)) != d1 || LOG##f(EXP##f(f1)) != f1 \
|
63 |
|
|
|| LOG##l(EXP##l(ld1)) != ld1) link_failure_##LOG##_##EXP##_same()
|
64 |
|
|
|
65 |
|
|
LOGEXP_SAME(log,exp);
|
66 |
|
|
LOGEXP_SAME(log2,exp2);
|
67 |
|
|
LOGEXP_SAME(log10,exp10);
|
68 |
|
|
LOGEXP_SAME(log10,pow10);
|
69 |
|
|
|
70 |
|
|
/* Test logN(expM(x)) -> x*logN(M). */
|
71 |
|
|
#define LOGEXP(LOG, EXP, BASE) \
|
72 |
|
|
extern void link_failure_##LOG##_##EXP(void); \
|
73 |
|
|
if (LOG(EXP(d1)) != d1*LOG(BASE) || LOG##f(EXP##f(f1)) != f1*LOG##f(BASE##F) \
|
74 |
|
|
|| LOG##l(EXP##l(ld1)) != ld1*LOG##l(BASE##L)) link_failure_##LOG##_##EXP()
|
75 |
|
|
|
76 |
|
|
LOGEXP(log,exp2,2.0);
|
77 |
|
|
LOGEXP(log,exp10,10.0);
|
78 |
|
|
LOGEXP(log,pow10,10.0);
|
79 |
|
|
LOGEXP(log2,exp,M_E);
|
80 |
|
|
LOGEXP(log2,exp2,2.0);
|
81 |
|
|
LOGEXP(log2,exp10,10.0);
|
82 |
|
|
LOGEXP(log2,pow10,10.0);
|
83 |
|
|
LOGEXP(log10,exp,M_E);
|
84 |
|
|
LOGEXP(log10,exp2,2.0);
|
85 |
|
|
LOGEXP(log10,exp10,10.0);
|
86 |
|
|
LOGEXP(log10,pow10,10.0);
|
87 |
|
|
|
88 |
|
|
/* Test logN(sqrt(x)) -> 0.5*logN(x). */
|
89 |
|
|
#define LOG_SQRT(LOG) \
|
90 |
|
|
extern void link_failure_##LOG##_sqrt(void); \
|
91 |
|
|
if (LOG(sqrt(d1)) != 0.5*LOG(d1) || LOG##f(sqrtf(f1)) != 0.5F*LOG##f(f1) \
|
92 |
|
|
|| LOG##l(sqrtl(ld1)) != 0.5L*LOG##l(ld1)) link_failure_##LOG##_sqrt()
|
93 |
|
|
|
94 |
|
|
LOG_SQRT(log);
|
95 |
|
|
LOG_SQRT(log2);
|
96 |
|
|
LOG_SQRT(log10);
|
97 |
|
|
|
98 |
|
|
/* Test sqrt(expN(x)) -> expN(x*0.5). */
|
99 |
|
|
#define SQRT_EXP(EXP) \
|
100 |
|
|
extern void link_failure_sqrt_##EXP(void); \
|
101 |
|
|
if (sqrt(EXP(d1)) != EXP(d1*0.5) || sqrtf(EXP##f(f1)) != EXP##f(f1*0.5F) \
|
102 |
|
|
|| sqrtl(EXP##l(ld1)) != EXP##l(ld1*0.5L)) link_failure_sqrt_##EXP()
|
103 |
|
|
|
104 |
|
|
SQRT_EXP(exp);
|
105 |
|
|
SQRT_EXP(exp2);
|
106 |
|
|
SQRT_EXP(exp10);
|
107 |
|
|
SQRT_EXP(pow10);
|
108 |
|
|
|
109 |
|
|
/* Test logN(cbrt(x)) -> (1/3)*logN(x). */
|
110 |
|
|
#define LOG_CBRT(LOG) \
|
111 |
|
|
extern void link_failure_##LOG##_cbrt(void); \
|
112 |
|
|
if (LOG(cbrt(d1)) != (1.0/3)*LOG(d1) \
|
113 |
|
|
|| LOG##f(cbrtf(f1)) != (1.0F/3)*LOG##f(f1) \
|
114 |
|
|
|| LOG##l(cbrtl(ld1)) != (1.0L/3)*LOG##l(ld1)) link_failure_##LOG##_cbrt()
|
115 |
|
|
|
116 |
|
|
LOG_CBRT(log);
|
117 |
|
|
LOG_CBRT(log2);
|
118 |
|
|
LOG_CBRT(log10);
|
119 |
|
|
|
120 |
|
|
/* Test cbrt(expN(x)) -> expN(x/3). */
|
121 |
|
|
#define CBRT_EXP(EXP) \
|
122 |
|
|
extern void link_failure_cbrt_##EXP(void); \
|
123 |
|
|
if (cbrt(EXP(d1)) != EXP(d1/3.0) || cbrtf(EXP##f(f1)) != EXP##f(f1/3.0F) \
|
124 |
|
|
|| cbrtl(EXP##l(ld1)) != EXP##l(ld1/3.0L)) link_failure_cbrt_##EXP()
|
125 |
|
|
|
126 |
|
|
CBRT_EXP(exp);
|
127 |
|
|
CBRT_EXP(exp2);
|
128 |
|
|
CBRT_EXP(exp10);
|
129 |
|
|
CBRT_EXP(pow10);
|
130 |
|
|
|
131 |
|
|
/* Test logN(pow(x,y)) -> y*logN(x). */
|
132 |
|
|
#define LOG_POW(LOG, POW) \
|
133 |
|
|
extern void link_failure_##LOG##_##POW(void); \
|
134 |
|
|
if (LOG(POW(d1,d2)) != d2*LOG(d1) || LOG##f(POW##f(f1,f2)) != f2*LOG##f(f1) \
|
135 |
|
|
|| LOG##l(POW##l(ld1,ld2)) != ld2*LOG##l(ld1)) link_failure_##LOG##_##POW()
|
136 |
|
|
|
137 |
|
|
LOG_POW(log,pow);
|
138 |
|
|
LOG_POW(log2,pow);
|
139 |
|
|
LOG_POW(log10,pow);
|
140 |
|
|
|
141 |
|
|
/* Test pow(expN(x),y)) -> expN(x*y). */
|
142 |
|
|
#define POW_EXP(POW, EXP) \
|
143 |
|
|
extern void link_failure_##POW##_##EXP(void); \
|
144 |
|
|
if (POW(EXP(d1),d2) != EXP(d1*d2) || POW##f(EXP##f(f1),f2) != EXP##f(f1*f2) \
|
145 |
|
|
|| POW##l(EXP##l(ld1),ld2) != EXP##l(ld1*ld2)) link_failure_##POW##_##EXP()
|
146 |
|
|
|
147 |
|
|
POW_EXP(pow, exp);
|
148 |
|
|
POW_EXP(pow, exp2);
|
149 |
|
|
POW_EXP(pow, exp10);
|
150 |
|
|
POW_EXP(pow, pow10);
|
151 |
|
|
|
152 |
|
|
/* Test expN(0) -> 1. */
|
153 |
|
|
#define EXP_0(EXP) \
|
154 |
|
|
extern void link_failure_##EXP##_0(void); \
|
155 |
|
|
if (EXP(0.0) != 1.0 || EXP##f(0.0F) != 1.0F || EXP##l(0.0L) != 1.0L) \
|
156 |
|
|
link_failure_##EXP##_0()
|
157 |
|
|
|
158 |
|
|
EXP_0(exp);
|
159 |
|
|
EXP_0(exp2);
|
160 |
|
|
EXP_0(exp10);
|
161 |
|
|
EXP_0(pow10);
|
162 |
|
|
|
163 |
|
|
/* Test expN(1) -> N. */
|
164 |
|
|
#define EXP_N(EXP, BASE) \
|
165 |
|
|
extern void link_failure_##EXP##_N(void); \
|
166 |
|
|
if (EXP(1.0) != BASE || EXP##f(1.0F) != BASE##F || EXP##l(1.0L) != BASE##L) \
|
167 |
|
|
link_failure_##EXP##_N()
|
168 |
|
|
|
169 |
|
|
EXP_N(exp, M_E);
|
170 |
|
|
EXP_N(exp2, 2.0);
|
171 |
|
|
EXP_N(exp10, 10.0);
|
172 |
|
|
EXP_N(pow10, 10.0);
|
173 |
|
|
|
174 |
|
|
/* Test expN(integer) -> N*N*N*... */
|
175 |
|
|
#define EXP_INT(EXP, BASE) \
|
176 |
|
|
extern void link_failure_##EXP##_INT(void); \
|
177 |
|
|
if (EXP(5.0) < (BASE)*(BASE)*(BASE)*(BASE)*(BASE) - PREC \
|
178 |
|
|
|| EXP(5.0) > (BASE)*(BASE)*(BASE)*(BASE)*(BASE) + PREC \
|
179 |
|
|
|| EXP##f(5.0F) < (BASE##F)*(BASE##F)*(BASE##F)*(BASE##F)*(BASE##F) -PRECF \
|
180 |
|
|
|| EXP##f(5.0F) > (BASE##F)*(BASE##F)*(BASE##F)*(BASE##F)*(BASE##F) +PRECF \
|
181 |
|
|
|| EXP##l(5.0L) < (BASE##L)*(BASE##L)*(BASE##L)*(BASE##L)*(BASE##L) -PRECL \
|
182 |
|
|
|| EXP##l(5.0L) > (BASE##L)*(BASE##L)*(BASE##L)*(BASE##L)*(BASE##L) +PRECL) \
|
183 |
|
|
link_failure_##EXP##_INT()
|
184 |
|
|
|
185 |
|
|
EXP_INT(exp, M_E);
|
186 |
|
|
EXP_INT(exp2, 2.0);
|
187 |
|
|
EXP_INT(exp10, 10.0);
|
188 |
|
|
EXP_INT(pow10, 10.0);
|
189 |
|
|
|
190 |
|
|
/* Test expN(logN(x)) -> x. */
|
191 |
|
|
#define EXPLOG_SAME(EXP, LOG) \
|
192 |
|
|
extern void link_failure_##EXP##_##LOG##_same(void); \
|
193 |
|
|
if (EXP(LOG(d1)) != d1 || EXP##f(LOG##f(f1)) != f1 \
|
194 |
|
|
|| EXP##l(LOG##l(ld1)) != ld1) link_failure_##EXP##_##LOG##_same()
|
195 |
|
|
|
196 |
|
|
EXPLOG_SAME(exp, log);
|
197 |
|
|
EXPLOG_SAME(exp2, log2);
|
198 |
|
|
EXPLOG_SAME(exp10, log10);
|
199 |
|
|
EXPLOG_SAME(pow10, log10);
|
200 |
|
|
|
201 |
|
|
/* Test expN(x)*expN(y)) -> expN(x+y). */
|
202 |
|
|
#define EXPXEXP(EXP) \
|
203 |
|
|
extern void link_failure_##EXP##X##EXP(void); \
|
204 |
|
|
if (EXP(d1)*EXP(d2) != EXP(d1+d2) || EXP##f(f1)*EXP##f(f2) != EXP##f(f1+f2) \
|
205 |
|
|
|| EXP##l(ld1)*EXP##l(ld2) != EXP##l(ld1+ld2)) link_failure_##EXP##X##EXP()
|
206 |
|
|
|
207 |
|
|
EXPXEXP(exp);
|
208 |
|
|
EXPXEXP(exp2);
|
209 |
|
|
EXPXEXP(exp10);
|
210 |
|
|
EXPXEXP(pow10);
|
211 |
|
|
|
212 |
|
|
/* Test x/expN(y) -> x*expN(-y). */
|
213 |
|
|
/* Test expN(x)/expN(y) -> expN(x-y). */
|
214 |
|
|
#define DIVEXP(EXP) \
|
215 |
|
|
extern void link_failure_div1_##EXP(void); \
|
216 |
|
|
if (d1/EXP(d2) != d1*EXP(-d2) || f1/EXP##f(f2) != f1*EXP##f(-f2) \
|
217 |
|
|
|| ld1/EXP##l(ld2) != ld1*EXP##l(-ld2)) link_failure_div1_##EXP(); \
|
218 |
|
|
extern void link_failure_div2_##EXP(void); \
|
219 |
|
|
if (EXP(d1)/EXP(d2) != EXP(d1-d2) || EXP##f(f1)/EXP##f(f2) != EXP##f(f1-f2) \
|
220 |
|
|
|| EXP##l(ld1)/EXP##l(ld2) != EXP##l(ld1-ld2)) link_failure_div2_##EXP()
|
221 |
|
|
|
222 |
|
|
DIVEXP(exp);
|
223 |
|
|
DIVEXP(exp2);
|
224 |
|
|
DIVEXP(exp10);
|
225 |
|
|
DIVEXP(pow10);
|
226 |
|
|
}
|
227 |
|
|
|
228 |
|
|
int main (void)
|
229 |
|
|
{
|
230 |
|
|
return 0;
|
231 |
|
|
}
|