1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux" | FileCheck %s
3 ; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32" | FileCheck %s
4 ; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" | FileCheck %s
5 ; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32" | FileCheck %s
6 ; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck %s
7 ; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck %s
8 ; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" -enable-debugify 2>&1 | FileCheck --check-prefix=DBG-VALID %s
10 declare double @floor(double)
11 declare double @ceil(double)
12 declare double @round(double)
13 declare double @nearbyint(double)
14 declare double @trunc(double)
15 declare double @fabs(double)
17 declare double @llvm.ceil.f64(double)
18 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
20 declare double @llvm.fabs.f64(double)
21 declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
23 declare double @llvm.floor.f64(double)
24 declare <2 x double> @llvm.floor.v2f64(<2 x double>)
26 declare double @llvm.nearbyint.f64(double)
27 declare <2 x double> @llvm.nearbyint.v2f64(<2 x double>)
29 declare float @llvm.rint.f32(float)
30 declare <2 x float> @llvm.rint.v2f32(<2 x float>)
32 declare double @llvm.round.f64(double)
33 declare <2 x double> @llvm.round.v2f64(<2 x double>)
35 declare double @llvm.trunc.f64(double)
36 declare <2 x double> @llvm.trunc.v2f64(<2 x double>)
38 define float @test_shrink_libcall_floor(float %C) {
39 ; CHECK-LABEL: @test_shrink_libcall_floor(
40 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.floor.f32(float [[C:%.*]])
41 ; CHECK-NEXT: ret float [[F]]
43 %D = fpext float %C to double
45 %E = call double @floor(double %D)
46 %F = fptrunc double %E to float
50 define float @test_shrink_libcall_ceil(float %C) {
51 ; CHECK-LABEL: @test_shrink_libcall_ceil(
52 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]])
53 ; CHECK-NEXT: ret float [[F]]
55 %D = fpext float %C to double
57 %E = call double @ceil(double %D)
58 %F = fptrunc double %E to float
62 define float @test_shrink_libcall_round(float %C) {
63 ; CHECK-LABEL: @test_shrink_libcall_round(
64 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.round.f32(float [[C:%.*]])
65 ; CHECK-NEXT: ret float [[F]]
67 %D = fpext float %C to double
69 %E = call double @round(double %D)
70 %F = fptrunc double %E to float
74 define float @test_shrink_libcall_nearbyint(float %C) {
75 ; CHECK-LABEL: @test_shrink_libcall_nearbyint(
76 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]])
77 ; CHECK-NEXT: ret float [[F]]
79 %D = fpext float %C to double
81 %E = call double @nearbyint(double %D)
82 %F = fptrunc double %E to float
86 define float @test_shrink_libcall_trunc(float %C) {
87 ; CHECK-LABEL: @test_shrink_libcall_trunc(
88 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]])
89 ; CHECK-NEXT: ret float [[F]]
91 %D = fpext float %C to double
93 %E = call double @trunc(double %D)
94 %F = fptrunc double %E to float
98 ; This is replaced with the intrinsic, which does the right thing on
100 define float @test_shrink_libcall_fabs(float %C) {
101 ; CHECK-LABEL: @test_shrink_libcall_fabs(
102 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]])
103 ; CHECK-NEXT: ret float [[F]]
105 %D = fpext float %C to double
106 %E = call double @fabs(double %D)
107 %F = fptrunc double %E to float
111 ; Make sure fast math flags are preserved
112 define float @test_shrink_libcall_fabs_fast(float %C) {
113 ; CHECK-LABEL: @test_shrink_libcall_fabs_fast(
114 ; CHECK-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]])
115 ; CHECK-NEXT: ret float [[F]]
117 %D = fpext float %C to double
118 %E = call fast double @fabs(double %D)
119 %F = fptrunc double %E to float
123 define float @test_shrink_intrin_ceil(float %C) {
124 ; CHECK-LABEL: @test_shrink_intrin_ceil(
125 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.ceil.f32(float [[C:%.*]])
126 ; CHECK-NEXT: ret float [[TMP1]]
128 %D = fpext float %C to double
129 %E = call double @llvm.ceil.f64(double %D)
130 %F = fptrunc double %E to float
134 define float @test_shrink_intrin_fabs(float %C) {
135 ; CHECK-LABEL: @test_shrink_intrin_fabs(
136 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[C:%.*]])
137 ; CHECK-NEXT: ret float [[TMP1]]
139 %D = fpext float %C to double
140 %E = call double @llvm.fabs.f64(double %D)
141 %F = fptrunc double %E to float
145 define float @test_shrink_intrin_floor(float %C) {
146 ; CHECK-LABEL: @test_shrink_intrin_floor(
147 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.floor.f32(float [[C:%.*]])
148 ; CHECK-NEXT: ret float [[TMP1]]
150 %D = fpext float %C to double
151 %E = call double @llvm.floor.f64(double %D)
152 %F = fptrunc double %E to float
156 define float @test_shrink_intrin_nearbyint(float %C) {
157 ; CHECK-LABEL: @test_shrink_intrin_nearbyint(
158 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.nearbyint.f32(float [[C:%.*]])
159 ; CHECK-NEXT: ret float [[TMP1]]
161 %D = fpext float %C to double
162 %E = call double @llvm.nearbyint.f64(double %D)
163 %F = fptrunc double %E to float
167 define half @test_shrink_intrin_rint(half %C) {
168 ; CHECK-LABEL: @test_shrink_intrin_rint(
169 ; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.rint.f16(half [[C:%.*]])
170 ; CHECK-NEXT: ret half [[TMP1]]
172 %D = fpext half %C to float
173 %E = call float @llvm.rint.f32(float %D)
174 %F = fptrunc float %E to half
178 define float @test_shrink_intrin_round(float %C) {
179 ; CHECK-LABEL: @test_shrink_intrin_round(
180 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.round.f32(float [[C:%.*]])
181 ; CHECK-NEXT: ret float [[TMP1]]
183 %D = fpext float %C to double
184 %E = call double @llvm.round.f64(double %D)
185 %F = fptrunc double %E to float
189 define float @test_shrink_intrin_trunc(float %C) {
190 ; CHECK-LABEL: @test_shrink_intrin_trunc(
191 ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.trunc.f32(float [[C:%.*]])
192 ; CHECK-NEXT: ret float [[TMP1]]
194 %D = fpext float %C to double
195 %E = call double @llvm.trunc.f64(double %D)
196 %F = fptrunc double %E to float
200 declare void @use_v2f64(<2 x double>)
201 declare void @use_v2f32(<2 x float>)
203 define <2 x float> @test_shrink_intrin_ceil_multi_use(<2 x float> %C) {
204 ; CHECK-LABEL: @test_shrink_intrin_ceil_multi_use(
205 ; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double>
206 ; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.ceil.v2f64(<2 x double> [[D]])
207 ; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float>
208 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]])
209 ; CHECK-NEXT: ret <2 x float> [[F]]
211 %D = fpext <2 x float> %C to <2 x double>
212 %E = call <2 x double> @llvm.ceil.v2f64(<2 x double> %D)
213 %F = fptrunc <2 x double> %E to <2 x float>
214 call void @use_v2f64(<2 x double> %D)
218 define <2 x float> @test_shrink_intrin_fabs_multi_use(<2 x float> %C) {
219 ; CHECK-LABEL: @test_shrink_intrin_fabs_multi_use(
220 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[C:%.*]])
221 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x float> [[TMP1]] to <2 x double>
222 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]])
223 ; CHECK-NEXT: ret <2 x float> [[TMP1]]
225 %D = fpext <2 x float> %C to <2 x double>
226 %E = call <2 x double> @llvm.fabs.v2f64(<2 x double> %D)
227 %F = fptrunc <2 x double> %E to <2 x float>
228 call void @use_v2f64(<2 x double> %E)
232 define <2 x float> @test_shrink_intrin_floor_multi_use(<2 x float> %C) {
233 ; CHECK-LABEL: @test_shrink_intrin_floor_multi_use(
234 ; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double>
235 ; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.floor.v2f64(<2 x double> [[D]])
236 ; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float>
237 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]])
238 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]])
239 ; CHECK-NEXT: ret <2 x float> [[F]]
241 %D = fpext <2 x float> %C to <2 x double>
242 %E = call <2 x double> @llvm.floor.v2f64(<2 x double> %D)
243 %F = fptrunc <2 x double> %E to <2 x float>
244 call void @use_v2f64(<2 x double> %D)
245 call void @use_v2f64(<2 x double> %E)
249 define <2 x float> @test_shrink_intrin_nearbyint_multi_use(<2 x float> %C) {
250 ; CHECK-LABEL: @test_shrink_intrin_nearbyint_multi_use(
251 ; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double>
252 ; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> [[D]])
253 ; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float>
254 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]])
255 ; CHECK-NEXT: ret <2 x float> [[F]]
257 %D = fpext <2 x float> %C to <2 x double>
258 %E = call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %D)
259 %F = fptrunc <2 x double> %E to <2 x float>
260 call void @use_v2f64(<2 x double> %D)
264 define <2 x half> @test_shrink_intrin_rint_multi_use(<2 x half> %C) {
265 ; CHECK-LABEL: @test_shrink_intrin_rint_multi_use(
266 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.rint.v2f16(<2 x half> [[C:%.*]])
267 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x float>
268 ; CHECK-NEXT: call void @use_v2f32(<2 x float> [[E]])
269 ; CHECK-NEXT: ret <2 x half> [[TMP1]]
271 %D = fpext <2 x half> %C to <2 x float>
272 %E = call <2 x float> @llvm.rint.v2f32(<2 x float> %D)
273 %F = fptrunc <2 x float> %E to <2 x half>
274 call void @use_v2f32(<2 x float> %E)
278 define <2 x float> @test_shrink_intrin_round_multi_use(<2 x float> %C) {
279 ; CHECK-LABEL: @test_shrink_intrin_round_multi_use(
280 ; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double>
281 ; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.round.v2f64(<2 x double> [[D]])
282 ; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float>
283 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]])
284 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[E]])
285 ; CHECK-NEXT: ret <2 x float> [[F]]
287 %D = fpext <2 x float> %C to <2 x double>
288 %E = call <2 x double> @llvm.round.v2f64(<2 x double> %D)
289 %F = fptrunc <2 x double> %E to <2 x float>
290 call void @use_v2f64(<2 x double> %D)
291 call void @use_v2f64(<2 x double> %E)
295 define <2 x float> @test_shrink_intrin_trunc_multi_use(<2 x float> %C) {
296 ; CHECK-LABEL: @test_shrink_intrin_trunc_multi_use(
297 ; CHECK-NEXT: [[D:%.*]] = fpext <2 x float> [[C:%.*]] to <2 x double>
298 ; CHECK-NEXT: [[E:%.*]] = call <2 x double> @llvm.trunc.v2f64(<2 x double> [[D]])
299 ; CHECK-NEXT: [[F:%.*]] = fptrunc <2 x double> [[E]] to <2 x float>
300 ; CHECK-NEXT: call void @use_v2f64(<2 x double> [[D]])
301 ; CHECK-NEXT: ret <2 x float> [[F]]
303 %D = fpext <2 x float> %C to <2 x double>
304 %E = call <2 x double> @llvm.trunc.v2f64(<2 x double> %D)
305 %F = fptrunc <2 x double> %E to <2 x float>
306 call void @use_v2f64(<2 x double> %D)
310 ; Make sure fast math flags are preserved
311 define float @test_shrink_intrin_fabs_fast(float %C) {
312 ; CHECK-LABEL: @test_shrink_intrin_fabs_fast(
313 ; CHECK-NEXT: [[TMP1:%.*]] = call fast float @llvm.fabs.f32(float [[C:%.*]])
314 ; CHECK-NEXT: ret float [[TMP1]]
316 %D = fpext float %C to double
317 %E = call fast double @llvm.fabs.f64(double %D)
318 %F = fptrunc double %E to float
322 define float @test_no_shrink_intrin_floor(double %D) {
323 ; CHECK-LABEL: @test_no_shrink_intrin_floor(
324 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]])
325 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
326 ; CHECK-NEXT: ret float [[F]]
328 %E = call double @llvm.floor.f64(double %D)
329 %F = fptrunc double %E to float
333 define float @test_no_shrink_intrin_ceil(double %D) {
334 ; CHECK-LABEL: @test_no_shrink_intrin_ceil(
335 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]])
336 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
337 ; CHECK-NEXT: ret float [[F]]
339 %E = call double @llvm.ceil.f64(double %D)
340 %F = fptrunc double %E to float
344 define float @test_no_shrink_intrin_round(double %D) {
345 ; CHECK-LABEL: @test_no_shrink_intrin_round(
346 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]])
347 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
348 ; CHECK-NEXT: ret float [[F]]
350 %E = call double @llvm.round.f64(double %D)
351 %F = fptrunc double %E to float
355 define float @test_no_shrink_intrin_nearbyint(double %D) {
356 ; CHECK-LABEL: @test_no_shrink_intrin_nearbyint(
357 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]])
358 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
359 ; CHECK-NEXT: ret float [[F]]
361 %E = call double @llvm.nearbyint.f64(double %D)
362 %F = fptrunc double %E to float
366 define float @test_no_shrink_intrin_trunc(double %D) {
367 ; CHECK-LABEL: @test_no_shrink_intrin_trunc(
368 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]])
369 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
370 ; CHECK-NEXT: ret float [[F]]
372 %E = call double @llvm.trunc.f64(double %D)
373 %F = fptrunc double %E to float
377 define float @test_shrink_intrin_fabs_double_src(double %D) {
378 ; CHECK-LABEL: @test_shrink_intrin_fabs_double_src(
379 ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float
380 ; CHECK-NEXT: [[F:%.*]] = call float @llvm.fabs.f32(float [[TMP1]])
381 ; CHECK-NEXT: ret float [[F]]
383 %E = call double @llvm.fabs.f64(double %D)
384 %F = fptrunc double %E to float
388 ; Make sure fast math flags are preserved
389 define float @test_shrink_intrin_fabs_fast_double_src(double %D) {
390 ; CHECK-LABEL: @test_shrink_intrin_fabs_fast_double_src(
391 ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to float
392 ; CHECK-NEXT: [[F:%.*]] = call fast float @llvm.fabs.f32(float [[TMP1]])
393 ; CHECK-NEXT: ret float [[F]]
395 %E = call fast double @llvm.fabs.f64(double %D)
396 %F = fptrunc double %E to float
400 define float @test_shrink_float_convertible_constant_intrin_floor() {
401 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_floor(
402 ; CHECK-NEXT: ret float 2.000000e+00
404 %E = call double @llvm.floor.f64(double 2.1)
405 %F = fptrunc double %E to float
409 define float @test_shrink_float_convertible_constant_intrin_ceil() {
410 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_ceil(
411 ; CHECK-NEXT: ret float 3.000000e+00
413 %E = call double @llvm.ceil.f64(double 2.1)
414 %F = fptrunc double %E to float
418 define float @test_shrink_float_convertible_constant_intrin_round() {
419 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_round(
420 ; CHECK-NEXT: ret float 2.000000e+00
422 %E = call double @llvm.round.f64(double 2.1)
423 %F = fptrunc double %E to float
427 define float @test_shrink_float_convertible_constant_intrin_nearbyint() {
428 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_nearbyint(
429 ; CHECK-NEXT: ret float 2.000000e+00
431 %E = call double @llvm.nearbyint.f64(double 2.1)
432 %F = fptrunc double %E to float
436 define float @test_shrink_float_convertible_constant_intrin_trunc() {
437 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_trunc(
438 ; CHECK-NEXT: ret float 2.000000e+00
440 %E = call double @llvm.trunc.f64(double 2.1)
441 %F = fptrunc double %E to float
445 define float @test_shrink_float_convertible_constant_intrin_fabs() {
446 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_fabs(
447 ; CHECK-NEXT: ret float 0x4000CCCCC0000000
449 %E = call double @llvm.fabs.f64(double 2.1)
450 %F = fptrunc double %E to float
454 ; Make sure fast math flags are preserved
455 define float @test_shrink_float_convertible_constant_intrin_fabs_fast() {
456 ; CHECK-LABEL: @test_shrink_float_convertible_constant_intrin_fabs_fast(
457 ; CHECK-NEXT: ret float 0x4000CCCCC0000000
459 %E = call fast double @llvm.fabs.f64(double 2.1)
460 %F = fptrunc double %E to float
464 define half @test_no_shrink_mismatched_type_intrin_floor(double %D) {
465 ; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_floor(
466 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D:%.*]])
467 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half
468 ; CHECK-NEXT: ret half [[F]]
470 %E = call double @llvm.floor.f64(double %D)
471 %F = fptrunc double %E to half
475 define half @test_no_shrink_mismatched_type_intrin_ceil(double %D) {
476 ; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_ceil(
477 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.ceil.f64(double [[D:%.*]])
478 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half
479 ; CHECK-NEXT: ret half [[F]]
481 %E = call double @llvm.ceil.f64(double %D)
482 %F = fptrunc double %E to half
486 define half @test_no_shrink_mismatched_type_intrin_round(double %D) {
487 ; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_round(
488 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.round.f64(double [[D:%.*]])
489 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half
490 ; CHECK-NEXT: ret half [[F]]
492 %E = call double @llvm.round.f64(double %D)
493 %F = fptrunc double %E to half
497 define half @test_no_shrink_mismatched_type_intrin_nearbyint(double %D) {
498 ; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_nearbyint(
499 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.nearbyint.f64(double [[D:%.*]])
500 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half
501 ; CHECK-NEXT: ret half [[F]]
503 %E = call double @llvm.nearbyint.f64(double %D)
504 %F = fptrunc double %E to half
508 define half @test_no_shrink_mismatched_type_intrin_trunc(double %D) {
509 ; CHECK-LABEL: @test_no_shrink_mismatched_type_intrin_trunc(
510 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.trunc.f64(double [[D:%.*]])
511 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to half
512 ; CHECK-NEXT: ret half [[F]]
514 %E = call double @llvm.trunc.f64(double %D)
515 %F = fptrunc double %E to half
519 define half @test_shrink_mismatched_type_intrin_fabs_double_src(double %D) {
520 ; CHECK-LABEL: @test_shrink_mismatched_type_intrin_fabs_double_src(
521 ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half
522 ; CHECK-NEXT: [[F:%.*]] = call half @llvm.fabs.f16(half [[TMP1]])
523 ; CHECK-NEXT: ret half [[F]]
525 %E = call double @llvm.fabs.f64(double %D)
526 %F = fptrunc double %E to half
530 ; Make sure fast math flags are preserved
531 define half @test_mismatched_type_intrin_fabs_fast_double_src(double %D) {
532 ; CHECK-LABEL: @test_mismatched_type_intrin_fabs_fast_double_src(
533 ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[D:%.*]] to half
534 ; CHECK-NEXT: [[F:%.*]] = call fast half @llvm.fabs.f16(half [[TMP1]])
535 ; CHECK-NEXT: ret half [[F]]
537 %E = call fast double @llvm.fabs.f64(double %D)
538 %F = fptrunc double %E to half
542 define <2 x double> @test_shrink_intrin_floor_fp16_vec(<2 x half> %C) {
543 ; CHECK-LABEL: @test_shrink_intrin_floor_fp16_vec(
544 ; CHECK-NEXT: [[TMP1:%.*]] = call arcp <2 x half> @llvm.floor.v2f16(<2 x half> [[C:%.*]])
545 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double>
546 ; CHECK-NEXT: ret <2 x double> [[E]]
548 %D = fpext <2 x half> %C to <2 x double>
549 %E = call arcp <2 x double> @llvm.floor.v2f64(<2 x double> %D)
553 define float @test_shrink_intrin_ceil_fp16_src(half %C) {
554 ; CHECK-LABEL: @test_shrink_intrin_ceil_fp16_src(
555 ; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.ceil.f16(half [[C:%.*]])
556 ; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float
557 ; CHECK-NEXT: ret float [[F]]
559 %D = fpext half %C to double
560 %E = call double @llvm.ceil.f64(double %D)
561 %F = fptrunc double %E to float
565 define <2 x double> @test_shrink_intrin_round_fp16_vec(<2 x half> %C) {
566 ; CHECK-LABEL: @test_shrink_intrin_round_fp16_vec(
567 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.round.v2f16(<2 x half> [[C:%.*]])
568 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double>
569 ; CHECK-NEXT: ret <2 x double> [[E]]
571 %D = fpext <2 x half> %C to <2 x double>
572 %E = call <2 x double> @llvm.round.v2f64(<2 x double> %D)
576 define float @test_shrink_intrin_nearbyint_fp16_src(half %C) {
577 ; CHECK-LABEL: @test_shrink_intrin_nearbyint_fp16_src(
578 ; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.nearbyint.f16(half [[C:%.*]])
579 ; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float
580 ; CHECK-NEXT: ret float [[F]]
582 %D = fpext half %C to double
583 %E = call double @llvm.nearbyint.f64(double %D)
584 %F = fptrunc double %E to float
588 define <2 x double> @test_shrink_intrin_trunc_fp16_src(<2 x half> %C) {
589 ; CHECK-LABEL: @test_shrink_intrin_trunc_fp16_src(
590 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x half> @llvm.trunc.v2f16(<2 x half> [[C:%.*]])
591 ; CHECK-NEXT: [[E:%.*]] = fpext <2 x half> [[TMP1]] to <2 x double>
592 ; CHECK-NEXT: ret <2 x double> [[E]]
594 %D = fpext <2 x half> %C to <2 x double>
595 %E = call <2 x double> @llvm.trunc.v2f64(<2 x double> %D)
599 define float @test_shrink_intrin_fabs_fp16_src(half %C) {
600 ; CHECK-LABEL: @test_shrink_intrin_fabs_fp16_src(
601 ; CHECK-NEXT: [[TMP1:%.*]] = call half @llvm.fabs.f16(half [[C:%.*]])
602 ; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float
603 ; CHECK-NEXT: ret float [[F]]
605 %D = fpext half %C to double
606 %E = call double @llvm.fabs.f64(double %D)
607 %F = fptrunc double %E to float
611 ; Make sure fast math flags are preserved
612 define float @test_shrink_intrin_fabs_fast_fp16_src(half %C) {
613 ; CHECK-LABEL: @test_shrink_intrin_fabs_fast_fp16_src(
614 ; CHECK-NEXT: [[TMP1:%.*]] = call fast half @llvm.fabs.f16(half [[C:%.*]])
615 ; CHECK-NEXT: [[F:%.*]] = fpext half [[TMP1]] to float
616 ; CHECK-NEXT: ret float [[F]]
618 %D = fpext half %C to double
619 %E = call fast double @llvm.fabs.f64(double %D)
620 %F = fptrunc double %E to float
624 define float @test_no_shrink_intrin_floor_multi_use_fpext(half %C) {
625 ; CHECK-LABEL: @test_no_shrink_intrin_floor_multi_use_fpext(
626 ; CHECK-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double
627 ; CHECK-NEXT: store volatile double [[D]], double* undef, align 8
628 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.floor.f64(double [[D]])
629 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
630 ; CHECK-NEXT: ret float [[F]]
632 %D = fpext half %C to double
633 store volatile double %D, double* undef
634 %E = call double @llvm.floor.f64(double %D)
635 %F = fptrunc double %E to float
639 define float @test_no_shrink_intrin_fabs_multi_use_fpext(half %C) {
640 ; CHECK-LABEL: @test_no_shrink_intrin_fabs_multi_use_fpext(
641 ; CHECK-NEXT: [[D:%.*]] = fpext half [[C:%.*]] to double
642 ; CHECK-NEXT: store volatile double [[D]], double* undef, align 8
643 ; CHECK-NEXT: [[E:%.*]] = call double @llvm.fabs.f64(double [[D]])
644 ; CHECK-NEXT: [[F:%.*]] = fptrunc double [[E]] to float
645 ; CHECK-NEXT: ret float [[F]]
647 %D = fpext half %C to double
648 store volatile double %D, double* undef
649 %E = call double @llvm.fabs.f64(double %D)
650 %F = fptrunc double %E to float
654 ; DBG-VALID: CheckModuleDebugify: PASS