[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / win-math.ll
blob38ed949e949dcef4f01822c81ede9495cbde3805
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
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
22     ret float %3
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
35     ret float %3
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
48     ret float %3
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
62     ret float %4
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
79     ret float %3
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
92     ret float %3
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
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
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
118     ret float %3
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
132     ret float %4
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
146     ret float %4
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
163     ret float %3
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
177     ret float %4
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
190     ret float %3
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
203     ret float %3
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
217     ret float %4
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
230     ret float %3
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
243     ret float %3
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
264     ret float %3
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
277     ret float %3
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
290     ret float %3
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
308     ret float %3
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 float @powf(float %x, float 0.5)
334     ret float %1