xref: /llvm-project/llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll (revision b1b7fb6f20b056a7eb5731a98485f9d541c7aabe)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s
3
4; Tests if an integer type can cover the entire range of an input
5; FP value. If so, we can remove an intermediate cast to a smaller
6; int type (remove a truncate).
7
8define i16 @half_fptoui_i17_i16(half %x) {
9; CHECK-LABEL: @half_fptoui_i17_i16(
10; CHECK-NEXT:    [[I:%.*]] = fptoui half [[X:%.*]] to i16
11; CHECK-NEXT:    ret i16 [[I]]
12;
13  %i = fptoui half %x to i17
14  %r = trunc i17 %i to i16
15  ret i16 %r
16}
17
18; Negative test - not enough bits to hold max half value (65504).
19
20define i15 @half_fptoui_i17_i15(half %x) {
21; CHECK-LABEL: @half_fptoui_i17_i15(
22; CHECK-NEXT:    [[I:%.*]] = fptoui half [[X:%.*]] to i17
23; CHECK-NEXT:    [[R:%.*]] = trunc i17 [[I]] to i15
24; CHECK-NEXT:    ret i15 [[R]]
25;
26  %i = fptoui half %x to i17
27  %r = trunc i17 %i to i15
28  ret i15 %r
29}
30
31; Wider intermediate type is ok.
32
33define i16 @half_fptoui_i32_i16(half %x) {
34; CHECK-LABEL: @half_fptoui_i32_i16(
35; CHECK-NEXT:    [[I:%.*]] = fptoui half [[X:%.*]] to i16
36; CHECK-NEXT:    ret i16 [[I]]
37;
38  %i = fptoui half %x to i32
39  %r = trunc i32 %i to i16
40  ret i16 %r
41}
42
43; Wider final type is ok.
44; TODO: Handle non-simple result type.
45
46define i17 @half_fptoui_i32_i17(half %x) {
47; CHECK-LABEL: @half_fptoui_i32_i17(
48; CHECK-NEXT:    [[I:%.*]] = fptoui half [[X:%.*]] to i32
49; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[I]] to i17
50; CHECK-NEXT:    ret i17 [[R]]
51;
52  %i = fptoui half %x to i32
53  %r = trunc i32 %i to i17
54  ret i17 %r
55}
56
57; Vectors work too.
58
59define <4 x i16> @half_fptoui_4xi32_4xi16(<4 x half> %x) {
60; CHECK-LABEL: @half_fptoui_4xi32_4xi16(
61; CHECK-NEXT:    [[I:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i16>
62; CHECK-NEXT:    ret <4 x i16> [[I]]
63;
64  %i = fptoui <4 x half> %x to <4 x i32>
65  %r = trunc <4 x i32> %i to <4 x i16>
66  ret <4 x i16> %r
67}
68
69define i128 @bfloat_fptoui_i129_i128(bfloat %x) {
70; CHECK-LABEL: @bfloat_fptoui_i129_i128(
71; CHECK-NEXT:    [[I:%.*]] = fptoui bfloat [[X:%.*]] to i128
72; CHECK-NEXT:    ret i128 [[I]]
73;
74  %i = fptoui bfloat %x to i129
75  %r = trunc i129 %i to i128
76  ret i128 %r
77}
78
79; Negative test - not enough bits to hold max bfloat value (2**127 * (2 − 2**−7))
80
81define i127 @bfloat_fptoui_i128_i127(bfloat %x) {
82; CHECK-LABEL: @bfloat_fptoui_i128_i127(
83; CHECK-NEXT:    [[I:%.*]] = fptoui bfloat [[X:%.*]] to i128
84; CHECK-NEXT:    [[R:%.*]] = trunc i128 [[I]] to i127
85; CHECK-NEXT:    ret i127 [[R]]
86;
87  %i = fptoui bfloat %x to i128
88  %r = trunc i128 %i to i127
89  ret i127 %r
90}
91
92define i128 @float_fptoui_i129_i128(float %x) {
93; CHECK-LABEL: @float_fptoui_i129_i128(
94; CHECK-NEXT:    [[I:%.*]] = fptoui float [[X:%.*]] to i128
95; CHECK-NEXT:    ret i128 [[I]]
96;
97  %i = fptoui float %x to i129
98  %r = trunc i129 %i to i128
99  ret i128 %r
100}
101
102; TODO: We could transform with multiple users.
103declare void @use(i129)
104define i128 @float_fptoui_i129_i128_use(float %x) {
105; CHECK-LABEL: @float_fptoui_i129_i128_use(
106; CHECK-NEXT:    [[I:%.*]] = fptoui float [[X:%.*]] to i129
107; CHECK-NEXT:    call void @use(i129 [[I]])
108; CHECK-NEXT:    [[R:%.*]] = trunc i129 [[I]] to i128
109; CHECK-NEXT:    ret i128 [[R]]
110;
111  %i = fptoui float %x to i129
112  call void @use(i129 %i)
113  %r = trunc i129 %i to i128
114  ret i128 %r
115}
116
117; Negative test - not enough bits to hold max float value (2**127 * (2 − 2**−23))
118
119define i127 @float_fptoui_i128_i127(float %x) {
120; CHECK-LABEL: @float_fptoui_i128_i127(
121; CHECK-NEXT:    [[I:%.*]] = fptoui float [[X:%.*]] to i128
122; CHECK-NEXT:    [[R:%.*]] = trunc i128 [[I]] to i127
123; CHECK-NEXT:    ret i127 [[R]]
124;
125  %i = fptoui float %x to i128
126  %r = trunc i128 %i to i127
127  ret i127 %r
128}
129
130define i1024 @double_fptoui_i1025_i1024(double %x) {
131; CHECK-LABEL: @double_fptoui_i1025_i1024(
132; CHECK-NEXT:    [[I:%.*]] = fptoui double [[X:%.*]] to i1024
133; CHECK-NEXT:    ret i1024 [[I]]
134;
135  %i = fptoui double %x to i1025
136  %r = trunc i1025 %i to i1024
137  ret i1024 %r
138}
139
140; Negative test - not enough bits to hold max double value (2**1023 * (2 − 2**−52))
141
142define i1023 @double_fptoui_i1024_i1023(double %x) {
143; CHECK-LABEL: @double_fptoui_i1024_i1023(
144; CHECK-NEXT:    [[I:%.*]] = fptoui double [[X:%.*]] to i1024
145; CHECK-NEXT:    [[R:%.*]] = trunc i1024 [[I]] to i1023
146; CHECK-NEXT:    ret i1023 [[R]]
147;
148  %i = fptoui double %x to i1024
149  %r = trunc i1024 %i to i1023
150  ret i1023 %r
151}
152
153; Negative test - not enough bits to hold min half value (-65504).
154
155define i16 @half_fptosi_i17_i16(half %x) {
156; CHECK-LABEL: @half_fptosi_i17_i16(
157; CHECK-NEXT:    [[I:%.*]] = fptosi half [[X:%.*]] to i17
158; CHECK-NEXT:    [[R:%.*]] = trunc i17 [[I]] to i16
159; CHECK-NEXT:    ret i16 [[R]]
160;
161  %i = fptosi half %x to i17
162  %r = trunc i17 %i to i16
163  ret i16 %r
164}
165
166define i17 @half_fptosi_i18_i17(half %x) {
167; CHECK-LABEL: @half_fptosi_i18_i17(
168; CHECK-NEXT:    [[I:%.*]] = fptosi half [[X:%.*]] to i17
169; CHECK-NEXT:    ret i17 [[I]]
170;
171  %i = fptosi half %x to i18
172  %r = trunc i18 %i to i17
173  ret i17 %r
174}
175
176; Wider intermediate type is ok.
177; TODO: Handle non-simple result type.
178
179define i17 @half_fptosi_i32_i17(half %x) {
180; CHECK-LABEL: @half_fptosi_i32_i17(
181; CHECK-NEXT:    [[I:%.*]] = fptosi half [[X:%.*]] to i32
182; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[I]] to i17
183; CHECK-NEXT:    ret i17 [[R]]
184;
185  %i = fptosi half %x to i32
186  %r = trunc i32 %i to i17
187  ret i17 %r
188}
189
190; Wider final type is ok.
191; TODO: Handle non-simple result type.
192
193define i18 @half_fptosi_i32_i18(half %x) {
194; CHECK-LABEL: @half_fptosi_i32_i18(
195; CHECK-NEXT:    [[I:%.*]] = fptosi half [[X:%.*]] to i32
196; CHECK-NEXT:    [[R:%.*]] = trunc i32 [[I]] to i18
197; CHECK-NEXT:    ret i18 [[R]]
198;
199  %i = fptosi half %x to i32
200  %r = trunc i32 %i to i18
201  ret i18 %r
202}
203
204; Vectors work too.
205
206define <4 x i17> @half_fptosi_4xi32_4xi17(<4 x half> %x) {
207; CHECK-LABEL: @half_fptosi_4xi32_4xi17(
208; CHECK-NEXT:    [[I:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i17>
209; CHECK-NEXT:    ret <4 x i17> [[I]]
210;
211  %i = fptosi <4 x half> %x to <4 x i32>
212  %r = trunc <4 x i32> %i to <4 x i17>
213  ret <4 x i17> %r
214}
215
216; Negative test - not enough bits to hold min float value.
217
218define i128 @bfloat_fptosi_i129_i128(bfloat %x) {
219; CHECK-LABEL: @bfloat_fptosi_i129_i128(
220; CHECK-NEXT:    [[I:%.*]] = fptosi bfloat [[X:%.*]] to i129
221; CHECK-NEXT:    [[R:%.*]] = trunc i129 [[I]] to i128
222; CHECK-NEXT:    ret i128 [[R]]
223;
224  %i = fptosi bfloat %x to i129
225  %r = trunc i129 %i to i128
226  ret i128 %r
227}
228
229define i129 @bfloat_fptosi_i130_i129(bfloat %x) {
230; CHECK-LABEL: @bfloat_fptosi_i130_i129(
231; CHECK-NEXT:    [[I:%.*]] = fptosi bfloat [[X:%.*]] to i129
232; CHECK-NEXT:    ret i129 [[I]]
233;
234  %i = fptosi bfloat %x to i130
235  %r = trunc i130 %i to i129
236  ret i129 %r
237}
238
239define i129 @float_fptosi_i130_i129(float %x) {
240; CHECK-LABEL: @float_fptosi_i130_i129(
241; CHECK-NEXT:    [[I:%.*]] = fptosi float [[X:%.*]] to i129
242; CHECK-NEXT:    ret i129 [[I]]
243;
244  %i = fptosi float %x to i130
245  %r = trunc i130 %i to i129
246  ret i129 %r
247}
248
249; Negative test - not enough bits to hold min float value.
250
251define i128 @float_fptosi_i129_i128(float %x) {
252; CHECK-LABEL: @float_fptosi_i129_i128(
253; CHECK-NEXT:    [[I:%.*]] = fptosi float [[X:%.*]] to i129
254; CHECK-NEXT:    [[R:%.*]] = trunc i129 [[I]] to i128
255; CHECK-NEXT:    ret i128 [[R]]
256;
257  %i = fptosi float %x to i129
258  %r = trunc i129 %i to i128
259  ret i128 %r
260}
261
262define i1025 @double_fptosi_i1026_i1025(double %x) {
263; CHECK-LABEL: @double_fptosi_i1026_i1025(
264; CHECK-NEXT:    [[I:%.*]] = fptosi double [[X:%.*]] to i1025
265; CHECK-NEXT:    ret i1025 [[I]]
266;
267  %i = fptosi double %x to i1026
268  %r = trunc i1026 %i to i1025
269  ret i1025 %r
270}
271
272; Negative test - not enough bits to hold min double value.
273
274define i1024 @double_fptosi_i1025_i1024(double %x) {
275; CHECK-LABEL: @double_fptosi_i1025_i1024(
276; CHECK-NEXT:    [[I:%.*]] = fptosi double [[X:%.*]] to i1025
277; CHECK-NEXT:    [[R:%.*]] = trunc i1025 [[I]] to i1024
278; CHECK-NEXT:    ret i1024 [[R]]
279;
280  %i = fptosi double %x to i1025
281  %r = trunc i1025 %i to i1024
282  ret i1024 %r
283}
284