llvm.org GIT mirror llvm / d5bda5e
fix pr12559: mark unavailable win32 math libcalls also fix SimplifyLibCalls to use TLI rather than compile-time conditionals to enable optimizations on floor, ceil, round, rint, and nearbyint git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154960 91177308-0d34-0410-b5e6-96231b3b80d8 Joe Groff 7 years ago
4 changed file(s) with 372 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
8282 /// long double expm1l(long double x);
8383 expm1l,
8484 /// float expm1f(float x);
85 expl1f,
85 expm1f,
8686 /// double fabs(double x);
8787 fabs,
8888 /// long double fabsl(long double x);
158158 rint,
159159 /// float rintf(float x);
160160 rintf,
161 /// long dobule rintl(long double x);
161 /// long double rintl(long double x);
162162 rintl,
163 /// double round(double x);
164 round,
165 /// float roundf(float x);
166 roundf,
167 /// long double roundl(long double x);
168 roundl,
163169 /// double sin(double x);
164170 sin,
165171 /// long double sinl(long double x);
5555 "exp2f",
5656 "expm1",
5757 "expm1l",
58 "expl1f",
58 "expm1f",
5959 "fabs",
6060 "fabsl",
6161 "fabsf",
9494 "rint",
9595 "rintf",
9696 "rintl",
97 "round",
98 "roundf",
99 "roundl",
97100 "sin",
98101 "sinl",
99102 "sinf",
154157 TLI.setUnavailable(LibFunc::siprintf);
155158 TLI.setUnavailable(LibFunc::fiprintf);
156159 }
160
161 if (T.getOS() == Triple::Win32) {
162 // Win32 does not support long double
163 TLI.setUnavailable(LibFunc::acosl);
164 TLI.setUnavailable(LibFunc::asinl);
165 TLI.setUnavailable(LibFunc::atanl);
166 TLI.setUnavailable(LibFunc::atan2l);
167 TLI.setUnavailable(LibFunc::ceill);
168 TLI.setUnavailable(LibFunc::copysignl);
169 TLI.setUnavailable(LibFunc::cosl);
170 TLI.setUnavailable(LibFunc::coshl);
171 TLI.setUnavailable(LibFunc::expl);
172 TLI.setUnavailable(LibFunc::fabsf); // Win32 and Win64 both lack fabsf
173 TLI.setUnavailable(LibFunc::fabsl);
174 TLI.setUnavailable(LibFunc::floorl);
175 TLI.setUnavailable(LibFunc::fmodl);
176 TLI.setUnavailable(LibFunc::logl);
177 TLI.setUnavailable(LibFunc::powl);
178 TLI.setUnavailable(LibFunc::sinl);
179 TLI.setUnavailable(LibFunc::sinhl);
180 TLI.setUnavailable(LibFunc::sqrtl);
181 TLI.setUnavailable(LibFunc::tanl);
182 TLI.setUnavailable(LibFunc::tanhl);
183
184 // Win32 only has C89 math
185 TLI.setUnavailable(LibFunc::exp2);
186 TLI.setUnavailable(LibFunc::exp2f);
187 TLI.setUnavailable(LibFunc::exp2l);
188 TLI.setUnavailable(LibFunc::expm1);
189 TLI.setUnavailable(LibFunc::expm1f);
190 TLI.setUnavailable(LibFunc::expm1l);
191 TLI.setUnavailable(LibFunc::log2);
192 TLI.setUnavailable(LibFunc::log2f);
193 TLI.setUnavailable(LibFunc::log2l);
194 TLI.setUnavailable(LibFunc::log1p);
195 TLI.setUnavailable(LibFunc::log1pf);
196 TLI.setUnavailable(LibFunc::log1pl);
197 TLI.setUnavailable(LibFunc::nearbyint);
198 TLI.setUnavailable(LibFunc::nearbyintf);
199 TLI.setUnavailable(LibFunc::nearbyintl);
200 TLI.setUnavailable(LibFunc::rint);
201 TLI.setUnavailable(LibFunc::rintf);
202 TLI.setUnavailable(LibFunc::rintl);
203 TLI.setUnavailable(LibFunc::round);
204 TLI.setUnavailable(LibFunc::roundf);
205 TLI.setUnavailable(LibFunc::roundl);
206 TLI.setUnavailable(LibFunc::trunc);
207 TLI.setUnavailable(LibFunc::truncf);
208 TLI.setUnavailable(LibFunc::truncl);
209
210 // Win32 provides some C99 math with mangled names
211 TLI.setAvailableWithName(LibFunc::copysign, "_copysign");
212
213 if (T.getArch() == Triple::x86) {
214 // Win32 on x86 implements single-precision math functions as macros
215 TLI.setUnavailable(LibFunc::acosf);
216 TLI.setUnavailable(LibFunc::asinf);
217 TLI.setUnavailable(LibFunc::atanf);
218 TLI.setUnavailable(LibFunc::atan2f);
219 TLI.setUnavailable(LibFunc::ceilf);
220 TLI.setUnavailable(LibFunc::copysignf);
221 TLI.setUnavailable(LibFunc::cosf);
222 TLI.setUnavailable(LibFunc::coshf);
223 TLI.setUnavailable(LibFunc::expf);
224 TLI.setUnavailable(LibFunc::floorf);
225 TLI.setUnavailable(LibFunc::fmodf);
226 TLI.setUnavailable(LibFunc::logf);
227 TLI.setUnavailable(LibFunc::powf);
228 TLI.setUnavailable(LibFunc::sinf);
229 TLI.setUnavailable(LibFunc::sinhf);
230 TLI.setUnavailable(LibFunc::sqrtf);
231 TLI.setUnavailable(LibFunc::tanf);
232 TLI.setUnavailable(LibFunc::tanhf);
233 }
234 }
157235 }
158236
159237
15821582 Optimizations["llvm.exp2.f64"] = &Exp2;
15831583 Optimizations["llvm.exp2.f32"] = &Exp2;
15841584
1585 #ifdef HAVE_FLOORF
1586 Optimizations["floor"] = &UnaryDoubleFP;
1587 #endif
1588 #ifdef HAVE_CEILF
1589 Optimizations["ceil"] = &UnaryDoubleFP;
1590 #endif
1591 #ifdef HAVE_ROUNDF
1592 Optimizations["round"] = &UnaryDoubleFP;
1593 #endif
1594 #ifdef HAVE_RINTF
1595 Optimizations["rint"] = &UnaryDoubleFP;
1596 #endif
1597 #ifdef HAVE_NEARBYINTF
1598 Optimizations["nearbyint"] = &UnaryDoubleFP;
1599 #endif
1585 if (TLI->has(LibFunc::floor) && TLI->has(LibFunc::floorf))
1586 Optimizations["floor"] = &UnaryDoubleFP;
1587 if (TLI->has(LibFunc::ceil) && TLI->has(LibFunc::ceilf))
1588 Optimizations["ceil"] = &UnaryDoubleFP;
1589 if (TLI->has(LibFunc::round) && TLI->has(LibFunc::roundf))
1590 Optimizations["round"] = &UnaryDoubleFP;
1591 if (TLI->has(LibFunc::rint) && TLI->has(LibFunc::rintf))
1592 Optimizations["rint"] = &UnaryDoubleFP;
1593 if (TLI->has(LibFunc::nearbyint) && TLI->has(LibFunc::nearbyintf))
1594 Optimizations["nearbyint"] = &UnaryDoubleFP;
16001595
16011596 // Integer Optimizations
16021597 Optimizations["ffs"] = &FFS;
0 ; RUN: opt -O2 -S -mtriple=i386-pc-win32 < %s | FileCheck %s -check-prefix=WIN32
1 ; RUN: opt -O2 -S -mtriple=x86_64-pc-win32 < %s | FileCheck %s -check-prefix=WIN64
2 ; RUN: opt -O2 -S -mtriple=i386-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW32
3 ; RUN: opt -O2 -S -mtriple=x86_64-pc-mingw32 < %s | FileCheck %s -check-prefix=MINGW64
4
5 ; x86 win32 msvcrt does not provide entry points for single-precision libm.
6 ; x86-64 win32 msvcrt does (except for fabsf)
7 ; msvcrt does not provide C99 math, but mingw32 does.
8
9 declare double @acos(double %x)
10 define float @float_acos(float %x) nounwind readnone {
11 ; WIN32: @float_acos
12 ; WIN32-NOT: float @acosf
13 ; WIN32: double @acos
14 %1 = fpext float %x to double
15 %2 = call double @acos(double %1)
16 %3 = fptrunc double %2 to float
17 ret float %3
18 }
19
20 declare double @asin(double %x)
21 define float @float_asin(float %x) nounwind readnone {
22 ; WIN32: @float_asin
23 ; WIN32-NOT: float @asinf
24 ; WIN32: double @asin
25 %1 = fpext float %x to double
26 %2 = call double @asin(double %1)
27 %3 = fptrunc double %2 to float
28 ret float %3
29 }
30
31 declare double @atan(double %x)
32 define float @float_atan(float %x) nounwind readnone {
33 ; WIN32: @float_atan
34 ; WIN32-NOT: float @atanf
35 ; WIN32: double @atan
36 %1 = fpext float %x to double
37 %2 = call double @atan(double %1)
38 %3 = fptrunc double %2 to float
39 ret float %3
40 }
41
42 declare double @atan2(double %x, double %y)
43 define float @float_atan2(float %x, float %y) nounwind readnone {
44 ; WIN32: @float_atan2
45 ; WIN32-NOT: float @atan2f
46 ; WIN32: double @atan2
47 %1 = fpext float %x to double
48 %2 = fpext float %y to double
49 %3 = call double @atan2(double %1, double %2)
50 %4 = fptrunc double %3 to float
51 ret float %4
52 }
53
54 declare double @ceil(double %x)
55 define float @float_ceil(float %x) nounwind readnone {
56 ; WIN32: @float_ceil
57 ; WIN32-NOT: float @ceilf
58 ; WIN32: double @ceil
59 ; WIN64: @float_ceil
60 ; WIN64: float @ceilf
61 ; WIN64-NOT: double @ceil
62 ; MINGW32: @float_ceil
63 ; MINGW32: float @ceilf
64 ; MINGW32-NOT: double @ceil
65 ; MINGW64: @float_ceil
66 ; MINGW64: float @ceilf
67 ; MINGW64-NOT: double @ceil
68 %1 = fpext float %x to double
69 %2 = call double @ceil(double %1)
70 %3 = fptrunc double %2 to float
71 ret float %3
72 }
73
74 declare double @_copysign(double %x)
75 define float @float_copysign(float %x) nounwind readnone {
76 ; WIN32: @float_copysign
77 ; WIN32-NOT: float @copysignf
78 ; WIN32-NOT: float @_copysignf
79 ; WIN32: double @_copysign
80 %1 = fpext float %x to double
81 %2 = call double @_copysign(double %1)
82 %3 = fptrunc double %2 to float
83 ret float %3
84 }
85
86 declare double @cos(double %x)
87 define float @float_cos(float %x) nounwind readnone {
88 ; WIN32: @float_cos
89 ; WIN32-NOT: float @cosf
90 ; WIN32: double @cos
91 %1 = fpext float %x to double
92 %2 = call double @cos(double %1)
93 %3 = fptrunc double %2 to float
94 ret float %3
95 }
96
97 declare double @cosh(double %x)
98 define float @float_cosh(float %x) nounwind readnone {
99 ; WIN32: @float_cosh
100 ; WIN32-NOT: float @coshf
101 ; WIN32: double @cosh
102 %1 = fpext float %x to double
103 %2 = call double @cosh(double %1)
104 %3 = fptrunc double %2 to float
105 ret float %3
106 }
107
108 declare double @exp(double %x, double %y)
109 define float @float_exp(float %x, float %y) nounwind readnone {
110 ; WIN32: @float_exp
111 ; WIN32-NOT: float @expf
112 ; WIN32: double @exp
113 %1 = fpext float %x to double
114 %2 = fpext float %y to double
115 %3 = call double @exp(double %1, double %2)
116 %4 = fptrunc double %3 to float
117 ret float %4
118 }
119
120 declare double @fabs(double %x, double %y)
121 define float @float_fabs(float %x, float %y) nounwind readnone {
122 ; WIN32: @float_fabs
123 ; WIN32-NOT: float @fabsf
124 ; WIN32: double @fabs
125 ; WIN64: @float_fabs
126 ; WIN64-NOT: float @fabsf
127 ; WIN64: double @fabs
128 %1 = fpext float %x to double
129 %2 = fpext float %y to double
130 %3 = call double @fabs(double %1, double %2)
131 %4 = fptrunc double %3 to float
132 ret float %4
133 }
134
135 declare double @floor(double %x)
136 define float @float_floor(float %x) nounwind readnone {
137 ; WIN32: @float_floor
138 ; WIN32-NOT: float @floorf
139 ; WIN32: double @floor
140 ; WIN64: @float_floor
141 ; WIN64: float @floorf
142 ; WIN64-NOT: double @floor
143 ; MINGW32: @float_floor
144 ; MINGW32: float @floorf
145 ; MINGW32-NOT: double @floor
146 ; MINGW64: @float_floor
147 ; MINGW64: float @floorf
148 ; MINGW64-NOT: double @floor
149 %1 = fpext float %x to double
150 %2 = call double @floor(double %1)
151 %3 = fptrunc double %2 to float
152 ret float %3
153 }
154
155 declare double @fmod(double %x, double %y)
156 define float @float_fmod(float %x, float %y) nounwind readnone {
157 ; WIN32: @float_fmod
158 ; WIN32-NOT: float @fmodf
159 ; WIN32: double @fmod
160 %1 = fpext float %x to double
161 %2 = fpext float %y to double
162 %3 = call double @fmod(double %1, double %2)
163 %4 = fptrunc double %3 to float
164 ret float %4
165 }
166
167 declare double @log(double %x)
168 define float @float_log(float %x) nounwind readnone {
169 ; WIN32: @float_log
170 ; WIN32-NOT: float @logf
171 ; WIN32: double @log
172 %1 = fpext float %x to double
173 %2 = call double @log(double %1)
174 %3 = fptrunc double %2 to float
175 ret float %3
176 }
177
178 declare double @pow(double %x, double %y)
179 define float @float_pow(float %x, float %y) nounwind readnone {
180 ; WIN32: @float_pow
181 ; WIN32-NOT: float @powf
182 ; WIN32: double @pow
183 %1 = fpext float %x to double
184 %2 = fpext float %y to double
185 %3 = call double @pow(double %1, double %2)
186 %4 = fptrunc double %3 to float
187 ret float %4
188 }
189
190 declare double @sin(double %x)
191 define float @float_sin(float %x) nounwind readnone {
192 ; WIN32: @float_sin
193 ; WIN32-NOT: float @sinf
194 ; WIN32: double @sin
195 %1 = fpext float %x to double
196 %2 = call double @sin(double %1)
197 %3 = fptrunc double %2 to float
198 ret float %3
199 }
200
201 declare double @sinh(double %x)
202 define float @float_sinh(float %x) nounwind readnone {
203 ; WIN32: @float_sinh
204 ; WIN32-NOT: float @sinhf
205 ; WIN32: double @sinh
206 %1 = fpext float %x to double
207 %2 = call double @sinh(double %1)
208 %3 = fptrunc double %2 to float
209 ret float %3
210 }
211
212 declare double @sqrt(double %x)
213 define float @float_sqrt(float %x) nounwind readnone {
214 ; WIN32: @float_sqrt
215 ; WIN32-NOT: float @sqrtf
216 ; WIN32: double @sqrt
217 ; WIN64: @float_sqrt
218 ; WIN64: float @sqrtf
219 ; WIN64-NOT: double @sqrt
220 ; MINGW32: @float_sqrt
221 ; MINGW32: float @sqrtf
222 ; MINGW32-NOT: double @sqrt
223 ; MINGW64: @float_sqrt
224 ; MINGW64: float @sqrtf
225 ; MINGW64-NOT: double @sqrt
226 %1 = fpext float %x to double
227 %2 = call double @sqrt(double %1)
228 %3 = fptrunc double %2 to float
229 ret float %3
230 }
231
232 declare double @tan(double %x)
233 define float @float_tan(float %x) nounwind readnone {
234 ; WIN32: @float_tan
235 ; WIN32-NOT: float @tanf
236 ; WIN32: double @tan
237 %1 = fpext float %x to double
238 %2 = call double @tan(double %1)
239 %3 = fptrunc double %2 to float
240 ret float %3
241 }
242
243 declare double @tanh(double %x)
244 define float @float_tanh(float %x) nounwind readnone {
245 ; WIN32: @float_tanh
246 ; WIN32-NOT: float @tanhf
247 ; WIN32: double @tanh
248 %1 = fpext float %x to double
249 %2 = call double @tanh(double %1)
250 %3 = fptrunc double %2 to float
251 ret float %3
252 }
253
254 ; win32 does not have round; mingw32 does
255 declare double @round(double %x)
256 define float @float_round(float %x) nounwind readnone {
257 ; WIN32: @float_round
258 ; WIN32-NOT: float @roundf
259 ; WIN32: double @round
260 ; WIN64: @float_round
261 ; WIN64-NOT: float @roundf
262 ; WIN64: double @round
263 ; MINGW32: @float_round
264 ; MINGW32: float @roundf
265 ; MINGW32-NOT: double @round
266 ; MINGW64: @float_round
267 ; MINGW64: float @roundf
268 ; MINGW64-NOT: double @round
269 %1 = fpext float %x to double
270 %2 = call double @round(double %1)
271 %3 = fptrunc double %2 to float
272 ret float %3
273 }
274