[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / double-float-shrink-2.ll
blob76e497bd68fc7949e4b57336b6d2e64dc3c1195b
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
44   ; --> floorf
45   %E = call double @floor(double %D)
46   %F = fptrunc double %E to float
47   ret float %F
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
56   ; --> ceilf
57   %E = call double @ceil(double %D)
58   %F = fptrunc double %E to float
59   ret float %F
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
68   ; --> roundf
69   %E = call double @round(double %D)
70   %F = fptrunc double %E to float
71   ret float %F
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
80   ; --> nearbyintf
81   %E = call double @nearbyint(double %D)
82   %F = fptrunc double %E to float
83   ret float %F
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
92   ; --> truncf
93   %E = call double @trunc(double %D)
94   %F = fptrunc double %E to float
95   ret float %F
98 ; This is replaced with the intrinsic, which does the right thing on
99 ; CHECK platforms.
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
108   ret float %F
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
120   ret float %F
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
131   ret float %F
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
142   ret float %F
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
153   ret float %F
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
164   ret float %F
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
175   ret half %F
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
186   ret float %F
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
197   ret float %F
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)
215   ret <2 x float> %F
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)
229   ret <2 x float> %F
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)
246   ret <2 x float> %F
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)
261   ret <2 x float> %F
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)
275   ret <2 x half> %F
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)
292   ret <2 x float> %F
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)
307   ret <2 x float> %F
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
319   ret float %F
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
330   ret float %F
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
341   ret float %F
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
352   ret float %F
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
363   ret float %F
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
374   ret float %F
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
385   ret float %F
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
397   ret float %F
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
406   ret float %F
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
415   ret float %F
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
424   ret float %F
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
433   ret float %F
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
442   ret float %F
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
451   ret float %F
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
461   ret float %F
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
472   ret half %F
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
483   ret half %F
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
494   ret half %F
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
505   ret half %F
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
516   ret half %F
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
527   ret half %F
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
539   ret half %F
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)
550   ret <2 x double> %E
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
562   ret float %F
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)
573   ret <2 x double> %E
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
585   ret float %F
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)
596   ret <2 x double> %E
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
608   ret float %F
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
621   ret float %F
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
636   ret float %F
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
651   ret float %F
654 ; DBG-VALID: CheckModuleDebugify: PASS