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 27PROTOTYPE(exp) 28PROTOTYPE(exp2) 29PROTOTYPE(exp10) 30PROTOTYPE(log) 31PROTOTYPE(log2) 32PROTOTYPE(log10) 33PROTOTYPE(pow10) 34PROTOTYPE(sqrt) 35PROTOTYPE(cbrt) 36PROTOTYPE2(pow) 37 38void 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 229int main (void) 230{ 231 return 0; 232} 233