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