1 ; RUN: opt %s -passes=instcombine -S -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC32
2 ; RUN: opt %s -passes=instcombine -S -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC51
3 ; RUN: opt %s -passes=instcombine -S -mtriple=x86_64-pc-windows-msvc17 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC64
4 ; RUN: opt %s -passes=instcombine -S -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC83
5 ; RUN: opt %s -passes=instcombine -S -mtriple=i386-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW32
6 ; RUN: opt %s -passes=instcombine -S -mtriple=x86_64-pc-mingw32 | FileCheck %s --check-prefixes=CHECK,MINGW64
8 ; x86 win32 msvcrt does not provide entry points for single-precision libm.
9 ; x86-64 win32 msvcrt does, but with exceptions
10 ; msvcrt does not provide all of C99 math, but mingw32 does.
12 declare double @acos(double %x)
13 define float @float_acos(float %x) nounwind readnone {
14 ; CHECK-LABEL: @float_acos(
15 ; MSVCXX-NOT: float @acosf
16 ; MSVCXX: double @acos
17 ; MSVC19-NOT: float @acosf
18 ; MSVC19: double @acos
19 %1 = fpext float %x to double
20 %2 = call double @acos(double %1)
21 %3 = fptrunc double %2 to float
25 declare double @asin(double %x)
26 define float @float_asin(float %x) nounwind readnone {
27 ; CHECK-LABEL: @float_asin(
28 ; MSVCXX-NOT: float @asinf
29 ; MSVCXX: double @asin
30 ; MSVC19-NOT: float @asinf
31 ; MSVC19: double @asin
32 %1 = fpext float %x to double
33 %2 = call double @asin(double %1)
34 %3 = fptrunc double %2 to float
38 declare double @atan(double %x)
39 define float @float_atan(float %x) nounwind readnone {
40 ; CHECK-LABEL: @float_atan(
41 ; MSVCXX-NOT: float @atanf
42 ; MSVCXX: double @atan
43 ; MSVC19-NOT: float @atanf
44 ; MSVC19: double @atan
45 %1 = fpext float %x to double
46 %2 = call double @atan(double %1)
47 %3 = fptrunc double %2 to float
51 declare double @atan2(double %x, double %y)
52 define float @float_atan2(float %x, float %y) nounwind readnone {
53 ; CHECK-LABEL: @float_atan2(
54 ; MSVCXX-NOT: float @atan2f
55 ; MSVCXX: double @atan2
56 ; MSVC19-NOT: float @atan2f
57 ; MSVC19: double @atan2
58 %1 = fpext float %x to double
59 %2 = fpext float %y to double
60 %3 = call double @atan2(double %1, double %2)
61 %4 = fptrunc double %3 to float
65 declare double @ceil(double %x)
66 define float @float_ceil(float %x) nounwind readnone {
67 ; CHECK-LABEL: @float_ceil(
68 ; MSVCXX-NOT: float @ceilf
69 ; MSVCXX: float @llvm.ceil.f32
70 ; MSVC19-NOT: double @ceil
71 ; MSVC19: float @llvm.ceil.f32
72 ; MINGW32-NOT: double @ceil
73 ; MINGW32: float @llvm.ceil.f32
74 ; MINGW64-NOT: double @ceil
75 ; MINGW64: float @llvm.ceil.f32
76 %1 = fpext float %x to double
77 %2 = call double @ceil(double %1)
78 %3 = fptrunc double %2 to float
82 declare double @_copysign(double %x)
83 define float @float_copysign(float %x) nounwind readnone {
84 ; CHECK-LABEL: @float_copysign(
85 ; MSVCXX-NOT: float @_copysignf
86 ; MSVCXX: double @_copysign
87 ; MSVC19-NOT: float @_copysignf
88 ; MSVC19: double @_copysign
89 %1 = fpext float %x to double
90 %2 = call double @_copysign(double %1)
91 %3 = fptrunc double %2 to float
95 declare double @cos(double %x)
96 define float @float_cos(float %x) nounwind readnone {
97 ; CHECK-LABEL: @float_cos(
98 ; MSVCXX-NOT: float @cosf
100 ; MSVC19-NOT: float @cosf
101 ; MSVC19: double @cos
102 %1 = fpext float %x to double
103 %2 = call double @cos(double %1)
104 %3 = fptrunc double %2 to float
108 declare double @cosh(double %x)
109 define float @float_cosh(float %x) nounwind readnone {
110 ; CHECK-LABEL: @float_cosh(
111 ; MSVCXX-NOT: float @coshf
112 ; MSVCXX: double @cosh
113 ; MSVC19-NOT: float @coshf
114 ; MSVC19: double @cosh
115 %1 = fpext float %x to double
116 %2 = call double @cosh(double %1)
117 %3 = fptrunc double %2 to float
121 declare double @exp(double %x, double %y)
122 define float @float_exp(float %x, float %y) nounwind readnone {
123 ; CHECK-LABEL: @float_exp(
124 ; MSVCXX-NOT: float @expf
125 ; MSVCXX: double @exp
126 ; MSVC19-NOT: float @expf
127 ; MSVC19: double @exp
128 %1 = fpext float %x to double
129 %2 = fpext float %y to double
130 %3 = call double @exp(double %1, double %2)
131 %4 = fptrunc double %3 to float
135 declare double @fabs(double %x, double %y)
136 define float @float_fabs(float %x, float %y) nounwind readnone {
137 ; CHECK-LABEL: @float_fabs(
138 ; MSVCXX-NOT: float @fabsf
139 ; MSVCXX: double @fabs
140 ; MSVC19-NOT: float @fabsf
141 ; MSVC19: double @fabs
142 %1 = fpext float %x to double
143 %2 = fpext float %y to double
144 %3 = call double @fabs(double %1, double %2)
145 %4 = fptrunc double %3 to float
149 declare double @floor(double %x)
150 define float @float_floor(float %x) nounwind readnone {
151 ; CHECK-LABEL: @float_floor(
152 ; MSVCXX-NOT: float @floorf
153 ; MSVCXX: float @llvm.floor.f32
154 ; MSVC19-NOT: double @floor
155 ; MSVC19: float @llvm.floor.f32
156 ; MINGW32-NOT: double @floor
157 ; MINGW32: float @llvm.floor.f32
158 ; MINGW64-NOT: double @floor
159 ; MINGW64: float @llvm.floor.f32
160 %1 = fpext float %x to double
161 %2 = call double @floor(double %1)
162 %3 = fptrunc double %2 to float
166 declare double @fmod(double %x, double %y)
167 define float @float_fmod(float %x, float %y) nounwind readnone {
168 ; MSVCXX-LABEL: @float_fmod(
169 ; MSVCXX-NOT: float @fmodf
170 ; MSVCXX: double @fmod
171 ; MSVC19-NOT: float @fmodf
172 ; MSVC19: double @fmod
173 %1 = fpext float %x to double
174 %2 = fpext float %y to double
175 %3 = call double @fmod(double %1, double %2)
176 %4 = fptrunc double %3 to float
180 declare double @log(double %x)
181 define float @float_log(float %x) nounwind readnone {
182 ; CHECK-LABEL: @float_log(
183 ; MSVCXX-NOT: float @logf
184 ; MSVCXX: double @log
185 ; MSVC19-NOT: float @logf
186 ; MSVC19: double @log
187 %1 = fpext float %x to double
188 %2 = call double @log(double %1)
189 %3 = fptrunc double %2 to float
193 declare double @logb(double %x)
194 define float @float_logb(float %x) nounwind readnone {
195 ; CHECK-LABEL: @float_logb(
196 ; MSVCXX-NOT: float @logbf
197 ; MSVCXX: double @logb
198 ; MSVC19-NOT: float @logbf
199 ; MSVC19: double @logb
200 %1 = fpext float %x to double
201 %2 = call double @logb(double %1)
202 %3 = fptrunc double %2 to float
206 declare double @pow(double %x, double %y)
207 define float @float_pow(float %x, float %y) nounwind readnone {
208 ; CHECK-LABEL: @float_pow(
209 ; MSVCXX-NOT: float @powf
210 ; MSVCXX: double @pow
211 ; MSVC19-NOT: float @powf
212 ; MSVC19: double @pow
213 %1 = fpext float %x to double
214 %2 = fpext float %y to double
215 %3 = call double @pow(double %1, double %2)
216 %4 = fptrunc double %3 to float
220 declare double @sin(double %x)
221 define float @float_sin(float %x) nounwind readnone {
222 ; CHECK-LABEL: @float_sin(
223 ; MSVCXX-NOT: float @sinf
224 ; MSVCXX: double @sin
225 ; MSVC19-NOT: float @sinf
226 ; MSVC19: double @sin
227 %1 = fpext float %x to double
228 %2 = call double @sin(double %1)
229 %3 = fptrunc double %2 to float
233 declare double @sinh(double %x)
234 define float @float_sinh(float %x) nounwind readnone {
235 ; CHECK-LABEL: @float_sinh(
236 ; MSVCXX-NOT: float @sinhf
237 ; MSVCXX: double @sinh
238 ; MSVC19-NOT: float @sinhf
239 ; MSVC19: double @sinh
240 %1 = fpext float %x to double
241 %2 = call double @sinh(double %1)
242 %3 = fptrunc double %2 to float
246 declare double @sqrt(double %x)
247 define float @float_sqrt(float %x) nounwind readnone {
248 ; CHECK-LABEL: @float_sqrt(
249 ; MSVC32-NOT: float @sqrtf
250 ; MSVC32: double @sqrt
251 ; MSVC51-NOT: float @sqrtf
252 ; MSVC51: double @sqrt
253 ; MSVC64-NOT: double @sqrt
254 ; MSVC64: float @sqrtf
255 ; MSVC83-NOT: double @sqrt
256 ; MSVC83: float @sqrtf
257 ; MINGW32-NOT: double @sqrt
258 ; MINGW32: float @sqrtf
259 ; MINGW64-NOT: double @sqrt
260 ; MINGW64: float @sqrtf
261 %1 = fpext float %x to double
262 %2 = call double @sqrt(double %1)
263 %3 = fptrunc double %2 to float
267 declare double @tan(double %x)
268 define float @float_tan(float %x) nounwind readnone {
269 ; CHECK-LABEL: @float_tan(
270 ; MSVCXX-NOT: float @tanf
271 ; MSVCXX: double @tan
272 ; MSVC19-NOT: float @tanf
273 ; MSVC19: double @tan
274 %1 = fpext float %x to double
275 %2 = call double @tan(double %1)
276 %3 = fptrunc double %2 to float
280 declare double @tanh(double %x)
281 define float @float_tanh(float %x) nounwind readnone {
282 ; CHECK-LABEL: @float_tanh(
283 ; MSVCXX-NOT: float @tanhf
284 ; MSVCXX: double @tanh
285 ; MSVC19-NOT: float @tanhf
286 ; MSVC19: double @tanh
287 %1 = fpext float %x to double
288 %2 = call double @tanh(double %1)
289 %3 = fptrunc double %2 to float
293 ; win32 does not have roundf; mingw32 does
294 declare double @round(double %x)
295 define float @float_round(float %x) nounwind readnone {
296 ; CHECK-LABEL: @float_round(
297 ; MSVCXX-NOT: double @roundf
298 ; MSVCXX: double @round
299 ; MSVC19-NOT: double @round
300 ; MSVC19: float @llvm.round.f32
301 ; MINGW32-NOT: double @round
302 ; MINGW32: float @llvm.round.f32
303 ; MINGW64-NOT: double @round
304 ; MINGW64: float @llvm.round.f32
305 %1 = fpext float %x to double
306 %2 = call double @round(double %1)
307 %3 = fptrunc double %2 to float
311 declare float @powf(float, float)
313 ; win32 lacks sqrtf & fabsf, win64 lacks fabsf, but
314 ; calls to the intrinsics can be emitted instead.
315 define float @float_powsqrt(float %x) nounwind readnone {
316 ; CHECK-LABEL: @float_powsqrt(
317 ; MSVC32-NOT: float @sqrtf
318 ; MSVC32: float @powf
319 ; MSVC51-NOT: float @sqrtf
320 ; MSVC51: float @powf
321 ; MSVC64-NOT: float @powf
322 ; MSVC64: float @sqrtf
323 ; MSVC64: float @llvm.fabs.f32(
324 ; MSVC83-NOT: float @powf
325 ; MSVC83: float @sqrtf
326 ; MSVC83: float @llvm.fabs.f32(
327 ; MINGW32-NOT: float @powf
328 ; MINGW32: float @sqrtf
329 ; MINGW32: float @llvm.fabs.f32
330 ; MINGW64-NOT: float @powf
331 ; MINGW64: float @sqrtf
332 ; MINGW64: float @llvm.fabs.f32(
333 %1 = call ninf float @powf(float %x, float 0.5)