1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,SIGNED
3 // RUN: %clang_cc1 -ffixed-point -triple x86_64-unknown-linux-gnu -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s --check-prefixes=CHECK,UNSIGNED
4
5 short _Accum sa;
6 _Accum a, a2;
7 long _Accum la;
8
9 unsigned short _Accum usa;
10 unsigned _Accum ua;
11 unsigned long _Accum ula;
12
13 short _Fract sf;
14 _Fract f;
15 long _Fract lf;
16 unsigned _Fract uf;
17
18 _Sat short _Accum sat_sa;
19 _Sat _Accum sat_a;
20 _Sat long _Accum sat_la;
21
22 _Sat unsigned short _Accum sat_usa;
23 _Sat unsigned _Accum sat_ua;
24 _Sat unsigned long _Accum sat_ula;
25
26 _Sat short _Fract sat_sf;
27 _Sat _Fract sat_f;
28 _Sat long _Fract sat_lf;
29
30 short s;
31 int i;
32 unsigned int ui;
33
34 // CHECK-LABEL: @fix_same1(
35 // CHECK-NEXT: entry:
36 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
37 // CHECK-NEXT: store i32 [[TMP0]], i32* @a2, align 4
38 // CHECK-NEXT: ret void
39 //
fix_same1()40 void fix_same1() {
41 a2 = a;
42 }
43
44 // CHECK-LABEL: @fix_same2(
45 // CHECK-NEXT: entry:
46 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
47 // CHECK-NEXT: store i32 [[TMP0]], i32* @a2, align 4
48 // CHECK-NEXT: ret void
49 //
fix_same2()50 void fix_same2() {
51 a2 = (_Accum)a;
52 }
53
54
55 // CHECK-LABEL: @fix_castdown1(
56 // CHECK-NEXT: entry:
57 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
58 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
59 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
60 // CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
61 // CHECK-NEXT: ret void
62 //
fix_castdown1()63 void fix_castdown1() {
64 a = la;
65 }
66
67 // CHECK-LABEL: @fix_castdown2(
68 // CHECK-NEXT: entry:
69 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
70 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
71 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
72 // CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
73 // CHECK-NEXT: ret void
74 //
fix_castdown2()75 void fix_castdown2() {
76 a = (_Accum)la;
77 }
78
79 // CHECK-LABEL: @fix_castdown3(
80 // CHECK-NEXT: entry:
81 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
82 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
83 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
84 // CHECK-NEXT: store i16 [[RESIZE]], i16* @sa, align 2
85 // CHECK-NEXT: ret void
86 //
fix_castdown3()87 void fix_castdown3() {
88 sa = a;
89 }
90
91 // CHECK-LABEL: @fix_castdown4(
92 // CHECK-NEXT: entry:
93 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
94 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
95 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i16
96 // CHECK-NEXT: store i16 [[RESIZE]], i16* @sa, align 2
97 // CHECK-NEXT: ret void
98 //
fix_castdown4()99 void fix_castdown4() {
100 sa = a;
101 }
102
103
104 // CHECK-LABEL: @fix_castup1(
105 // CHECK-NEXT: entry:
106 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
107 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
108 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
109 // CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
110 // CHECK-NEXT: ret void
111 //
fix_castup1()112 void fix_castup1() {
113 a = sa;
114 }
115
116 // CHECK-LABEL: @fix_castup2(
117 // CHECK-NEXT: entry:
118 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
119 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
120 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
121 // CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
122 // CHECK-NEXT: ret void
123 //
fix_castup2()124 void fix_castup2() {
125 a = (_Accum)sa;
126 }
127
128 // CHECK-LABEL: @fix_castup3(
129 // CHECK-NEXT: entry:
130 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
131 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
132 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
133 // CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
134 // CHECK-NEXT: ret void
135 //
fix_castup3()136 void fix_castup3() {
137 a = la;
138 }
139
140 // CHECK-LABEL: @fix_castup4(
141 // CHECK-NEXT: entry:
142 // CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* @la, align 8
143 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i64 [[TMP0]], 16
144 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i64 [[DOWNSCALE]] to i32
145 // CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
146 // CHECK-NEXT: ret void
147 //
fix_castup4()148 void fix_castup4() {
149 a = (long _Accum)la;
150 }
151
152
153 // SIGNED-LABEL: @fix_sign1(
154 // SIGNED-NEXT: entry:
155 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
156 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
157 // SIGNED-NEXT: store i32 [[UPSCALE]], i32* @ua, align 4
158 // SIGNED-NEXT: ret void
159 //
160 // UNSIGNED-LABEL: @fix_sign1(
161 // UNSIGNED-NEXT: entry:
162 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
163 // UNSIGNED-NEXT: store i32 [[TMP0]], i32* @ua, align 4
164 // UNSIGNED-NEXT: ret void
165 //
fix_sign1()166 void fix_sign1() {
167 ua = a;
168 }
169
170 // SIGNED-LABEL: @fix_sign2(
171 // SIGNED-NEXT: entry:
172 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
173 // SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
174 // SIGNED-NEXT: store i32 [[DOWNSCALE]], i32* @a, align 4
175 // SIGNED-NEXT: ret void
176 //
177 // UNSIGNED-LABEL: @fix_sign2(
178 // UNSIGNED-NEXT: entry:
179 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
180 // UNSIGNED-NEXT: store i32 [[TMP0]], i32* @a, align 4
181 // UNSIGNED-NEXT: ret void
182 //
fix_sign2()183 void fix_sign2() {
184 a = ua;
185 }
186
187 // SIGNED-LABEL: @fix_sign3(
188 // SIGNED-NEXT: entry:
189 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
190 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[TMP0]], 1
191 // SIGNED-NEXT: store i32 [[UPSCALE]], i32* @ua, align 4
192 // SIGNED-NEXT: ret void
193 //
194 // UNSIGNED-LABEL: @fix_sign3(
195 // UNSIGNED-NEXT: entry:
196 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
197 // UNSIGNED-NEXT: store i32 [[TMP0]], i32* @ua, align 4
198 // UNSIGNED-NEXT: ret void
199 //
fix_sign3()200 void fix_sign3() {
201 ua = (unsigned _Accum)a;
202 }
203
204 // SIGNED-LABEL: @fix_sign4(
205 // SIGNED-NEXT: entry:
206 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
207 // SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i32 [[TMP0]], 1
208 // SIGNED-NEXT: store i32 [[DOWNSCALE]], i32* @a, align 4
209 // SIGNED-NEXT: ret void
210 //
211 // UNSIGNED-LABEL: @fix_sign4(
212 // UNSIGNED-NEXT: entry:
213 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
214 // UNSIGNED-NEXT: store i32 [[TMP0]], i32* @a, align 4
215 // UNSIGNED-NEXT: ret void
216 //
fix_sign4()217 void fix_sign4() {
218 a = (_Accum)ua;
219 }
220
221 // SIGNED-LABEL: @fix_sign5(
222 // SIGNED-NEXT: entry:
223 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
224 // SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
225 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 17
226 // SIGNED-NEXT: store i64 [[UPSCALE]], i64* @ula, align 8
227 // SIGNED-NEXT: ret void
228 //
229 // UNSIGNED-LABEL: @fix_sign5(
230 // UNSIGNED-NEXT: entry:
231 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
232 // UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i64
233 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 16
234 // UNSIGNED-NEXT: store i64 [[UPSCALE]], i64* @ula, align 8
235 // UNSIGNED-NEXT: ret void
236 //
fix_sign5()237 void fix_sign5() {
238 ula = a;
239 }
240
241
242 // CHECK-LABEL: @fix_sat1(
243 // CHECK-NEXT: entry:
244 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
245 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
246 // CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
247 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
248 // CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
249 // CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
250 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
251 // CHECK-NEXT: store i16 [[RESIZE]], i16* @sat_sa, align 2
252 // CHECK-NEXT: ret void
253 //
fix_sat1()254 void fix_sat1() {
255 // Casting down between types
256 sat_sa = sat_a;
257 }
258
259 // CHECK-LABEL: @fix_sat2(
260 // CHECK-NEXT: entry:
261 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
262 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
263 // CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 127
264 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 127, i32 [[DOWNSCALE]]
265 // CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -128
266 // CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -128, i32 [[SATMAX]]
267 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i8
268 // CHECK-NEXT: store i8 [[RESIZE]], i8* @sat_sf, align 1
269 // CHECK-NEXT: ret void
270 //
fix_sat2()271 void fix_sat2() {
272 // Accum to Fract, decreasing scale
273 sat_sf = sat_a;
274 }
275
276 // CHECK-LABEL: @fix_sat3(
277 // CHECK-NEXT: entry:
278 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
279 // CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 32767
280 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[TMP0]]
281 // CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], -32768
282 // CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 -32768, i32 [[SATMAX]]
283 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
284 // CHECK-NEXT: store i16 [[RESIZE]], i16* @sat_f, align 2
285 // CHECK-NEXT: ret void
286 //
fix_sat3()287 void fix_sat3() {
288 // Accum to Fract, same scale
289 sat_f = a;
290 }
291
292 // CHECK-LABEL: @fix_sat4(
293 // CHECK-NEXT: entry:
294 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
295 // CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i48
296 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i48 [[RESIZE]], 16
297 // CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i48 [[UPSCALE]], 2147483647
298 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i48 2147483647, i48 [[UPSCALE]]
299 // CHECK-NEXT: [[TMP2:%.*]] = icmp slt i48 [[SATMAX]], -2147483648
300 // CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i48 -2147483648, i48 [[SATMAX]]
301 // CHECK-NEXT: [[RESIZE1:%.*]] = trunc i48 [[SATMIN]] to i32
302 // CHECK-NEXT: store i32 [[RESIZE1]], i32* @sat_lf, align 4
303 // CHECK-NEXT: ret void
304 //
fix_sat4()305 void fix_sat4() {
306 // Accum to Fract, increasing scale
307 sat_lf = sat_a;
308 }
309
310 // SIGNED-LABEL: @fix_sat5(
311 // SIGNED-NEXT: entry:
312 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
313 // SIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 7
314 // SIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 65535
315 // SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 65535, i32 [[DOWNSCALE]]
316 // SIGNED-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
317 // SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
318 // SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
319 // SIGNED-NEXT: store i16 [[RESIZE]], i16* @sat_usa, align 2
320 // SIGNED-NEXT: ret void
321 //
322 // UNSIGNED-LABEL: @fix_sat5(
323 // UNSIGNED-NEXT: entry:
324 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
325 // UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
326 // UNSIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[DOWNSCALE]], 32767
327 // UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i32 32767, i32 [[DOWNSCALE]]
328 // UNSIGNED-NEXT: [[TMP2:%.*]] = icmp slt i32 [[SATMAX]], 0
329 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i32 0, i32 [[SATMAX]]
330 // UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[SATMIN]] to i16
331 // UNSIGNED-NEXT: store i16 [[RESIZE]], i16* @sat_usa, align 2
332 // UNSIGNED-NEXT: ret void
333 //
fix_sat5()334 void fix_sat5() {
335 // Signed to unsigned, decreasing scale
336 sat_usa = sat_a;
337 }
338
339 // SIGNED-LABEL: @fix_sat6(
340 // SIGNED-NEXT: entry:
341 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
342 // SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i33
343 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i33 [[RESIZE]], 1
344 // SIGNED-NEXT: [[TMP1:%.*]] = icmp slt i33 [[UPSCALE]], 0
345 // SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i33 0, i33 [[UPSCALE]]
346 // SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i33 [[SATMIN]] to i32
347 // SIGNED-NEXT: store i32 [[RESIZE1]], i32* @sat_ua, align 4
348 // SIGNED-NEXT: ret void
349 //
350 // UNSIGNED-LABEL: @fix_sat6(
351 // UNSIGNED-NEXT: entry:
352 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
353 // UNSIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0]], 0
354 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[TMP0]]
355 // UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
356 // UNSIGNED-NEXT: ret void
357 //
fix_sat6()358 void fix_sat6() {
359 // Signed to unsigned, increasing scale
360 sat_ua = sat_a;
361 }
362
363 // CHECK-LABEL: @fix_sat7(
364 // CHECK-NEXT: entry:
365 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
366 // CHECK-NEXT: store i32 [[TMP0]], i32* @sat_a, align 4
367 // CHECK-NEXT: ret void
368 //
fix_sat7()369 void fix_sat7() {
370 // Nothing when saturating to the same type and size
371 sat_a = a;
372 }
373
374 // CHECK-LABEL: @fix_sat8(
375 // CHECK-NEXT: entry:
376 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @sat_a, align 4
377 // CHECK-NEXT: store i32 [[TMP0]], i32* @a, align 4
378 // CHECK-NEXT: ret void
379 //
fix_sat8()380 void fix_sat8() {
381 // Nothing when assigning back
382 a = sat_a;
383 }
384
385 // CHECK-LABEL: @fix_sat9(
386 // CHECK-NEXT: entry:
387 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sat_f, align 2
388 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
389 // CHECK-NEXT: store i32 [[RESIZE]], i32* @sat_a, align 4
390 // CHECK-NEXT: ret void
391 //
fix_sat9()392 void fix_sat9() {
393 // No overflow when casting from fract to signed accum
394 sat_a = sat_f;
395 }
396
397 // SIGNED-LABEL: @fix_sat10(
398 // SIGNED-NEXT: entry:
399 // SIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @sat_sf, align 1
400 // SIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
401 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 9
402 // SIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
403 // SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
404 // SIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
405 // SIGNED-NEXT: ret void
406 //
407 // UNSIGNED-LABEL: @fix_sat10(
408 // UNSIGNED-NEXT: entry:
409 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i8, i8* @sat_sf, align 1
410 // UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
411 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
412 // UNSIGNED-NEXT: [[TMP1:%.*]] = icmp slt i32 [[UPSCALE]], 0
413 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP1]], i32 0, i32 [[UPSCALE]]
414 // UNSIGNED-NEXT: store i32 [[SATMIN]], i32* @sat_ua, align 4
415 // UNSIGNED-NEXT: ret void
416 //
fix_sat10()417 void fix_sat10() {
418 // Only get overflow checking if signed fract to unsigned accum
419 sat_ua = sat_sf;
420 }
421
422
423 // CHECK-LABEL: @fix_fract1(
424 // CHECK-NEXT: entry:
425 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
426 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i32 [[TMP0]], 8
427 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[DOWNSCALE]] to i8
428 // CHECK-NEXT: store i8 [[RESIZE]], i8* @sf, align 1
429 // CHECK-NEXT: ret void
430 //
fix_fract1()431 void fix_fract1() {
432 // To lower scale
433 sf = a;
434 }
435
436 // CHECK-LABEL: @fix_fract2(
437 // CHECK-NEXT: entry:
438 // CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* @sf, align 1
439 // CHECK-NEXT: [[RESIZE:%.*]] = sext i8 [[TMP0]] to i32
440 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i32 [[RESIZE]], 8
441 // CHECK-NEXT: store i32 [[UPSCALE]], i32* @a, align 4
442 // CHECK-NEXT: ret void
443 //
fix_fract2()444 void fix_fract2() {
445 // To higher scale
446 a = sf;
447 }
448
449 // CHECK-LABEL: @fix_fract3(
450 // CHECK-NEXT: entry:
451 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
452 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
453 // CHECK-NEXT: store i16 [[RESIZE]], i16* @f, align 2
454 // CHECK-NEXT: ret void
455 //
fix_fract3()456 void fix_fract3() {
457 // To same scale
458 f = a;
459 }
460
461 // CHECK-LABEL: @fix_fract4(
462 // CHECK-NEXT: entry:
463 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @f, align 2
464 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i32
465 // CHECK-NEXT: store i32 [[RESIZE]], i32* @a, align 4
466 // CHECK-NEXT: ret void
467 //
fix_fract4()468 void fix_fract4() {
469 a = f;
470 }
471
472 // CHECK-LABEL: @fix_fract5(
473 // CHECK-NEXT: entry:
474 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @uf, align 2
475 // CHECK-NEXT: [[RESIZE:%.*]] = zext i16 [[TMP0]] to i32
476 // CHECK-NEXT: store i32 [[RESIZE]], i32* @ua, align 4
477 // CHECK-NEXT: ret void
478 //
fix_fract5()479 void fix_fract5() {
480 // To unsigned
481 ua = uf;
482 }
483
484 // CHECK-LABEL: @fix_fract6(
485 // CHECK-NEXT: entry:
486 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ua, align 4
487 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
488 // CHECK-NEXT: store i16 [[RESIZE]], i16* @uf, align 2
489 // CHECK-NEXT: ret void
490 //
fix_fract6()491 void fix_fract6() {
492 uf = ua;
493 }
494
495
496 // CHECK-LABEL: @fix_int1(
497 // CHECK-NEXT: entry:
498 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @sa, align 2
499 // CHECK-NEXT: [[TMP1:%.*]] = icmp slt i16 [[TMP0]], 0
500 // CHECK-NEXT: [[TMP2:%.*]] = add i16 [[TMP0]], 127
501 // CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i16 [[TMP2]], i16 [[TMP0]]
502 // CHECK-NEXT: [[DOWNSCALE:%.*]] = ashr i16 [[TMP3]], 7
503 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[DOWNSCALE]] to i32
504 // CHECK-NEXT: store i32 [[RESIZE]], i32* @i, align 4
505 // CHECK-NEXT: ret void
506 //
fix_int1()507 void fix_int1() {
508 // Will need to check for negative values
509 i = sa;
510 }
511
512 // SIGNED-LABEL: @fix_int2(
513 // SIGNED-NEXT: entry:
514 // SIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
515 // SIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 8
516 // SIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
517 // SIGNED-NEXT: store i32 [[RESIZE]], i32* @i, align 4
518 // SIGNED-NEXT: ret void
519 //
520 // UNSIGNED-LABEL: @fix_int2(
521 // UNSIGNED-NEXT: entry:
522 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i16, i16* @usa, align 2
523 // UNSIGNED-NEXT: [[DOWNSCALE:%.*]] = lshr i16 [[TMP0]], 7
524 // UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i16 [[DOWNSCALE]] to i32
525 // UNSIGNED-NEXT: store i32 [[RESIZE]], i32* @i, align 4
526 // UNSIGNED-NEXT: ret void
527 //
fix_int2()528 void fix_int2() {
529 // No check needed for unsigned fixed points. Can just right shift.
530 i = usa;
531 }
532
533
534 // CHECK-LABEL: @int_fix1(
535 // CHECK-NEXT: entry:
536 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
537 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
538 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
539 // CHECK-NEXT: store i16 [[UPSCALE]], i16* @sa, align 2
540 // CHECK-NEXT: ret void
541 //
int_fix1()542 void int_fix1() {
543 sa = i;
544 }
545
546 // CHECK-LABEL: @int_fix2(
547 // CHECK-NEXT: entry:
548 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
549 // CHECK-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
550 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
551 // CHECK-NEXT: store i16 [[UPSCALE]], i16* @sa, align 2
552 // CHECK-NEXT: ret void
553 //
int_fix2()554 void int_fix2() {
555 sa = ui;
556 }
557
558 // SIGNED-LABEL: @int_fix3(
559 // SIGNED-NEXT: entry:
560 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
561 // SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
562 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
563 // SIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
564 // SIGNED-NEXT: ret void
565 //
566 // UNSIGNED-LABEL: @int_fix3(
567 // UNSIGNED-NEXT: entry:
568 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
569 // UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
570 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
571 // UNSIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
572 // UNSIGNED-NEXT: ret void
573 //
int_fix3()574 void int_fix3() {
575 usa = i;
576 }
577
578 // SIGNED-LABEL: @int_fix4(
579 // SIGNED-NEXT: entry:
580 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
581 // SIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
582 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 8
583 // SIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
584 // SIGNED-NEXT: ret void
585 //
586 // UNSIGNED-LABEL: @int_fix4(
587 // UNSIGNED-NEXT: entry:
588 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
589 // UNSIGNED-NEXT: [[RESIZE:%.*]] = trunc i32 [[TMP0]] to i16
590 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i16 [[RESIZE]], 7
591 // UNSIGNED-NEXT: store i16 [[UPSCALE]], i16* @usa, align 2
592 // UNSIGNED-NEXT: ret void
593 //
int_fix4()594 void int_fix4() {
595 usa = ui;
596 }
597
598 // CHECK-LABEL: @int_fix5(
599 // CHECK-NEXT: entry:
600 // CHECK-NEXT: [[TMP0:%.*]] = load i16, i16* @s, align 2
601 // CHECK-NEXT: [[RESIZE:%.*]] = sext i16 [[TMP0]] to i64
602 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i64 [[RESIZE]], 31
603 // CHECK-NEXT: store i64 [[UPSCALE]], i64* @la, align 8
604 // CHECK-NEXT: ret void
605 //
int_fix5()606 void int_fix5() {
607 la = s;
608 }
609
610
611 // CHECK-LABEL: @int_sat1(
612 // CHECK-NEXT: entry:
613 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
614 // CHECK-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
615 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
616 // CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
617 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
618 // CHECK-NEXT: [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], -32768
619 // CHECK-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i39 -32768, i39 [[SATMAX]]
620 // CHECK-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
621 // CHECK-NEXT: store i16 [[RESIZE1]], i16* @sat_sa, align 2
622 // CHECK-NEXT: ret void
623 //
int_sat1()624 void int_sat1() {
625 sat_sa = i;
626 }
627
628 // CHECK-LABEL: @int_sat2(
629 // CHECK-NEXT: entry:
630 // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
631 // CHECK-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
632 // CHECK-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
633 // CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
634 // CHECK-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
635 // CHECK-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
636 // CHECK-NEXT: store i16 [[RESIZE1]], i16* @sat_sa, align 2
637 // CHECK-NEXT: ret void
638 //
int_sat2()639 void int_sat2() {
640 sat_sa = ui;
641 }
642
643 // SIGNED-LABEL: @int_sat3(
644 // SIGNED-NEXT: entry:
645 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
646 // SIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i40
647 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
648 // SIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i40 [[UPSCALE]], 65535
649 // SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
650 // SIGNED-NEXT: [[TMP2:%.*]] = icmp slt i40 [[SATMAX]], 0
651 // SIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i40 0, i40 [[SATMAX]]
652 // SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i40 [[SATMIN]] to i16
653 // SIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
654 // SIGNED-NEXT: ret void
655 //
656 // UNSIGNED-LABEL: @int_sat3(
657 // UNSIGNED-NEXT: entry:
658 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @i, align 4
659 // UNSIGNED-NEXT: [[RESIZE:%.*]] = sext i32 [[TMP0]] to i39
660 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
661 // UNSIGNED-NEXT: [[TMP1:%.*]] = icmp sgt i39 [[UPSCALE]], 32767
662 // UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
663 // UNSIGNED-NEXT: [[TMP2:%.*]] = icmp slt i39 [[SATMAX]], 0
664 // UNSIGNED-NEXT: [[SATMIN:%.*]] = select i1 [[TMP2]], i39 0, i39 [[SATMAX]]
665 // UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMIN]] to i16
666 // UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
667 // UNSIGNED-NEXT: ret void
668 //
int_sat3()669 void int_sat3() {
670 sat_usa = i;
671 }
672
673 // SIGNED-LABEL: @int_sat4(
674 // SIGNED-NEXT: entry:
675 // SIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
676 // SIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i40
677 // SIGNED-NEXT: [[UPSCALE:%.*]] = shl i40 [[RESIZE]], 8
678 // SIGNED-NEXT: [[TMP1:%.*]] = icmp ugt i40 [[UPSCALE]], 65535
679 // SIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i40 65535, i40 [[UPSCALE]]
680 // SIGNED-NEXT: [[RESIZE1:%.*]] = trunc i40 [[SATMAX]] to i16
681 // SIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
682 // SIGNED-NEXT: ret void
683 //
684 // UNSIGNED-LABEL: @int_sat4(
685 // UNSIGNED-NEXT: entry:
686 // UNSIGNED-NEXT: [[TMP0:%.*]] = load i32, i32* @ui, align 4
687 // UNSIGNED-NEXT: [[RESIZE:%.*]] = zext i32 [[TMP0]] to i39
688 // UNSIGNED-NEXT: [[UPSCALE:%.*]] = shl i39 [[RESIZE]], 7
689 // UNSIGNED-NEXT: [[TMP1:%.*]] = icmp ugt i39 [[UPSCALE]], 32767
690 // UNSIGNED-NEXT: [[SATMAX:%.*]] = select i1 [[TMP1]], i39 32767, i39 [[UPSCALE]]
691 // UNSIGNED-NEXT: [[RESIZE1:%.*]] = trunc i39 [[SATMAX]] to i16
692 // UNSIGNED-NEXT: store i16 [[RESIZE1]], i16* @sat_usa, align 2
693 // UNSIGNED-NEXT: ret void
694 //
int_sat4()695 void int_sat4() {
696 sat_usa = ui;
697 }
698