[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / fptrunc.ll
blobc04c4b5c66c4801aaced7c791667078bd680e58b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define float @fadd_fpext_op0(float %x, double %y) {
5 ; CHECK-LABEL: @fadd_fpext_op0(
6 ; CHECK-NEXT:    [[EXT:%.*]] = fpext float [[X:%.*]] to double
7 ; CHECK-NEXT:    [[BO:%.*]] = fadd reassoc double [[EXT]], [[Y:%.*]]
8 ; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[BO]] to float
9 ; CHECK-NEXT:    ret float [[R]]
11   %ext = fpext float %x to double
12   %bo = fadd reassoc double %ext, %y
13   %r = fptrunc double %bo to float
14   ret float %r
17 define half @fsub_fpext_op1(half %x, double %y) {
18 ; CHECK-LABEL: @fsub_fpext_op1(
19 ; CHECK-NEXT:    [[EXT:%.*]] = fpext half [[X:%.*]] to double
20 ; CHECK-NEXT:    [[BO:%.*]] = fsub reassoc double [[Y:%.*]], [[EXT]]
21 ; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[BO]] to half
22 ; CHECK-NEXT:    ret half [[R]]
24   %ext = fpext half %x to double
25   %bo = fsub reassoc double %y, %ext
26   %r = fptrunc double %bo to half
27   ret half %r
30 define <2 x float> @fdiv_constant_op0(<2 x double> %x) {
31 ; CHECK-LABEL: @fdiv_constant_op0(
32 ; CHECK-NEXT:    [[BO:%.*]] = fdiv reassoc <2 x double> <double 4.210000e+01, double -1.000000e-01>, [[X:%.*]]
33 ; CHECK-NEXT:    [[R:%.*]] = fptrunc <2 x double> [[BO]] to <2 x float>
34 ; CHECK-NEXT:    ret <2 x float> [[R]]
36   %bo = fdiv reassoc <2 x double> <double 42.1, double -0.1>, %x
37   %r = fptrunc <2 x double> %bo to <2 x float>
38   ret <2 x float> %r
41 define <2 x half> @fmul_constant_op1(<2 x float> %x) {
42 ; CHECK-LABEL: @fmul_constant_op1(
43 ; CHECK-NEXT:    [[BO:%.*]] = fmul reassoc <2 x float> [[X:%.*]], <float 0x47EFFFFFE0000000, float 5.000000e-01>
44 ; CHECK-NEXT:    [[R:%.*]] = fptrunc <2 x float> [[BO]] to <2 x half>
45 ; CHECK-NEXT:    ret <2 x half> [[R]]
47   %bo = fmul reassoc <2 x float> %x, <float 0x47efffffe0000000, float 0.5>
48   %r = fptrunc <2 x float> %bo to <2 x half>
49   ret <2 x half> %r
52 define float @fptrunc_select_true_val(float %x, double %y, i1 %cond) {
53 ; CHECK-LABEL: @fptrunc_select_true_val(
54 ; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc double [[Y:%.*]] to float
55 ; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select fast i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]]
56 ; CHECK-NEXT:    ret float [[NARROW_SEL]]
58   %e = fpext float %x to double
59   %sel = select fast i1 %cond, double %y, double %e
60   %r = fptrunc double %sel to float
61   ret float %r
64 define <2 x float> @fptrunc_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) {
65 ; CHECK-LABEL: @fptrunc_select_false_val(
66 ; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc <2 x double> [[Y:%.*]] to <2 x float>
67 ; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select nnan <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]]
68 ; CHECK-NEXT:    ret <2 x float> [[NARROW_SEL]]
70   %e = fpext <2 x float> %x to <2 x double>
71   %sel = select nnan <2 x i1> %cond, <2 x double> %e, <2 x double> %y
72   %r = fptrunc <2 x double> %sel to <2 x float>
73   ret <2 x float> %r
76 declare void @use(float)
78 define half @fptrunc_select_true_val_extra_use(half %x, float %y, i1 %cond) {
79 ; CHECK-LABEL: @fptrunc_select_true_val_extra_use(
80 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float
81 ; CHECK-NEXT:    call void @use(float [[E]])
82 ; CHECK-NEXT:    [[TMP1:%.*]] = fptrunc float [[Y:%.*]] to half
83 ; CHECK-NEXT:    [[NARROW_SEL:%.*]] = select ninf i1 [[COND:%.*]], half [[TMP1]], half [[X]]
84 ; CHECK-NEXT:    ret half [[NARROW_SEL]]
86   %e = fpext half %x to float
87   call void @use(float %e)
88   %sel = select ninf i1 %cond, float %y, float %e
89   %r = fptrunc float %sel to half
90   ret half %r
93 ; Negative test - this would require an extra instruction.
95 define half @fptrunc_select_true_val_extra_use_2(half %x, float %y, i1 %cond) {
96 ; CHECK-LABEL: @fptrunc_select_true_val_extra_use_2(
97 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to float
98 ; CHECK-NEXT:    [[SEL:%.*]] = select ninf i1 [[COND:%.*]], float [[Y:%.*]], float [[E]]
99 ; CHECK-NEXT:    call void @use(float [[SEL]])
100 ; CHECK-NEXT:    [[R:%.*]] = fptrunc float [[SEL]] to half
101 ; CHECK-NEXT:    ret half [[R]]
103   %e = fpext half %x to float
104   %sel = select ninf i1 %cond, float %y, float %e
105   call void @use(float %sel)
106   %r = fptrunc float %sel to half
107   ret half %r
110 ; Negative test - the extend must be from the same source type as the result of the trunc.
112 define float @fptrunc_select_true_val_type_mismatch(half %x, double %y, i1 %cond) {
113 ; CHECK-LABEL: @fptrunc_select_true_val_type_mismatch(
114 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double
115 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double [[E]]
116 ; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[SEL]] to float
117 ; CHECK-NEXT:    ret float [[R]]
119   %e = fpext half %x to double
120   %sel = select i1 %cond, double %y, double %e
121   %r = fptrunc double %sel to float
122   ret float %r
125 ; Negative test - but given enough FMF, should this be folded?
127 define float @fptrunc_select_true_val_type_mismatch_fast(half %x, double %y, i1 %cond) {
128 ; CHECK-LABEL: @fptrunc_select_true_val_type_mismatch_fast(
129 ; CHECK-NEXT:    [[E:%.*]] = fpext half [[X:%.*]] to double
130 ; CHECK-NEXT:    [[SEL:%.*]] = select fast i1 [[COND:%.*]], double [[Y:%.*]], double [[E]]
131 ; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[SEL]] to float
132 ; CHECK-NEXT:    ret float [[R]]
134   %e = fpext half %x to double
135   %sel = select fast i1 %cond, double %y, double %e
136   %r = fptrunc double %sel to float
137   ret float %r
140 ; Convert from integer is exact, so convert directly to float.
142 define <2 x float> @ItoFtoF_s54_f64_f32(<2 x i54> %i) {
143 ; CHECK-LABEL: @ItoFtoF_s54_f64_f32(
144 ; CHECK-NEXT:    [[R:%.*]] = sitofp <2 x i54> [[I:%.*]] to <2 x float>
145 ; CHECK-NEXT:    ret <2 x float> [[R]]
147   %x = sitofp <2 x i54> %i to <2 x double>
148   %r = fptrunc <2 x double> %x to <2 x float>
149   ret <2 x float> %r
152 ; Convert from integer is exact, so convert directly to half.
153 ; Extra use is ok.
155 define half @ItoFtoF_u24_f32_f16(i24 %i) {
156 ; CHECK-LABEL: @ItoFtoF_u24_f32_f16(
157 ; CHECK-NEXT:    [[X:%.*]] = uitofp i24 [[I:%.*]] to float
158 ; CHECK-NEXT:    call void @use(float [[X]])
159 ; CHECK-NEXT:    [[R:%.*]] = uitofp i24 [[I]] to half
160 ; CHECK-NEXT:    ret half [[R]]
162   %x = uitofp i24 %i to float
163   call void @use(float %x)
164   %r = fptrunc float %x to half
165   ret half %r
168 ; Negative test - intermediate rounding in float type.
170 define float @ItoFtoF_s55_f64_f32(i55 %i) {
171 ; CHECK-LABEL: @ItoFtoF_s55_f64_f32(
172 ; CHECK-NEXT:    [[X:%.*]] = sitofp i55 [[I:%.*]] to double
173 ; CHECK-NEXT:    [[R:%.*]] = fptrunc double [[X]] to float
174 ; CHECK-NEXT:    ret float [[R]]
176   %x = sitofp i55 %i to double
177   %r = fptrunc double %x to float
178   ret float %r
181 ; Negative test - intermediate rounding in float type.
183 define half @ItoFtoF_u25_f32_f16(i25 %i) {
184 ; CHECK-LABEL: @ItoFtoF_u25_f32_f16(
185 ; CHECK-NEXT:    [[X:%.*]] = uitofp i25 [[I:%.*]] to float
186 ; CHECK-NEXT:    [[R:%.*]] = fptrunc float [[X]] to half
187 ; CHECK-NEXT:    ret half [[R]]
189   %x = uitofp i25 %i to float
190   %r = fptrunc float %x to half
191   ret half %r