1; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc18   | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC32
2; RUN: opt < %s -O2 -S -mtriple=i386-pc-windows-msvc     | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC51
3; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-windows-msvc17 | FileCheck %s --check-prefixes=CHECK,MSVCXX,MSVC64
4; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-win32          | FileCheck %s --check-prefixes=CHECK,MSVC19,MSVC83
5; RUN: opt < %s -O2 -S -mtriple=i386-pc-mingw32          | FileCheck %s --check-prefixes=CHECK,MINGW32
6; RUN: opt < %s -O2 -S -mtriple=x86_64-pc-mingw32        | FileCheck %s --check-prefixes=CHECK,MINGW64
7
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.
11
12declare double @acos(double %x)
13define 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
22    ret float %3
23}
24
25declare double @asin(double %x)
26define 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
35    ret float %3
36}
37
38declare double @atan(double %x)
39define 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
48    ret float %3
49}
50
51declare double @atan2(double %x, double %y)
52define 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
62    ret float %4
63}
64
65declare double @ceil(double %x)
66define 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
79    ret float %3
80}
81
82declare double @_copysign(double %x)
83define 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
92    ret float %3
93}
94
95declare double @cos(double %x)
96define float @float_cos(float %x) nounwind readnone {
97; CHECK-LABEL: @float_cos(
98; MSVCXX-NOT: float @cosf
99; MSVCXX: double @cos
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
105    ret float %3
106}
107
108declare double @cosh(double %x)
109define 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
118    ret float %3
119}
120
121declare double @exp(double %x, double %y)
122define 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
132    ret float %4
133}
134
135declare double @fabs(double %x, double %y)
136define 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
146    ret float %4
147}
148
149declare double @floor(double %x)
150define 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
163    ret float %3
164}
165
166declare double @fmod(double %x, double %y)
167define 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
177    ret float %4
178}
179
180declare double @log(double %x)
181define 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
190    ret float %3
191}
192
193declare double @logb(double %x)
194define 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
203    ret float %3
204}
205
206declare double @pow(double %x, double %y)
207define 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
217    ret float %4
218}
219
220declare double @sin(double %x)
221define 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
230    ret float %3
231}
232
233declare double @sinh(double %x)
234define 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
243    ret float %3
244}
245
246declare double @sqrt(double %x)
247define 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
264    ret float %3
265}
266
267declare double @tan(double %x)
268define 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
277    ret float %3
278}
279
280declare double @tanh(double %x)
281define 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
290    ret float %3
291}
292
293; win32 does not have roundf; mingw32 does
294declare double @round(double %x)
295define 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
308    ret float %3
309}
310
311declare float @powf(float, float)
312
313; win32 lacks sqrtf & fabsf, win64 lacks fabsf, but
314; calls to the intrinsics can be emitted instead.
315define 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)
334    ret float %1
335}
336