xref: /llvm-project/clang/test/Frontend/fixed_point_conversions.c (revision c5de4dd1eab00df76c1a68c5f397304ceacb71f2)
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -x c -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
3 // RUN: %clang_cc1 -x c -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
4 // RUN: %clang_cc1 -x c++ -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
5 // RUN: %clang_cc1 -x c++ -ffixed-point -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
11 short _Accum sa;
12 _Accum a, a2;
13 long _Accum la;
14 
15 unsigned short _Accum usa;
16 unsigned _Accum ua;
17 unsigned long _Accum ula;
18 
19 short _Fract sf;
20 _Fract f;
21 long _Fract lf;
22 unsigned _Fract uf;
23 
24 _Sat short _Accum sat_sa;
25 _Sat _Accum sat_a;
26 _Sat long _Accum sat_la;
27 
28 _Sat unsigned short _Accum sat_usa;
29 _Sat unsigned _Accum sat_ua;
30 _Sat unsigned long _Accum sat_ula;
31 
32 _Sat short _Fract sat_sf;
33 _Sat _Fract sat_f;
34 _Sat long _Fract sat_lf;
35 _Sat unsigned _Fract sat_uf;
36 
37 short s;
38 int i;
39 unsigned int ui;
40 
41 float fl;
42 double d;
43 
44 // CHECK-LABEL: @fix_same1(
45 // CHECK-NEXT:  entry:
46 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
47 // CHECK-NEXT:    store i32 [[TMP0]], ptr @a2, align 4
48 // CHECK-NEXT:    ret void
49 //
fix_same1(void)50 void fix_same1(void) {
51   a2 = a;
52 }
53 
54 // CHECK-LABEL: @fix_same2(
55 // CHECK-NEXT:  entry:
56 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
57 // CHECK-NEXT:    store i32 [[TMP0]], ptr @a2, align 4
58 // CHECK-NEXT:    ret void
59 //
fix_same2(void)60 void fix_same2(void) {
61   a2 = (_Accum)a;
62 }
63 
64 
65 // CHECK-LABEL: @fix_castdown1(
66 // CHECK-NEXT:  entry:
67 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @la, align 8
68 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
69 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
70 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @a, align 4
71 // CHECK-NEXT:    ret void
72 //
fix_castdown1(void)73 void fix_castdown1(void) {
74   a = la;
75 }
76 
77 // CHECK-LABEL: @fix_castdown2(
78 // CHECK-NEXT:  entry:
79 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @la, align 8
80 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
81 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
82 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @a, align 4
83 // CHECK-NEXT:    ret void
84 //
fix_castdown2(void)85 void fix_castdown2(void) {
86   a = (_Accum)la;
87 }
88 
89 // CHECK-LABEL: @fix_castdown3(
90 // CHECK-NEXT:  entry:
91 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
92 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
93 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
94 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @sa, align 2
95 // CHECK-NEXT:    ret void
96 //
fix_castdown3(void)97 void fix_castdown3(void) {
98   sa = a;
99 }
100 
101 // CHECK-LABEL: @fix_castdown4(
102 // CHECK-NEXT:  entry:
103 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
104 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
105 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
106 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @sa, align 2
107 // CHECK-NEXT:    ret void
108 //
fix_castdown4(void)109 void fix_castdown4(void) {
110   sa = a;
111 }
112 
113 
114 // CHECK-LABEL: @fix_castup1(
115 // CHECK-NEXT:  entry:
116 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @sa, align 2
117 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
118 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
119 // CHECK-NEXT:    store i32 [[UPSCALE]], ptr @a, align 4
120 // CHECK-NEXT:    ret void
121 //
fix_castup1(void)122 void fix_castup1(void) {
123   a = sa;
124 }
125 
126 // CHECK-LABEL: @fix_castup2(
127 // CHECK-NEXT:  entry:
128 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @sa, align 2
129 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
130 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
131 // CHECK-NEXT:    store i32 [[UPSCALE]], ptr @a, align 4
132 // CHECK-NEXT:    ret void
133 //
fix_castup2(void)134 void fix_castup2(void) {
135   a = (_Accum)sa;
136 }
137 
138 // CHECK-LABEL: @fix_castup3(
139 // CHECK-NEXT:  entry:
140 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @la, align 8
141 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
142 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
143 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @a, align 4
144 // CHECK-NEXT:    ret void
145 //
fix_castup3(void)146 void fix_castup3(void) {
147   a = la;
148 }
149 
150 // CHECK-LABEL: @fix_castup4(
151 // CHECK-NEXT:  entry:
152 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @la, align 8
153 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
154 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
155 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @a, align 4
156 // CHECK-NEXT:    ret void
157 //
fix_castup4(void)158 void fix_castup4(void) {
159   a = (long _Accum)la;
160 }
161 
162 
163 // SIGNED-LABEL: @fix_sign1(
164 // SIGNED-NEXT:  entry:
165 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
166 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
167 // SIGNED-NEXT:    store i32 [[UPSCALE]], ptr @ua, align 4
168 // SIGNED-NEXT:    ret void
169 //
170 // UNSIGNED-LABEL: @fix_sign1(
171 // UNSIGNED-NEXT:  entry:
172 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
173 // UNSIGNED-NEXT:    store i32 [[TMP0]], ptr @ua, align 4
174 // UNSIGNED-NEXT:    ret void
175 //
fix_sign1(void)176 void fix_sign1(void) {
177   ua = a;
178 }
179 
180 // SIGNED-LABEL: @fix_sign2(
181 // SIGNED-NEXT:  entry:
182 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
183 // SIGNED-NEXT:    [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
184 // SIGNED-NEXT:    store i32 [[DOWNSCALE]], ptr @a, align 4
185 // SIGNED-NEXT:    ret void
186 //
187 // UNSIGNED-LABEL: @fix_sign2(
188 // UNSIGNED-NEXT:  entry:
189 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
190 // UNSIGNED-NEXT:    store i32 [[TMP0]], ptr @a, align 4
191 // UNSIGNED-NEXT:    ret void
192 //
fix_sign2(void)193 void fix_sign2(void) {
194   a = ua;
195 }
196 
197 // SIGNED-LABEL: @fix_sign3(
198 // SIGNED-NEXT:  entry:
199 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
200 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
201 // SIGNED-NEXT:    store i32 [[UPSCALE]], ptr @ua, align 4
202 // SIGNED-NEXT:    ret void
203 //
204 // UNSIGNED-LABEL: @fix_sign3(
205 // UNSIGNED-NEXT:  entry:
206 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
207 // UNSIGNED-NEXT:    store i32 [[TMP0]], ptr @ua, align 4
208 // UNSIGNED-NEXT:    ret void
209 //
fix_sign3(void)210 void fix_sign3(void) {
211   ua = (unsigned _Accum)a;
212 }
213 
214 // SIGNED-LABEL: @fix_sign4(
215 // SIGNED-NEXT:  entry:
216 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
217 // SIGNED-NEXT:    [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
218 // SIGNED-NEXT:    store i32 [[DOWNSCALE]], ptr @a, align 4
219 // SIGNED-NEXT:    ret void
220 //
221 // UNSIGNED-LABEL: @fix_sign4(
222 // UNSIGNED-NEXT:  entry:
223 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
224 // UNSIGNED-NEXT:    store i32 [[TMP0]], ptr @a, align 4
225 // UNSIGNED-NEXT:    ret void
226 //
fix_sign4(void)227 void fix_sign4(void) {
228   a = (_Accum)ua;
229 }
230 
231 // SIGNED-LABEL: @fix_sign5(
232 // SIGNED-NEXT:  entry:
233 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
234 // SIGNED-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
235 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 17
236 // SIGNED-NEXT:    store i64 [[UPSCALE]], ptr @ula, align 8
237 // SIGNED-NEXT:    ret void
238 //
239 // UNSIGNED-LABEL: @fix_sign5(
240 // UNSIGNED-NEXT:  entry:
241 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
242 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
243 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 16
244 // UNSIGNED-NEXT:    store i64 [[UPSCALE]], ptr @ula, align 8
245 // UNSIGNED-NEXT:    ret void
246 //
fix_sign5(void)247 void fix_sign5(void) {
248   ula = a;
249 }
250 
251 
252 // CHECK-LABEL: @fix_sat1(
253 // CHECK-NEXT:  entry:
254 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
255 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
256 // CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
257 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
258 // CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
259 // CHECK-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
260 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
261 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @sat_sa, align 2
262 // CHECK-NEXT:    ret void
263 //
fix_sat1(void)264 void fix_sat1(void) {
265   // Casting down between types
266   sat_sa = sat_a;
267 }
268 
269 // CHECK-LABEL: @fix_sat2(
270 // CHECK-NEXT:  entry:
271 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
272 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
273 // CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 127
274 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i32 127, i32 [[DOWNSCALE]]
275 // CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -128
276 // CHECK-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -128, i32 [[SATMAX]]
277 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i8
278 // CHECK-NEXT:    store i8 [[RESIZE]], ptr @sat_sf, align 1
279 // CHECK-NEXT:    ret void
280 //
fix_sat2(void)281 void fix_sat2(void) {
282   // Accum to Fract, decreasing scale
283   sat_sf = sat_a;
284 }
285 
286 // CHECK-LABEL: @fix_sat3(
287 // CHECK-NEXT:  entry:
288 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
289 // CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 32767
290 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[TMP0]]
291 // CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
292 // CHECK-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
293 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
294 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @sat_f, align 2
295 // CHECK-NEXT:    ret void
296 //
fix_sat3(void)297 void fix_sat3(void) {
298   // Accum to Fract, same scale
299   sat_f = a;
300 }
301 
302 // CHECK-LABEL: @fix_sat4(
303 // CHECK-NEXT:  entry:
304 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
305 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
306 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
307 // CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i48 [[UPSCALE]], 2147483647
308 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i48 2147483647, i48 [[UPSCALE]]
309 // CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i48 [[SATMAX]], -2147483648
310 // CHECK-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i48 -2147483648, i48 [[SATMAX]]
311 // CHECK-NEXT:    [[RESIZE1:%.*]] = trunc i48 [[SATMIN]] to i32
312 // CHECK-NEXT:    store i32 [[RESIZE1]], ptr @sat_lf, align 4
313 // CHECK-NEXT:    ret void
314 //
fix_sat4(void)315 void fix_sat4(void) {
316   // Accum to Fract, increasing scale
317   sat_lf = sat_a;
318 }
319 
320 // SIGNED-LABEL: @fix_sat5(
321 // SIGNED-NEXT:  entry:
322 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
323 // SIGNED-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 7
324 // SIGNED-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 65535
325 // SIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i32 65535, i32 [[DOWNSCALE]]
326 // SIGNED-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
327 // SIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
328 // SIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
329 // SIGNED-NEXT:    store i16 [[RESIZE]], ptr @sat_usa, align 2
330 // SIGNED-NEXT:    ret void
331 //
332 // UNSIGNED-LABEL: @fix_sat5(
333 // UNSIGNED-NEXT:  entry:
334 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
335 // UNSIGNED-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
336 // UNSIGNED-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
337 // UNSIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
338 // UNSIGNED-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
339 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
340 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
341 // UNSIGNED-NEXT:    store i16 [[RESIZE]], ptr @sat_usa, align 2
342 // UNSIGNED-NEXT:    ret void
343 //
fix_sat5(void)344 void fix_sat5(void) {
345   // Signed to unsigned, decreasing scale
346   sat_usa = sat_a;
347 }
348 
349 // SIGNED-LABEL: @fix_sat6(
350 // SIGNED-NEXT:  entry:
351 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
352 // SIGNED-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i33
353 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
354 // SIGNED-NEXT:    [[TMP1:%.*]] = icmp slt i33 [[UPSCALE]], 0
355 // SIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP1]], i33 0, i33 [[UPSCALE]]
356 // SIGNED-NEXT:    [[RESIZE1:%.*]] = trunc i33 [[SATMIN]] to i32
357 // SIGNED-NEXT:    store i32 [[RESIZE1]], ptr @sat_ua, align 4
358 // SIGNED-NEXT:    ret void
359 //
360 // UNSIGNED-LABEL: @fix_sat6(
361 // UNSIGNED-NEXT:  entry:
362 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
363 // UNSIGNED-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 0
364 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[TMP0]]
365 // UNSIGNED-NEXT:    store i32 [[SATMIN]], ptr @sat_ua, align 4
366 // UNSIGNED-NEXT:    ret void
367 //
fix_sat6(void)368 void fix_sat6(void) {
369   // Signed to unsigned, increasing scale
370   sat_ua = sat_a;
371 }
372 
373 // CHECK-LABEL: @fix_sat7(
374 // CHECK-NEXT:  entry:
375 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
376 // CHECK-NEXT:    store i32 [[TMP0]], ptr @sat_a, align 4
377 // CHECK-NEXT:    ret void
378 //
fix_sat7(void)379 void fix_sat7(void) {
380   // Nothing when saturating to the same type and size
381   sat_a = a;
382 }
383 
384 // CHECK-LABEL: @fix_sat8(
385 // CHECK-NEXT:  entry:
386 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @sat_a, align 4
387 // CHECK-NEXT:    store i32 [[TMP0]], ptr @a, align 4
388 // CHECK-NEXT:    ret void
389 //
fix_sat8(void)390 void fix_sat8(void) {
391   // Nothing when assigning back
392   a = sat_a;
393 }
394 
395 // CHECK-LABEL: @fix_sat9(
396 // CHECK-NEXT:  entry:
397 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @sat_f, align 2
398 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
399 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @sat_a, align 4
400 // CHECK-NEXT:    ret void
401 //
fix_sat9(void)402 void fix_sat9(void) {
403   // No overflow when casting from fract to signed accum
404   sat_a = sat_f;
405 }
406 
407 // SIGNED-LABEL: @fix_sat10(
408 // SIGNED-NEXT:  entry:
409 // SIGNED-NEXT:    [[TMP0:%.*]] = load i8, ptr @sat_sf, align 1
410 // SIGNED-NEXT:    [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
411 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 9
412 // SIGNED-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
413 // SIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
414 // SIGNED-NEXT:    store i32 [[SATMIN]], ptr @sat_ua, align 4
415 // SIGNED-NEXT:    ret void
416 //
417 // UNSIGNED-LABEL: @fix_sat10(
418 // UNSIGNED-NEXT:  entry:
419 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i8, ptr @sat_sf, align 1
420 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
421 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
422 // UNSIGNED-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
423 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
424 // UNSIGNED-NEXT:    store i32 [[SATMIN]], ptr @sat_ua, align 4
425 // UNSIGNED-NEXT:    ret void
426 //
fix_sat10(void)427 void fix_sat10(void) {
428   // Only get overflow checking if signed fract to unsigned accum
429   sat_ua = sat_sf;
430 }
431 
432 
433 // CHECK-LABEL: @fix_fract1(
434 // CHECK-NEXT:  entry:
435 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
436 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
437 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i8
438 // CHECK-NEXT:    store i8 [[RESIZE]], ptr @sf, align 1
439 // CHECK-NEXT:    ret void
440 //
fix_fract1(void)441 void fix_fract1(void) {
442   // To lower scale
443   sf = a;
444 }
445 
446 // CHECK-LABEL: @fix_fract2(
447 // CHECK-NEXT:  entry:
448 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr @sf, align 1
449 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
450 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
451 // CHECK-NEXT:    store i32 [[UPSCALE]], ptr @a, align 4
452 // CHECK-NEXT:    ret void
453 //
fix_fract2(void)454 void fix_fract2(void) {
455   // To higher scale
456   a = sf;
457 }
458 
459 // CHECK-LABEL: @fix_fract3(
460 // CHECK-NEXT:  entry:
461 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
462 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
463 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @f, align 2
464 // CHECK-NEXT:    ret void
465 //
fix_fract3(void)466 void fix_fract3(void) {
467   // To same scale
468   f = a;
469 }
470 
471 // CHECK-LABEL: @fix_fract4(
472 // CHECK-NEXT:  entry:
473 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @f, align 2
474 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
475 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @a, align 4
476 // CHECK-NEXT:    ret void
477 //
fix_fract4(void)478 void fix_fract4(void) {
479   a = f;
480 }
481 
482 // CHECK-LABEL: @fix_fract5(
483 // CHECK-NEXT:  entry:
484 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @uf, align 2
485 // CHECK-NEXT:    [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
486 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @ua, align 4
487 // CHECK-NEXT:    ret void
488 //
fix_fract5(void)489 void fix_fract5(void) {
490   // To unsigned
491   ua = uf;
492 }
493 
494 // CHECK-LABEL: @fix_fract6(
495 // CHECK-NEXT:  entry:
496 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
497 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
498 // CHECK-NEXT:    store i16 [[RESIZE]], ptr @uf, align 2
499 // CHECK-NEXT:    ret void
500 //
fix_fract6(void)501 void fix_fract6(void) {
502   uf = ua;
503 }
504 
505 
506 // CHECK-LABEL: @fix_int1(
507 // CHECK-NEXT:  entry:
508 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @sa, align 2
509 // CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i16 [[TMP0]], 0
510 // CHECK-NEXT:    [[TMP2:%.*]] = add i16 [[TMP0]], 127
511 // CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i16 [[TMP2]], i16 [[TMP0]]
512 // CHECK-NEXT:    [[DOWNSCALE:%.*]] = ashr i16 [[TMP3]], 7
513 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[DOWNSCALE]] to i32
514 // CHECK-NEXT:    store i32 [[RESIZE]], ptr @i, align 4
515 // CHECK-NEXT:    ret void
516 //
fix_int1(void)517 void fix_int1(void) {
518   // Will need to check for negative values
519   i = sa;
520 }
521 
522 // SIGNED-LABEL: @fix_int2(
523 // SIGNED-NEXT:  entry:
524 // SIGNED-NEXT:    [[TMP0:%.*]] = load i16, ptr @usa, align 2
525 // SIGNED-NEXT:    [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 8
526 // SIGNED-NEXT:    [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
527 // SIGNED-NEXT:    store i32 [[RESIZE]], ptr @i, align 4
528 // SIGNED-NEXT:    ret void
529 //
530 // UNSIGNED-LABEL: @fix_int2(
531 // UNSIGNED-NEXT:  entry:
532 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i16, ptr @usa, align 2
533 // UNSIGNED-NEXT:    [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 7
534 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
535 // UNSIGNED-NEXT:    store i32 [[RESIZE]], ptr @i, align 4
536 // UNSIGNED-NEXT:    ret void
537 //
fix_int2(void)538 void fix_int2(void) {
539   // No check needed for unsigned fixed points. Can just right shift.
540   i = usa;
541 }
542 
543 
544 // CHECK-LABEL: @int_fix1(
545 // CHECK-NEXT:  entry:
546 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
547 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
548 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
549 // CHECK-NEXT:    store i16 [[UPSCALE]], ptr @sa, align 2
550 // CHECK-NEXT:    ret void
551 //
int_fix1(void)552 void int_fix1(void) {
553   sa = i;
554 }
555 
556 // CHECK-LABEL: @int_fix2(
557 // CHECK-NEXT:  entry:
558 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
559 // CHECK-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
560 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
561 // CHECK-NEXT:    store i16 [[UPSCALE]], ptr @sa, align 2
562 // CHECK-NEXT:    ret void
563 //
int_fix2(void)564 void int_fix2(void) {
565   sa = ui;
566 }
567 
568 // SIGNED-LABEL: @int_fix3(
569 // SIGNED-NEXT:  entry:
570 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
571 // SIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
572 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
573 // SIGNED-NEXT:    store i16 [[UPSCALE]], ptr @usa, align 2
574 // SIGNED-NEXT:    ret void
575 //
576 // UNSIGNED-LABEL: @int_fix3(
577 // UNSIGNED-NEXT:  entry:
578 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
579 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
580 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
581 // UNSIGNED-NEXT:    store i16 [[UPSCALE]], ptr @usa, align 2
582 // UNSIGNED-NEXT:    ret void
583 //
int_fix3(void)584 void int_fix3(void) {
585   usa = i;
586 }
587 
588 // SIGNED-LABEL: @int_fix4(
589 // SIGNED-NEXT:  entry:
590 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
591 // SIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
592 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
593 // SIGNED-NEXT:    store i16 [[UPSCALE]], ptr @usa, align 2
594 // SIGNED-NEXT:    ret void
595 //
596 // UNSIGNED-LABEL: @int_fix4(
597 // UNSIGNED-NEXT:  entry:
598 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
599 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
600 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
601 // UNSIGNED-NEXT:    store i16 [[UPSCALE]], ptr @usa, align 2
602 // UNSIGNED-NEXT:    ret void
603 //
int_fix4(void)604 void int_fix4(void) {
605   usa = ui;
606 }
607 
608 // CHECK-LABEL: @int_fix5(
609 // CHECK-NEXT:  entry:
610 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @s, align 2
611 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i16 [[TMP0]] to i64
612 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 31
613 // CHECK-NEXT:    store i64 [[UPSCALE]], ptr @la, align 8
614 // CHECK-NEXT:    ret void
615 //
int_fix5(void)616 void int_fix5(void) {
617   la = s;
618 }
619 
620 
621 // CHECK-LABEL: @int_sat1(
622 // CHECK-NEXT:  entry:
623 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
624 // CHECK-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
625 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
626 // CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
627 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
628 // CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], -32768
629 // CHECK-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i39 -32768, i39 [[SATMAX]]
630 // CHECK-NEXT:    [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
631 // CHECK-NEXT:    store i16 [[RESIZE1]], ptr @sat_sa, align 2
632 // CHECK-NEXT:    ret void
633 //
int_sat1(void)634 void int_sat1(void) {
635   sat_sa = i;
636 }
637 
638 // CHECK-LABEL: @int_sat2(
639 // CHECK-NEXT:  entry:
640 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
641 // CHECK-NEXT:    [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
642 // CHECK-NEXT:    [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
643 // CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
644 // CHECK-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
645 // CHECK-NEXT:    [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
646 // CHECK-NEXT:    store i16 [[RESIZE1]], ptr @sat_sa, align 2
647 // CHECK-NEXT:    ret void
648 //
int_sat2(void)649 void int_sat2(void) {
650   sat_sa = ui;
651 }
652 
653 // SIGNED-LABEL: @int_sat3(
654 // SIGNED-NEXT:  entry:
655 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
656 // SIGNED-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i40
657 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
658 // SIGNED-NEXT:    [[TMP1:%.*]] = icmp sgt i40 [[UPSCALE]], 65535
659 // SIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
660 // SIGNED-NEXT:    [[TMP2:%.*]] = icmp slt i40 [[SATMAX]], 0
661 // SIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i40 0, i40 [[SATMAX]]
662 // SIGNED-NEXT:    [[RESIZE1:%.*]] = trunc i40 [[SATMIN]] to i16
663 // SIGNED-NEXT:    store i16 [[RESIZE1]], ptr @sat_usa, align 2
664 // SIGNED-NEXT:    ret void
665 //
666 // UNSIGNED-LABEL: @int_sat3(
667 // UNSIGNED-NEXT:  entry:
668 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @i, align 4
669 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
670 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
671 // UNSIGNED-NEXT:    [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
672 // UNSIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
673 // UNSIGNED-NEXT:    [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], 0
674 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP2]], i39 0, i39 [[SATMAX]]
675 // UNSIGNED-NEXT:    [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
676 // UNSIGNED-NEXT:    store i16 [[RESIZE1]], ptr @sat_usa, align 2
677 // UNSIGNED-NEXT:    ret void
678 //
int_sat3(void)679 void int_sat3(void) {
680   sat_usa = i;
681 }
682 
683 // SIGNED-LABEL: @int_sat4(
684 // SIGNED-NEXT:  entry:
685 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
686 // SIGNED-NEXT:    [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
687 // SIGNED-NEXT:    [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
688 // SIGNED-NEXT:    [[TMP1:%.*]] = icmp ugt i40 [[UPSCALE]], 65535
689 // SIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
690 // SIGNED-NEXT:    [[RESIZE1:%.*]] = trunc i40 [[SATMAX]] to i16
691 // SIGNED-NEXT:    store i16 [[RESIZE1]], ptr @sat_usa, align 2
692 // SIGNED-NEXT:    ret void
693 //
694 // UNSIGNED-LABEL: @int_sat4(
695 // UNSIGNED-NEXT:  entry:
696 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ui, align 4
697 // UNSIGNED-NEXT:    [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
698 // UNSIGNED-NEXT:    [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
699 // UNSIGNED-NEXT:    [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
700 // UNSIGNED-NEXT:    [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
701 // UNSIGNED-NEXT:    [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
702 // UNSIGNED-NEXT:    store i16 [[RESIZE1]], ptr @sat_usa, align 2
703 // UNSIGNED-NEXT:    ret void
704 //
int_sat4(void)705 void int_sat4(void) {
706   sat_usa = ui;
707 }
708 
709 
710 // CHECK-LABEL: @float_fix1(
711 // CHECK-NEXT:  entry:
712 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
713 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 1.280000e+02
714 // CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i16
715 // CHECK-NEXT:    store i16 [[TMP2]], ptr @sa, align 2
716 // CHECK-NEXT:    ret void
717 //
float_fix1(void)718 void float_fix1(void) {
719   sa = fl;
720 }
721 
722 // CHECK-LABEL: @float_fix2(
723 // CHECK-NEXT:  entry:
724 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
725 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
726 // CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i32
727 // CHECK-NEXT:    store i32 [[TMP2]], ptr @a, align 4
728 // CHECK-NEXT:    ret void
729 //
float_fix2(void)730 void float_fix2(void) {
731   a = fl;
732 }
733 
734 // CHECK-LABEL: @float_fix3(
735 // CHECK-NEXT:  entry:
736 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
737 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 0x41E0000000000000
738 // CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i64
739 // CHECK-NEXT:    store i64 [[TMP2]], ptr @la, align 8
740 // CHECK-NEXT:    ret void
741 //
float_fix3(void)742 void float_fix3(void) {
743   la = fl;
744 }
745 
746 // CHECK-LABEL: @float_fix4(
747 // CHECK-NEXT:  entry:
748 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
749 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 1.280000e+02
750 // CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
751 // CHECK-NEXT:    store i8 [[TMP2]], ptr @sf, align 1
752 // CHECK-NEXT:    ret void
753 //
float_fix4(void)754 void float_fix4(void) {
755   sf = fl;
756 }
757 
758 // CHECK-LABEL: @float_fix5(
759 // CHECK-NEXT:  entry:
760 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
761 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 0x41E0000000000000
762 // CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i32
763 // CHECK-NEXT:    store i32 [[TMP2]], ptr @lf, align 4
764 // CHECK-NEXT:    ret void
765 //
float_fix5(void)766 void float_fix5(void) {
767   lf = fl;
768 }
769 
770 // SIGNED-LABEL: @float_fix6(
771 // SIGNED-NEXT:  entry:
772 // SIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
773 // SIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 6.553600e+04
774 // SIGNED-NEXT:    [[TMP2:%.*]] = fptoui float [[TMP1]] to i32
775 // SIGNED-NEXT:    store i32 [[TMP2]], ptr @ua, align 4
776 // SIGNED-NEXT:    ret void
777 //
778 // UNSIGNED-LABEL: @float_fix6(
779 // UNSIGNED-NEXT:  entry:
780 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
781 // UNSIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
782 // UNSIGNED-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i32
783 // UNSIGNED-NEXT:    store i32 [[TMP2]], ptr @ua, align 4
784 // UNSIGNED-NEXT:    ret void
785 //
float_fix6(void)786 void float_fix6(void) {
787   ua = fl;
788 }
789 
790 // SIGNED-LABEL: @float_fix7(
791 // SIGNED-NEXT:  entry:
792 // SIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
793 // SIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 6.553600e+04
794 // SIGNED-NEXT:    [[TMP2:%.*]] = fptoui float [[TMP1]] to i16
795 // SIGNED-NEXT:    store i16 [[TMP2]], ptr @uf, align 2
796 // SIGNED-NEXT:    ret void
797 //
798 // UNSIGNED-LABEL: @float_fix7(
799 // UNSIGNED-NEXT:  entry:
800 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
801 // UNSIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
802 // UNSIGNED-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i16
803 // UNSIGNED-NEXT:    store i16 [[TMP2]], ptr @uf, align 2
804 // UNSIGNED-NEXT:    ret void
805 //
float_fix7(void)806 void float_fix7(void) {
807   uf = fl;
808 }
809 
810 
811 // CHECK-LABEL: @fix_float1(
812 // CHECK-NEXT:  entry:
813 // CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @sa, align 2
814 // CHECK-NEXT:    [[TMP1:%.*]] = sitofp i16 [[TMP0]] to float
815 // CHECK-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 7.812500e-03
816 // CHECK-NEXT:    store float [[TMP2]], ptr @fl, align 4
817 // CHECK-NEXT:    ret void
818 //
fix_float1(void)819 void fix_float1(void) {
820   fl = sa;
821 }
822 
823 // CHECK-LABEL: @fix_float2(
824 // CHECK-NEXT:  entry:
825 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @a, align 4
826 // CHECK-NEXT:    [[TMP1:%.*]] = sitofp i32 [[TMP0]] to float
827 // CHECK-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3F00000000000000
828 // CHECK-NEXT:    store float [[TMP2]], ptr @fl, align 4
829 // CHECK-NEXT:    ret void
830 //
fix_float2(void)831 void fix_float2(void) {
832   fl = a;
833 }
834 
835 // CHECK-LABEL: @fix_float3(
836 // CHECK-NEXT:  entry:
837 // CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr @la, align 8
838 // CHECK-NEXT:    [[TMP1:%.*]] = sitofp i64 [[TMP0]] to float
839 // CHECK-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3E00000000000000
840 // CHECK-NEXT:    store float [[TMP2]], ptr @fl, align 4
841 // CHECK-NEXT:    ret void
842 //
fix_float3(void)843 void fix_float3(void) {
844   fl = la;
845 }
846 
847 // CHECK-LABEL: @fix_float4(
848 // CHECK-NEXT:  entry:
849 // CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr @sf, align 1
850 // CHECK-NEXT:    [[TMP1:%.*]] = sitofp i8 [[TMP0]] to float
851 // CHECK-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 7.812500e-03
852 // CHECK-NEXT:    store float [[TMP2]], ptr @fl, align 4
853 // CHECK-NEXT:    ret void
854 //
fix_float4(void)855 void fix_float4(void) {
856   fl = sf;
857 }
858 
859 // CHECK-LABEL: @fix_float5(
860 // CHECK-NEXT:  entry:
861 // CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr @lf, align 4
862 // CHECK-NEXT:    [[TMP1:%.*]] = sitofp i32 [[TMP0]] to float
863 // CHECK-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3E00000000000000
864 // CHECK-NEXT:    store float [[TMP2]], ptr @fl, align 4
865 // CHECK-NEXT:    ret void
866 //
fix_float5(void)867 void fix_float5(void) {
868   fl = lf;
869 }
870 
871 // SIGNED-LABEL: @fix_float6(
872 // SIGNED-NEXT:  entry:
873 // SIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
874 // SIGNED-NEXT:    [[TMP1:%.*]] = uitofp i32 [[TMP0]] to float
875 // SIGNED-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3EF0000000000000
876 // SIGNED-NEXT:    store float [[TMP2]], ptr @fl, align 4
877 // SIGNED-NEXT:    ret void
878 //
879 // UNSIGNED-LABEL: @fix_float6(
880 // UNSIGNED-NEXT:  entry:
881 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i32, ptr @ua, align 4
882 // UNSIGNED-NEXT:    [[TMP1:%.*]] = uitofp i32 [[TMP0]] to float
883 // UNSIGNED-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3F00000000000000
884 // UNSIGNED-NEXT:    store float [[TMP2]], ptr @fl, align 4
885 // UNSIGNED-NEXT:    ret void
886 //
fix_float6(void)887 void fix_float6(void) {
888   fl = ua;
889 }
890 
891 // SIGNED-LABEL: @fix_float7(
892 // SIGNED-NEXT:  entry:
893 // SIGNED-NEXT:    [[TMP0:%.*]] = load i16, ptr @uf, align 2
894 // SIGNED-NEXT:    [[TMP1:%.*]] = uitofp i16 [[TMP0]] to float
895 // SIGNED-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3EF0000000000000
896 // SIGNED-NEXT:    store float [[TMP2]], ptr @fl, align 4
897 // SIGNED-NEXT:    ret void
898 //
899 // UNSIGNED-LABEL: @fix_float7(
900 // UNSIGNED-NEXT:  entry:
901 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load i16, ptr @uf, align 2
902 // UNSIGNED-NEXT:    [[TMP1:%.*]] = uitofp i16 [[TMP0]] to float
903 // UNSIGNED-NEXT:    [[TMP2:%.*]] = fmul float [[TMP1]], 0x3F00000000000000
904 // UNSIGNED-NEXT:    store float [[TMP2]], ptr @fl, align 4
905 // UNSIGNED-NEXT:    ret void
906 //
fix_float7(void)907 void fix_float7(void) {
908   fl = uf;
909 }
910 
911 
912 // CHECK-LABEL: @float_sat1(
913 // CHECK-NEXT:  entry:
914 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
915 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 1.280000e+02
916 // CHECK-NEXT:    [[TMP2:%.*]] = call i16 @llvm.fptosi.sat.i16.f32(float [[TMP1]])
917 // CHECK-NEXT:    store i16 [[TMP2]], ptr @sat_sa, align 2
918 // CHECK-NEXT:    ret void
919 //
float_sat1(void)920 void float_sat1(void) {
921   sat_sa = fl;
922 }
923 
924 // CHECK-LABEL: @float_sat2(
925 // CHECK-NEXT:  entry:
926 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
927 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
928 // CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[TMP1]])
929 // CHECK-NEXT:    store i32 [[TMP2]], ptr @sat_a, align 4
930 // CHECK-NEXT:    ret void
931 //
float_sat2(void)932 void float_sat2(void) {
933   sat_a = fl;
934 }
935 
936 // CHECK-LABEL: @float_sat3(
937 // CHECK-NEXT:  entry:
938 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
939 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 0x41E0000000000000
940 // CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.fptosi.sat.i64.f32(float [[TMP1]])
941 // CHECK-NEXT:    store i64 [[TMP2]], ptr @sat_la, align 8
942 // CHECK-NEXT:    ret void
943 //
float_sat3(void)944 void float_sat3(void) {
945   sat_la = fl;
946 }
947 
948 // CHECK-LABEL: @float_sat4(
949 // CHECK-NEXT:  entry:
950 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
951 // CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 1.280000e+02
952 // CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.fptosi.sat.i8.f32(float [[TMP1]])
953 // CHECK-NEXT:    store i8 [[TMP2]], ptr @sat_sf, align 1
954 // CHECK-NEXT:    ret void
955 //
float_sat4(void)956 void float_sat4(void) {
957   sat_sf = fl;
958 }
959 
960 // SIGNED-LABEL: @float_sat5(
961 // SIGNED-NEXT:  entry:
962 // SIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
963 // SIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 6.553600e+04
964 // SIGNED-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fptoui.sat.i32.f32(float [[TMP1]])
965 // SIGNED-NEXT:    store i32 [[TMP2]], ptr @sat_ua, align 4
966 // SIGNED-NEXT:    ret void
967 //
968 // UNSIGNED-LABEL: @float_sat5(
969 // UNSIGNED-NEXT:  entry:
970 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
971 // UNSIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
972 // UNSIGNED-NEXT:    [[TMP2:%.*]] = call i32 @llvm.fptosi.sat.i32.f32(float [[TMP1]])
973 // UNSIGNED-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 0
974 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP3]], i32 0, i32 [[TMP2]]
975 // UNSIGNED-NEXT:    store i32 [[SATMIN]], ptr @sat_ua, align 4
976 // UNSIGNED-NEXT:    ret void
977 //
float_sat5(void)978 void float_sat5(void) {
979   sat_ua = fl;
980 }
981 
982 // SIGNED-LABEL: @float_sat6(
983 // SIGNED-NEXT:  entry:
984 // SIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
985 // SIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 6.553600e+04
986 // SIGNED-NEXT:    [[TMP2:%.*]] = call i16 @llvm.fptoui.sat.i16.f32(float [[TMP1]])
987 // SIGNED-NEXT:    store i16 [[TMP2]], ptr @sat_uf, align 2
988 // SIGNED-NEXT:    ret void
989 //
990 // UNSIGNED-LABEL: @float_sat6(
991 // UNSIGNED-NEXT:  entry:
992 // UNSIGNED-NEXT:    [[TMP0:%.*]] = load float, ptr @fl, align 4
993 // UNSIGNED-NEXT:    [[TMP1:%.*]] = fmul float [[TMP0]], 3.276800e+04
994 // UNSIGNED-NEXT:    [[TMP2:%.*]] = call i16 @llvm.fptosi.sat.i16.f32(float [[TMP1]])
995 // UNSIGNED-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 0
996 // UNSIGNED-NEXT:    [[SATMIN:%.*]] = select i1 [[TMP3]], i16 0, i16 [[TMP2]]
997 // UNSIGNED-NEXT:    store i16 [[SATMIN]], ptr @sat_uf, align 2
998 // UNSIGNED-NEXT:    ret void
999 //
float_sat6(void)1000 void float_sat6(void) {
1001   sat_uf = fl;
1002 }
1003 
1004 #ifdef __cplusplus
1005 }
1006 #endif
1007