1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S -o - %s | FileCheck %s
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).
8 define 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]]
13 %i = fptoui half %x to i17
14 %r = trunc i17 %i to i16
18 ; Negative test - not enough bits to hold max half value (65504).
20 define 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]]
26 %i = fptoui half %x to i17
27 %r = trunc i17 %i to i15
31 ; Wider intermediate type is ok.
33 define 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]]
38 %i = fptoui half %x to i32
39 %r = trunc i32 %i to i16
43 ; Wider final type is ok.
44 ; TODO: Handle non-simple result type.
46 define 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]]
52 %i = fptoui half %x to i32
53 %r = trunc i32 %i to i17
59 define <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]]
64 %i = fptoui <4 x half> %x to <4 x i32>
65 %r = trunc <4 x i32> %i to <4 x i16>
69 define 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]]
74 %i = fptoui bfloat %x to i129
75 %r = trunc i129 %i to i128
79 ; Negative test - not enough bits to hold max bfloat value (2**127 * (2 − 2**−7))
81 define 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]]
87 %i = fptoui bfloat %x to i128
88 %r = trunc i128 %i to i127
92 define 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]]
97 %i = fptoui float %x to i129
98 %r = trunc i129 %i to i128
102 ; TODO: We could transform with multiple users.
103 declare void @use(i129)
104 define 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]]
111 %i = fptoui float %x to i129
112 call void @use(i129 %i)
113 %r = trunc i129 %i to i128
117 ; Negative test - not enough bits to hold max float value (2**127 * (2 − 2**−23))
119 define 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]]
125 %i = fptoui float %x to i128
126 %r = trunc i128 %i to i127
130 define 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]]
135 %i = fptoui double %x to i1025
136 %r = trunc i1025 %i to i1024
140 ; Negative test - not enough bits to hold max double value (2**1023 * (2 − 2**−52))
142 define 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]]
148 %i = fptoui double %x to i1024
149 %r = trunc i1024 %i to i1023
153 ; Negative test - not enough bits to hold min half value (-65504).
155 define 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]]
161 %i = fptosi half %x to i17
162 %r = trunc i17 %i to i16
166 define 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]]
171 %i = fptosi half %x to i18
172 %r = trunc i18 %i to i17
176 ; Wider intermediate type is ok.
177 ; TODO: Handle non-simple result type.
179 define 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]]
185 %i = fptosi half %x to i32
186 %r = trunc i32 %i to i17
190 ; Wider final type is ok.
191 ; TODO: Handle non-simple result type.
193 define 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]]
199 %i = fptosi half %x to i32
200 %r = trunc i32 %i to i18
206 define <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]]
211 %i = fptosi <4 x half> %x to <4 x i32>
212 %r = trunc <4 x i32> %i to <4 x i17>
216 ; Negative test - not enough bits to hold min float value.
218 define 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]]
224 %i = fptosi bfloat %x to i129
225 %r = trunc i129 %i to i128
229 define 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]]
234 %i = fptosi bfloat %x to i130
235 %r = trunc i130 %i to i129
239 define 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]]
244 %i = fptosi float %x to i130
245 %r = trunc i130 %i to i129
249 ; Negative test - not enough bits to hold min float value.
251 define 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]]
257 %i = fptosi float %x to i129
258 %r = trunc i129 %i to i128
262 define 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]]
267 %i = fptosi double %x to i1026
268 %r = trunc i1026 %i to i1025
272 ; Negative test - not enough bits to hold min double value.
274 define 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]]
280 %i = fptosi double %x to i1025
281 %r = trunc i1025 %i to i1024