1 /* Copyright (C) 2007 Free Software Foundation.
3 Verify that built-in folding of ldexp et al. is correctly performed
6 Origin: Kaveh R. Ghazi, February 17, 2007. */
9 /* { dg-options "-fno-finite-math-only" { target sh*-*-* } } */
10 /* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
12 extern void link_error(int);
14 /* Return TRUE if the sign of X != sign of Y. This is important when
15 comparing signed zeros. */
16 #define CKSGN_F(X,Y) \
17 (__builtin_copysignf(1.0F,(X)) != __builtin_copysignf(1.0F,(Y)))
19 (__builtin_copysign(1.0,(X)) != __builtin_copysign(1.0,(Y)))
20 #define CKSGN_L(X,Y) \
21 (__builtin_copysignl(1.0L,(X)) != __builtin_copysignl(1.0L,(Y)))
23 /* Test that FUNC(ARG1,ARG2) == RES. Check the sign for -0.0. */
24 #define TESTIT(FUNC,ARG1,ARG2,RES) do { \
25 if (__builtin_##FUNC##f(ARG1##f,ARG2) != RES##f \
26 || CKSGN_F(__builtin_##FUNC##f(ARG1##f,ARG2),RES##f)) \
27 link_error(__LINE__); \
28 if (__builtin_##FUNC(ARG1,ARG2) != RES \
29 || CKSGN(__builtin_##FUNC(ARG1,ARG2),RES)) \
30 link_error(__LINE__); \
31 if (__builtin_##FUNC##l(ARG1##l,ARG2) != RES##l \
32 || CKSGN_L(__builtin_##FUNC##l(ARG1##l,ARG2),RES##l)) \
33 link_error(__LINE__); \
36 /* Test that (long)FUNC(ARG1,ARG2) == (long)RES. The cast is
37 necessary when RES is not a constant. */
38 #define TESTIT2(FUNC,ARG1,ARG2,RES) do { \
39 if ((long)__builtin_##FUNC##f(ARG1##f,ARG2) != (long)RES##f) \
40 link_error(__LINE__); \
41 if ((long)__builtin_##FUNC(ARG1,ARG2) != (long)RES) \
42 link_error(__LINE__); \
43 if ((long)__builtin_##FUNC##l(ARG1##l,ARG2) != (long)RES##l) \
44 link_error(__LINE__); \
47 /* Test that FUNCRES(FUNC(NEG FUNCARG(ARGARG),ARG2)) is false. Check
50 #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,ARG2,FUNCRES) do { \
51 if (!__builtin_##FUNCRES##f(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG),ARG2)) \
52 || CKSGN_F(__builtin_##FUNC##f(NEG __builtin_##FUNCARG##f(ARGARG),ARG2), NEG __builtin_##FUNCARG##f(ARGARG))) \
53 link_error(__LINE__); \
54 if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2)) \
55 || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2), NEG __builtin_##FUNCARG(ARGARG))) \
56 link_error(__LINE__); \
57 if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2)) \
58 || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2), NEG __builtin_##FUNCARG##l(ARGARG))) \
59 link_error(__LINE__); \
62 #define TESTIT3(FUNC,NEG,FUNCARG,ARGARG,ARG2,FUNCRES) do { \
63 /* SPU single-precision floating point format does not support Inf or Nan. */ \
64 if (!__builtin_##FUNCRES(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2)) \
65 || CKSGN(__builtin_##FUNC(NEG __builtin_##FUNCARG(ARGARG),ARG2), NEG __builtin_##FUNCARG(ARGARG))) \
66 link_error(__LINE__); \
67 if (!__builtin_##FUNCRES##l(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2)) \
68 || CKSGN_L(__builtin_##FUNC##l(NEG __builtin_##FUNCARG##l(ARGARG),ARG2), NEG __builtin_##FUNCARG##l(ARGARG))) \
69 link_error(__LINE__); \
73 /* Using foo==MIN/MAX float values, test that FUNC(foo,EXP) == foo*exp2(EXP),
74 and also that FUNC(foo,-EXP) == foo*exp2(-EXP). */
75 #define TESTIT4(FUNC,EXP) do { \
76 if (__builtin_##FUNC##f(__FLT_MIN__,EXP) != __FLT_MIN__*__builtin_exp2f(EXP)) \
77 link_error(__LINE__); \
78 if (__builtin_##FUNC##f(-__FLT_MIN__,EXP) != -__FLT_MIN__*__builtin_exp2f(EXP)) \
79 link_error(__LINE__); \
80 if (__builtin_##FUNC(__DBL_MIN__,EXP) != __DBL_MIN__*__builtin_exp2(EXP)) \
81 link_error(__LINE__); \
82 if (__builtin_##FUNC(-__DBL_MIN__,EXP) != -__DBL_MIN__*__builtin_exp2(EXP)) \
83 link_error(__LINE__); \
84 if (__builtin_##FUNC##l(__LDBL_MIN__,EXP) != __LDBL_MIN__*__builtin_exp2l(EXP)) \
85 link_error(__LINE__); \
86 if (__builtin_##FUNC##l(-__LDBL_MIN__,EXP) != -__LDBL_MIN__*__builtin_exp2l(EXP)) \
87 link_error(__LINE__); \
88 if (__builtin_##FUNC##f(__FLT_MAX__,-EXP) != __FLT_MAX__*__builtin_exp2f(-EXP)) \
89 link_error(__LINE__); \
90 if (__builtin_##FUNC##f(-__FLT_MAX__,-EXP) != -__FLT_MAX__*__builtin_exp2f(-EXP)) \
91 link_error(__LINE__); \
92 if (__builtin_##FUNC(__DBL_MAX__,-EXP) != __DBL_MAX__*__builtin_exp2(-EXP)) \
93 link_error(__LINE__); \
94 if (__builtin_##FUNC(-__DBL_MAX__,-EXP) != -__DBL_MAX__*__builtin_exp2(-EXP)) \
95 link_error(__LINE__); \
96 if (__builtin_##FUNC##l(__LDBL_MAX__,-EXP) != __LDBL_MAX__*__builtin_exp2l(-EXP)) \
97 link_error(__LINE__); \
98 if (__builtin_##FUNC##l(-__LDBL_MAX__,-EXP) != -__LDBL_MAX__*__builtin_exp2l(-EXP)) \
99 link_error(__LINE__); \
102 void __attribute__ ((__noinline__
))
103 foo(float xf
, double x
, long double xl
, int i
, long l
)
105 /* f(0.0, i) -> 0.0 and f(-0.0, i) -> -0.0. */
106 TESTIT (ldexp
, 0.0, i
, 0.0);
107 TESTIT (ldexp
, -0.0, i
, -0.0);
108 TESTIT (scalbn
, 0.0, i
, 0.0);
109 TESTIT (scalbn
, -0.0, i
, -0.0);
110 TESTIT (scalbln
, 0.0, l
, 0.0);
111 TESTIT (scalbln
, -0.0, l
, -0.0);
114 TESTIT2 (ldexp
, x
, 0, x
);
115 TESTIT2 (scalbn
, x
, 0, x
);
116 TESTIT2 (scalbln
, x
, 0, x
);
118 /* f(Inf,i) -> Inf and f(NaN,i) -> NaN. */
119 TESTIT3 (ldexp
, , inf
, , i
, isinf
);
120 TESTIT3 (ldexp
, -, inf
, , i
, isinf
);
121 TESTIT3 (ldexp
, , nan
, "", i
, isnan
);
122 TESTIT3 (ldexp
, -, nan
, "", i
, isnan
);
124 TESTIT3 (scalbn
, , inf
, , i
, isinf
);
125 TESTIT3 (scalbn
, -, inf
, , i
, isinf
);
126 TESTIT3 (scalbn
, , nan
, "", i
, isnan
);
127 TESTIT3 (scalbn
, -, nan
, "", i
, isnan
);
129 TESTIT3 (scalbln
, , inf
, , i
, isinf
);
130 TESTIT3 (scalbln
, -, inf
, , i
, isinf
);
131 TESTIT3 (scalbln
, , nan
, "", i
, isnan
);
132 TESTIT3 (scalbln
, -, nan
, "", i
, isnan
);
134 /* Evaluate when both arguments are constant. */
135 TESTIT (ldexp
, 5.0, 3, 40.0);
136 TESTIT (ldexp
, -5.0, 3, -40.0);
137 TESTIT (ldexp
, 5.0, -3, 0.625);
138 TESTIT (ldexp
, -5.0, -3, -0.625);
140 TESTIT (ldexp
, 1000.0, 5, 32000.0);
141 TESTIT (ldexp
, -1000.0, 5, -32000.0);
142 TESTIT (ldexp
, 1000.0, -5, 31.25);
143 TESTIT (ldexp
, -1000.0, -5, -31.25);
145 /* f(x,N) -> x*exp2(N), using MIN/MAX constants for x and constant N. */
157 TESTIT4 (ldexp
, 100);
158 TESTIT4 (ldexp
, 123);
160 /* These are folded when float radix is two. */
161 #if __FLT_RADIX__ == 2
162 TESTIT (scalbn
, 5.0, 3, 40.0);
163 TESTIT (scalbn
, -5.0, 3, -40.0);
164 TESTIT (scalbn
, 5.0, -3, 0.625);
165 TESTIT (scalbn
, -5.0, -3, -0.625);
167 TESTIT (scalbn
, 1000.0, 5, 32000.0);
168 TESTIT (scalbn
, -1000.0, 5, -32000.0);
169 TESTIT (scalbn
, 1000.0, -5, 31.25);
170 TESTIT (scalbn
, -1000.0, -5, -31.25);
177 TESTIT4 (scalbn
, 10);
178 TESTIT4 (scalbn
, 12);
179 TESTIT4 (scalbn
, 18);
180 TESTIT4 (scalbn
, 25);
181 TESTIT4 (scalbn
, 50);
182 TESTIT4 (scalbn
, 75);
183 TESTIT4 (scalbn
, 100);
184 TESTIT4 (scalbn
, 123);
186 TESTIT (scalbln
, 5.0, 3, 40.0);
187 TESTIT (scalbln
, -5.0, 3, -40.0);
188 TESTIT (scalbln
, 5.0, -3, 0.625);
189 TESTIT (scalbln
, -5.0, -3, -0.625);
191 TESTIT (scalbln
, 1000.0, 5, 32000.0);
192 TESTIT (scalbln
, -1000.0, 5, -32000.0);
193 TESTIT (scalbln
, 1000.0, -5, 31.25);
194 TESTIT (scalbln
, -1000.0, -5, -31.25);
196 TESTIT4 (scalbln
, 1);
197 TESTIT4 (scalbln
, 2);
198 TESTIT4 (scalbln
, 3);
199 TESTIT4 (scalbln
, 5);
200 TESTIT4 (scalbln
, 9);
201 TESTIT4 (scalbln
, 10);
202 TESTIT4 (scalbln
, 12);
203 TESTIT4 (scalbln
, 18);
204 TESTIT4 (scalbln
, 25);
205 TESTIT4 (scalbln
, 50);
206 TESTIT4 (scalbln
, 75);
207 TESTIT4 (scalbln
, 100);
208 TESTIT4 (scalbln
, 123);