1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=armv4t-eabi %s -o - | FileCheck %s --check-prefix=V4T
3 ; RUN: llc -mtriple=armv6-eabi %s -o - | FileCheck %s --check-prefix=V6
4 ; RUN: llc -mtriple=armv6t2-eabi %s -o - | FileCheck %s --check-prefix=V6T2
6 ; Check for several conditions that should result in USAT.
7 ; For example, the base test is equivalent to
8 ; x < 0 ? 0 : (x > k ? k : x) in C. All patterns that bound x
9 ; to the interval [0, k] where k + 1 is a power of 2 can be
10 ; transformed into USAT. At the end there are some tests
11 ; checking that conditionals are not transformed if they don't
12 ; match the right pattern.
15 ; Base tests with different bit widths
18 ; x < 0 ? 0 : (x > k ? k : x)
20 define i32 @unsigned_sat_base_32bit(i32 %x) #0 {
21 ; V4T-LABEL: unsigned_sat_base_32bit:
22 ; V4T: @ %bb.0: @ %entry
23 ; V4T-NEXT: ldr r1, .LCPI0_0
24 ; V4T-NEXT: cmp r0, r1
25 ; V4T-NEXT: movlt r1, r0
26 ; V4T-NEXT: bic r0, r1, r1, asr #31
28 ; V4T-NEXT: .p2align 2
31 ; V4T-NEXT: .long 8388607 @ 0x7fffff
33 ; V6-LABEL: unsigned_sat_base_32bit:
34 ; V6: @ %bb.0: @ %entry
35 ; V6-NEXT: usat r0, #23, r0
38 ; V6T2-LABEL: unsigned_sat_base_32bit:
39 ; V6T2: @ %bb.0: @ %entry
40 ; V6T2-NEXT: usat r0, #23, r0
43 %0 = icmp slt i32 %x, 8388607
44 %saturateUp = select i1 %0, i32 %x, i32 8388607
45 %1 = icmp sgt i32 %saturateUp, 0
46 %saturateLow = select i1 %1, i32 %saturateUp, i32 0
50 ; x < 0 ? 0 : (x > k ? k : x)
52 define i16 @unsigned_sat_base_16bit(i16 %x) #0 {
53 ; V4T-LABEL: unsigned_sat_base_16bit:
54 ; V4T: @ %bb.0: @ %entry
55 ; V4T-NEXT: mov r2, #255
56 ; V4T-NEXT: lsl r1, r0, #16
57 ; V4T-NEXT: orr r2, r2, #1792
58 ; V4T-NEXT: asr r1, r1, #16
59 ; V4T-NEXT: cmp r1, r2
60 ; V4T-NEXT: movge r0, r2
61 ; V4T-NEXT: lsl r1, r0, #16
62 ; V4T-NEXT: asr r1, r1, #16
63 ; V4T-NEXT: cmp r1, #0
64 ; V4T-NEXT: movle r0, #0
67 ; V6-LABEL: unsigned_sat_base_16bit:
68 ; V6: @ %bb.0: @ %entry
69 ; V6-NEXT: mov r2, #255
70 ; V6-NEXT: sxth r1, r0
71 ; V6-NEXT: orr r2, r2, #1792
73 ; V6-NEXT: movge r0, r2
74 ; V6-NEXT: sxth r1, r0
76 ; V6-NEXT: movle r0, #0
79 ; V6T2-LABEL: unsigned_sat_base_16bit:
80 ; V6T2: @ %bb.0: @ %entry
81 ; V6T2-NEXT: sxth r1, r0
82 ; V6T2-NEXT: movw r2, #2047
83 ; V6T2-NEXT: cmp r1, r2
84 ; V6T2-NEXT: movge r0, r2
85 ; V6T2-NEXT: sxth r1, r0
86 ; V6T2-NEXT: cmp r1, #0
87 ; V6T2-NEXT: movle r0, #0
90 %0 = icmp slt i16 %x, 2047
91 %saturateUp = select i1 %0, i16 %x, i16 2047
92 %1 = icmp sgt i16 %saturateUp, 0
93 %saturateLow = select i1 %1, i16 %saturateUp, i16 0
97 ; x < 0 ? 0 : (x > k ? k : x)
99 define i8 @unsigned_sat_base_8bit(i8 %x) #0 {
100 ; V4T-LABEL: unsigned_sat_base_8bit:
101 ; V4T: @ %bb.0: @ %entry
102 ; V4T-NEXT: lsl r1, r0, #24
103 ; V4T-NEXT: asr r1, r1, #24
104 ; V4T-NEXT: cmp r1, #31
105 ; V4T-NEXT: movge r0, #31
106 ; V4T-NEXT: lsl r1, r0, #24
107 ; V4T-NEXT: asr r1, r1, #24
108 ; V4T-NEXT: cmp r1, #0
109 ; V4T-NEXT: movle r0, #0
112 ; V6-LABEL: unsigned_sat_base_8bit:
113 ; V6: @ %bb.0: @ %entry
114 ; V6-NEXT: sxtb r1, r0
115 ; V6-NEXT: cmp r1, #31
116 ; V6-NEXT: movge r0, #31
117 ; V6-NEXT: sxtb r1, r0
118 ; V6-NEXT: cmp r1, #0
119 ; V6-NEXT: movle r0, #0
122 ; V6T2-LABEL: unsigned_sat_base_8bit:
123 ; V6T2: @ %bb.0: @ %entry
124 ; V6T2-NEXT: sxtb r1, r0
125 ; V6T2-NEXT: cmp r1, #31
126 ; V6T2-NEXT: movge r0, #31
127 ; V6T2-NEXT: sxtb r1, r0
128 ; V6T2-NEXT: cmp r1, #0
129 ; V6T2-NEXT: movle r0, #0
132 %0 = icmp slt i8 %x, 31
133 %saturateUp = select i1 %0, i8 %x, i8 31
134 %1 = icmp sgt i8 %saturateUp, 0
135 %saturateLow = select i1 %1, i8 %saturateUp, i8 0
140 ; Tests where the conditionals that check for upper and lower bounds,
141 ; or the < and > operators, are arranged in different ways. Only some
142 ; of the possible combinations that lead to USAT are tested.
144 ; x < 0 ? 0 : (x < k ? x : k)
145 define i32 @unsigned_sat_lower_upper_1(i32 %x) #0 {
146 ; V4T-LABEL: unsigned_sat_lower_upper_1:
147 ; V4T: @ %bb.0: @ %entry
148 ; V4T-NEXT: ldr r1, .LCPI3_0
149 ; V4T-NEXT: cmp r0, r1
150 ; V4T-NEXT: movlt r1, r0
151 ; V4T-NEXT: bic r0, r1, r1, asr #31
153 ; V4T-NEXT: .p2align 2
155 ; V4T-NEXT: .LCPI3_0:
156 ; V4T-NEXT: .long 8388607 @ 0x7fffff
158 ; V6-LABEL: unsigned_sat_lower_upper_1:
159 ; V6: @ %bb.0: @ %entry
160 ; V6-NEXT: usat r0, #23, r0
163 ; V6T2-LABEL: unsigned_sat_lower_upper_1:
164 ; V6T2: @ %bb.0: @ %entry
165 ; V6T2-NEXT: usat r0, #23, r0
168 %cmpUp = icmp slt i32 %x, 8388607
169 %saturateUp = select i1 %cmpUp, i32 %x, i32 8388607
170 %0 = icmp sgt i32 %saturateUp, 0
171 %saturateLow = select i1 %0, i32 %saturateUp, i32 0
175 ; x > 0 ? (x > k ? k : x) : 0
176 define i32 @unsigned_sat_lower_upper_2(i32 %x) #0 {
177 ; V4T-LABEL: unsigned_sat_lower_upper_2:
178 ; V4T: @ %bb.0: @ %entry
179 ; V4T-NEXT: ldr r1, .LCPI4_0
180 ; V4T-NEXT: cmp r0, r1
181 ; V4T-NEXT: movlt r1, r0
182 ; V4T-NEXT: bic r0, r1, r1, asr #31
184 ; V4T-NEXT: .p2align 2
186 ; V4T-NEXT: .LCPI4_0:
187 ; V4T-NEXT: .long 8388607 @ 0x7fffff
189 ; V6-LABEL: unsigned_sat_lower_upper_2:
190 ; V6: @ %bb.0: @ %entry
191 ; V6-NEXT: usat r0, #23, r0
194 ; V6T2-LABEL: unsigned_sat_lower_upper_2:
195 ; V6T2: @ %bb.0: @ %entry
196 ; V6T2-NEXT: usat r0, #23, r0
199 %0 = icmp slt i32 %x, 8388607
200 %saturateUp = select i1 %0, i32 %x, i32 8388607
201 %1 = icmp sgt i32 %saturateUp, 0
202 %saturateLow = select i1 %1, i32 %saturateUp, i32 0
206 ; x < k ? (x < 0 ? 0 : x) : k
207 define i32 @unsigned_sat_upper_lower_1(i32 %x) #0 {
208 ; V4T-LABEL: unsigned_sat_upper_lower_1:
209 ; V4T: @ %bb.0: @ %entry
210 ; V4T-NEXT: bic r1, r0, r0, asr #31
211 ; V4T-NEXT: ldr r0, .LCPI5_0
212 ; V4T-NEXT: cmp r1, r0
213 ; V4T-NEXT: movlt r0, r1
215 ; V4T-NEXT: .p2align 2
217 ; V4T-NEXT: .LCPI5_0:
218 ; V4T-NEXT: .long 8388607 @ 0x7fffff
220 ; V6-LABEL: unsigned_sat_upper_lower_1:
221 ; V6: @ %bb.0: @ %entry
222 ; V6-NEXT: usat r0, #23, r0
225 ; V6T2-LABEL: unsigned_sat_upper_lower_1:
226 ; V6T2: @ %bb.0: @ %entry
227 ; V6T2-NEXT: usat r0, #23, r0
230 %0 = icmp sgt i32 %x, 0
231 %saturateLow = select i1 %0, i32 %x, i32 0
232 %1 = icmp slt i32 %saturateLow, 8388607
233 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
237 ; x > k ? k : (x < 0 ? 0 : x)
238 define i32 @unsigned_sat_upper_lower_2(i32 %x) #0 {
239 ; V4T-LABEL: unsigned_sat_upper_lower_2:
240 ; V4T: @ %bb.0: @ %entry
241 ; V4T-NEXT: bic r1, r0, r0, asr #31
242 ; V4T-NEXT: ldr r0, .LCPI6_0
243 ; V4T-NEXT: cmp r1, r0
244 ; V4T-NEXT: movlt r0, r1
246 ; V4T-NEXT: .p2align 2
248 ; V4T-NEXT: .LCPI6_0:
249 ; V4T-NEXT: .long 8388607 @ 0x7fffff
251 ; V6-LABEL: unsigned_sat_upper_lower_2:
252 ; V6: @ %bb.0: @ %entry
253 ; V6-NEXT: usat r0, #23, r0
256 ; V6T2-LABEL: unsigned_sat_upper_lower_2:
257 ; V6T2: @ %bb.0: @ %entry
258 ; V6T2-NEXT: usat r0, #23, r0
261 %0 = icmp sgt i32 %x, 0
262 %saturateLow = select i1 %0, i32 %x, i32 0
263 %1 = icmp slt i32 %saturateLow, 8388607
264 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
268 ; k < x ? k : (x > 0 ? x : 0)
269 define i32 @unsigned_sat_upper_lower_3(i32 %x) #0 {
270 ; V4T-LABEL: unsigned_sat_upper_lower_3:
271 ; V4T: @ %bb.0: @ %entry
272 ; V4T-NEXT: bic r1, r0, r0, asr #31
273 ; V4T-NEXT: ldr r0, .LCPI7_0
274 ; V4T-NEXT: cmp r1, r0
275 ; V4T-NEXT: movlt r0, r1
277 ; V4T-NEXT: .p2align 2
279 ; V4T-NEXT: .LCPI7_0:
280 ; V4T-NEXT: .long 8388607 @ 0x7fffff
282 ; V6-LABEL: unsigned_sat_upper_lower_3:
283 ; V6: @ %bb.0: @ %entry
284 ; V6-NEXT: usat r0, #23, r0
287 ; V6T2-LABEL: unsigned_sat_upper_lower_3:
288 ; V6T2: @ %bb.0: @ %entry
289 ; V6T2-NEXT: usat r0, #23, r0
292 %cmpLow = icmp sgt i32 %x, 0
293 %saturateLow = select i1 %cmpLow, i32 %x, i32 0
294 %0 = icmp slt i32 %saturateLow, 8388607
295 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607
300 ; The following tests check for patterns that should not transform
301 ; into USAT but are similar enough that could confuse the selector.
303 ; x > k ? k : (x > 0 ? 0 : x)
304 ; First condition upper-saturates, second doesn't lower-saturate.
305 define i32 @no_unsigned_sat_missing_lower(i32 %x) #0 {
306 ; V4T-LABEL: no_unsigned_sat_missing_lower:
307 ; V4T: @ %bb.0: @ %entry
308 ; V4T-NEXT: ldr r1, .LCPI8_0
309 ; V4T-NEXT: cmp r0, #8388608
310 ; V4T-NEXT: andlt r1, r0, r0, asr #31
311 ; V4T-NEXT: mov r0, r1
313 ; V4T-NEXT: .p2align 2
315 ; V4T-NEXT: .LCPI8_0:
316 ; V4T-NEXT: .long 8388607 @ 0x7fffff
318 ; V6-LABEL: no_unsigned_sat_missing_lower:
319 ; V6: @ %bb.0: @ %entry
320 ; V6-NEXT: ldr r1, .LCPI8_0
321 ; V6-NEXT: cmp r0, #8388608
322 ; V6-NEXT: andlt r1, r0, r0, asr #31
323 ; V6-NEXT: mov r0, r1
325 ; V6-NEXT: .p2align 2
328 ; V6-NEXT: .long 8388607 @ 0x7fffff
330 ; V6T2-LABEL: no_unsigned_sat_missing_lower:
331 ; V6T2: @ %bb.0: @ %entry
332 ; V6T2-NEXT: and r1, r0, r0, asr #31
333 ; V6T2-NEXT: cmp r0, #8388608
334 ; V6T2-NEXT: movwge r1, #65535
335 ; V6T2-NEXT: movtge r1, #127
336 ; V6T2-NEXT: mov r0, r1
339 %cmpUp = icmp sgt i32 %x, 8388607
340 %0 = icmp slt i32 %x, 0
341 %saturateLow = select i1 %0, i32 %x, i32 0
342 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
346 ; x < k ? k : (x < 0 ? 0 : x)
347 ; Second condition lower-saturates, first doesn't upper-saturate.
348 define i32 @no_unsigned_sat_missing_upper(i32 %x) #0 {
349 ; V4T-LABEL: no_unsigned_sat_missing_upper:
350 ; V4T: @ %bb.0: @ %entry
351 ; V4T-NEXT: ldr r1, .LCPI9_0
352 ; V4T-NEXT: cmp r0, r1
353 ; V4T-NEXT: bicge r1, r0, r0, asr #31
354 ; V4T-NEXT: mov r0, r1
356 ; V4T-NEXT: .p2align 2
358 ; V4T-NEXT: .LCPI9_0:
359 ; V4T-NEXT: .long 8388607 @ 0x7fffff
361 ; V6-LABEL: no_unsigned_sat_missing_upper:
362 ; V6: @ %bb.0: @ %entry
363 ; V6-NEXT: ldr r1, .LCPI9_0
364 ; V6-NEXT: cmp r0, r1
365 ; V6-NEXT: bicge r1, r0, r0, asr #31
366 ; V6-NEXT: mov r0, r1
368 ; V6-NEXT: .p2align 2
371 ; V6-NEXT: .long 8388607 @ 0x7fffff
373 ; V6T2-LABEL: no_unsigned_sat_missing_upper:
374 ; V6T2: @ %bb.0: @ %entry
375 ; V6T2-NEXT: movw r2, #65535
376 ; V6T2-NEXT: bic r1, r0, r0, asr #31
377 ; V6T2-NEXT: movt r2, #127
378 ; V6T2-NEXT: cmp r0, r2
379 ; V6T2-NEXT: movwlt r1, #65535
380 ; V6T2-NEXT: movtlt r1, #127
381 ; V6T2-NEXT: mov r0, r1
384 %cmpUp = icmp slt i32 %x, 8388607
385 %0 = icmp sgt i32 %x, 0
386 %saturateLow = select i1 %0, i32 %x, i32 0
387 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
391 ; Lower constant is different in the select and in the compare
392 define i32 @no_unsigned_sat_incorrect_constant(i32 %x) #0 {
393 ; V4T-LABEL: no_unsigned_sat_incorrect_constant:
394 ; V4T: @ %bb.0: @ %entry
395 ; V4T-NEXT: orr r1, r0, r0, asr #31
396 ; V4T-NEXT: ldr r0, .LCPI10_0
397 ; V4T-NEXT: cmp r1, r0
398 ; V4T-NEXT: movlt r0, r1
400 ; V4T-NEXT: .p2align 2
402 ; V4T-NEXT: .LCPI10_0:
403 ; V4T-NEXT: .long 8388607 @ 0x7fffff
405 ; V6-LABEL: no_unsigned_sat_incorrect_constant:
406 ; V6: @ %bb.0: @ %entry
407 ; V6-NEXT: orr r1, r0, r0, asr #31
408 ; V6-NEXT: ldr r0, .LCPI10_0
409 ; V6-NEXT: cmp r1, r0
410 ; V6-NEXT: movlt r0, r1
412 ; V6-NEXT: .p2align 2
414 ; V6-NEXT: .LCPI10_0:
415 ; V6-NEXT: .long 8388607 @ 0x7fffff
417 ; V6T2-LABEL: no_unsigned_sat_incorrect_constant:
418 ; V6T2: @ %bb.0: @ %entry
419 ; V6T2-NEXT: orr r1, r0, r0, asr #31
420 ; V6T2-NEXT: movw r0, #65535
421 ; V6T2-NEXT: movt r0, #127
422 ; V6T2-NEXT: cmp r1, r0
423 ; V6T2-NEXT: movlt r0, r1
426 %cmpLow.inv = icmp sgt i32 %x, -1
427 %saturateLow = select i1 %cmpLow.inv, i32 %x, i32 -1
428 %0 = icmp slt i32 %saturateLow, 8388607
429 %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607
433 ; The interval is [0, k] but k+1 is not a power of 2
434 define i32 @no_unsigned_sat_incorrect_constant2(i32 %x) #0 {
435 ; V4T-LABEL: no_unsigned_sat_incorrect_constant2:
436 ; V4T: @ %bb.0: @ %entry
437 ; V4T-NEXT: bic r1, r0, r0, asr #31
438 ; V4T-NEXT: mov r0, #1
439 ; V4T-NEXT: orr r0, r0, #8388608
440 ; V4T-NEXT: cmp r1, #8388608
441 ; V4T-NEXT: movle r0, r1
444 ; V6-LABEL: no_unsigned_sat_incorrect_constant2:
445 ; V6: @ %bb.0: @ %entry
446 ; V6-NEXT: bic r1, r0, r0, asr #31
447 ; V6-NEXT: mov r0, #1
448 ; V6-NEXT: orr r0, r0, #8388608
449 ; V6-NEXT: cmp r1, #8388608
450 ; V6-NEXT: movle r0, r1
453 ; V6T2-LABEL: no_unsigned_sat_incorrect_constant2:
454 ; V6T2: @ %bb.0: @ %entry
455 ; V6T2-NEXT: bic r1, r0, r0, asr #31
456 ; V6T2-NEXT: movw r0, #1
457 ; V6T2-NEXT: movt r0, #128
458 ; V6T2-NEXT: cmp r1, #8388608
459 ; V6T2-NEXT: movle r0, r1
462 %0 = icmp sgt i32 %x, 0
463 %saturateLow = select i1 %0, i32 %x, i32 0
464 %1 = icmp slt i32 %saturateLow, 8388609
465 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388609
469 ; The interval is not [0, k]
470 define i32 @no_unsigned_sat_incorrect_interval(i32 %x) #0 {
471 ; V4T-LABEL: no_unsigned_sat_incorrect_interval:
472 ; V4T: @ %bb.0: @ %entry
473 ; V4T-NEXT: ldr r1, .LCPI12_0
474 ; V4T-NEXT: cmn r0, #4
475 ; V4T-NEXT: mvnle r0, #3
476 ; V4T-NEXT: cmp r0, r1
477 ; V4T-NEXT: movge r0, r1
479 ; V4T-NEXT: .p2align 2
481 ; V4T-NEXT: .LCPI12_0:
482 ; V4T-NEXT: .long 8388607 @ 0x7fffff
484 ; V6-LABEL: no_unsigned_sat_incorrect_interval:
485 ; V6: @ %bb.0: @ %entry
486 ; V6-NEXT: ldr r1, .LCPI12_0
487 ; V6-NEXT: cmn r0, #4
488 ; V6-NEXT: mvnle r0, #3
489 ; V6-NEXT: cmp r0, r1
490 ; V6-NEXT: movge r0, r1
492 ; V6-NEXT: .p2align 2
494 ; V6-NEXT: .LCPI12_0:
495 ; V6-NEXT: .long 8388607 @ 0x7fffff
497 ; V6T2-LABEL: no_unsigned_sat_incorrect_interval:
498 ; V6T2: @ %bb.0: @ %entry
499 ; V6T2-NEXT: cmn r0, #4
500 ; V6T2-NEXT: movw r1, #65535
501 ; V6T2-NEXT: mvnle r0, #3
502 ; V6T2-NEXT: movt r1, #127
503 ; V6T2-NEXT: cmp r0, r1
504 ; V6T2-NEXT: movge r0, r1
507 %0 = icmp sgt i32 %x, -4
508 %saturateLow = select i1 %0, i32 %x, i32 -4
509 %1 = icmp slt i32 %saturateLow, 8388607
510 %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
514 ; The returned value (y) is not the same as the tested value (x).
515 define i32 @no_unsigned_sat_incorrect_return(i32 %x, i32 %y) #0 {
516 ; V4T-LABEL: no_unsigned_sat_incorrect_return:
517 ; V4T: @ %bb.0: @ %entry
518 ; V4T-NEXT: cmp r0, #0
519 ; V4T-NEXT: ldr r2, .LCPI13_0
520 ; V4T-NEXT: movmi r1, #0
521 ; V4T-NEXT: cmp r0, #8388608
522 ; V4T-NEXT: movlt r2, r1
523 ; V4T-NEXT: mov r0, r2
525 ; V4T-NEXT: .p2align 2
527 ; V4T-NEXT: .LCPI13_0:
528 ; V4T-NEXT: .long 8388607 @ 0x7fffff
530 ; V6-LABEL: no_unsigned_sat_incorrect_return:
531 ; V6: @ %bb.0: @ %entry
532 ; V6-NEXT: cmp r0, #0
533 ; V6-NEXT: ldr r2, .LCPI13_0
534 ; V6-NEXT: movmi r1, #0
535 ; V6-NEXT: cmp r0, #8388608
536 ; V6-NEXT: movlt r2, r1
537 ; V6-NEXT: mov r0, r2
539 ; V6-NEXT: .p2align 2
541 ; V6-NEXT: .LCPI13_0:
542 ; V6-NEXT: .long 8388607 @ 0x7fffff
544 ; V6T2-LABEL: no_unsigned_sat_incorrect_return:
545 ; V6T2: @ %bb.0: @ %entry
546 ; V6T2-NEXT: cmp r0, #0
547 ; V6T2-NEXT: movwmi r1, #0
548 ; V6T2-NEXT: cmp r0, #8388608
549 ; V6T2-NEXT: movwge r1, #65535
550 ; V6T2-NEXT: movtge r1, #127
551 ; V6T2-NEXT: mov r0, r1
554 %cmpUp = icmp sgt i32 %x, 8388607
555 %cmpLow = icmp slt i32 %x, 0
556 %saturateLow = select i1 %cmpLow, i32 0, i32 %y
557 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
561 ; One of the values in a compare (y) is not the same as the rest
562 ; of the compare and select values (x).
563 define i32 @no_unsigned_sat_incorrect_compare(i32 %x, i32 %y) #0 {
564 ; V4T-LABEL: no_unsigned_sat_incorrect_compare:
565 ; V4T: @ %bb.0: @ %entry
566 ; V4T-NEXT: cmp r1, #0
567 ; V4T-NEXT: mov r2, r0
568 ; V4T-NEXT: movmi r2, #0
569 ; V4T-NEXT: ldr r1, .LCPI14_0
570 ; V4T-NEXT: cmp r0, #8388608
571 ; V4T-NEXT: movlt r1, r2
572 ; V4T-NEXT: mov r0, r1
574 ; V4T-NEXT: .p2align 2
576 ; V4T-NEXT: .LCPI14_0:
577 ; V4T-NEXT: .long 8388607 @ 0x7fffff
579 ; V6-LABEL: no_unsigned_sat_incorrect_compare:
580 ; V6: @ %bb.0: @ %entry
581 ; V6-NEXT: cmp r1, #0
582 ; V6-NEXT: mov r2, r0
583 ; V6-NEXT: movmi r2, #0
584 ; V6-NEXT: ldr r1, .LCPI14_0
585 ; V6-NEXT: cmp r0, #8388608
586 ; V6-NEXT: movlt r1, r2
587 ; V6-NEXT: mov r0, r1
589 ; V6-NEXT: .p2align 2
591 ; V6-NEXT: .LCPI14_0:
592 ; V6-NEXT: .long 8388607 @ 0x7fffff
594 ; V6T2-LABEL: no_unsigned_sat_incorrect_compare:
595 ; V6T2: @ %bb.0: @ %entry
596 ; V6T2-NEXT: cmp r1, #0
597 ; V6T2-NEXT: mov r1, r0
598 ; V6T2-NEXT: movwmi r1, #0
599 ; V6T2-NEXT: cmp r0, #8388608
600 ; V6T2-NEXT: movwge r1, #65535
601 ; V6T2-NEXT: movtge r1, #127
602 ; V6T2-NEXT: mov r0, r1
605 %cmpUp = icmp sgt i32 %x, 8388607
606 %cmpLow = icmp slt i32 %y, 0
607 %saturateLow = select i1 %cmpLow, i32 0, i32 %x
608 %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
612 define i32 @mm_unsigned_sat_base_32bit(i32 %x) {
613 ; V4T-LABEL: mm_unsigned_sat_base_32bit:
614 ; V4T: @ %bb.0: @ %entry
615 ; V4T-NEXT: ldr r1, .LCPI15_0
616 ; V4T-NEXT: cmp r0, r1
617 ; V4T-NEXT: movlt r1, r0
618 ; V4T-NEXT: bic r0, r1, r1, asr #31
620 ; V4T-NEXT: .p2align 2
622 ; V4T-NEXT: .LCPI15_0:
623 ; V4T-NEXT: .long 8388607 @ 0x7fffff
625 ; V6-LABEL: mm_unsigned_sat_base_32bit:
626 ; V6: @ %bb.0: @ %entry
627 ; V6-NEXT: usat r0, #23, r0
630 ; V6T2-LABEL: mm_unsigned_sat_base_32bit:
631 ; V6T2: @ %bb.0: @ %entry
632 ; V6T2-NEXT: usat r0, #23, r0
635 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)
636 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)
640 define i16 @mm_unsigned_sat_base_16bit(i16 %x) {
641 ; V4T-LABEL: mm_unsigned_sat_base_16bit:
642 ; V4T: @ %bb.0: @ %entry
643 ; V4T-NEXT: mov r2, #255
644 ; V4T-NEXT: lsl r0, r0, #16
645 ; V4T-NEXT: orr r2, r2, #1792
646 ; V4T-NEXT: asr r1, r0, #16
647 ; V4T-NEXT: cmp r1, r2
648 ; V4T-NEXT: asrlt r2, r0, #16
649 ; V4T-NEXT: bic r0, r2, r2, asr #31
652 ; V6-LABEL: mm_unsigned_sat_base_16bit:
653 ; V6: @ %bb.0: @ %entry
654 ; V6-NEXT: sxth r0, r0
655 ; V6-NEXT: usat r0, #11, r0
658 ; V6T2-LABEL: mm_unsigned_sat_base_16bit:
659 ; V6T2: @ %bb.0: @ %entry
660 ; V6T2-NEXT: sxth r0, r0
661 ; V6T2-NEXT: usat r0, #11, r0
664 %0 = call i16 @llvm.smin.i16(i16 %x, i16 2047)
665 %1 = call i16 @llvm.smax.i16(i16 %0, i16 0)
669 define i8 @mm_unsigned_sat_base_8bit(i8 %x) {
670 ; V4T-LABEL: mm_unsigned_sat_base_8bit:
671 ; V4T: @ %bb.0: @ %entry
672 ; V4T-NEXT: lsl r0, r0, #24
673 ; V4T-NEXT: mov r2, #31
674 ; V4T-NEXT: asr r1, r0, #24
675 ; V4T-NEXT: cmp r1, #31
676 ; V4T-NEXT: asrlt r2, r0, #24
677 ; V4T-NEXT: bic r0, r2, r2, asr #31
680 ; V6-LABEL: mm_unsigned_sat_base_8bit:
681 ; V6: @ %bb.0: @ %entry
682 ; V6-NEXT: sxtb r0, r0
683 ; V6-NEXT: usat r0, #5, r0
686 ; V6T2-LABEL: mm_unsigned_sat_base_8bit:
687 ; V6T2: @ %bb.0: @ %entry
688 ; V6T2-NEXT: sxtb r0, r0
689 ; V6T2-NEXT: usat r0, #5, r0
692 %0 = call i8 @llvm.smin.i8(i8 %x, i8 31)
693 %1 = call i8 @llvm.smax.i8(i8 %0, i8 0)
697 define i32 @mm_unsigned_sat_lower_upper_1(i32 %x) {
698 ; V4T-LABEL: mm_unsigned_sat_lower_upper_1:
699 ; V4T: @ %bb.0: @ %entry
700 ; V4T-NEXT: ldr r1, .LCPI18_0
701 ; V4T-NEXT: cmp r0, r1
702 ; V4T-NEXT: movlt r1, r0
703 ; V4T-NEXT: bic r0, r1, r1, asr #31
705 ; V4T-NEXT: .p2align 2
707 ; V4T-NEXT: .LCPI18_0:
708 ; V4T-NEXT: .long 8388607 @ 0x7fffff
710 ; V6-LABEL: mm_unsigned_sat_lower_upper_1:
711 ; V6: @ %bb.0: @ %entry
712 ; V6-NEXT: usat r0, #23, r0
715 ; V6T2-LABEL: mm_unsigned_sat_lower_upper_1:
716 ; V6T2: @ %bb.0: @ %entry
717 ; V6T2-NEXT: usat r0, #23, r0
720 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)
721 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)
725 define i32 @mm_unsigned_sat_lower_upper_2(i32 %x) {
726 ; V4T-LABEL: mm_unsigned_sat_lower_upper_2:
727 ; V4T: @ %bb.0: @ %entry
728 ; V4T-NEXT: ldr r1, .LCPI19_0
729 ; V4T-NEXT: cmp r0, r1
730 ; V4T-NEXT: movlt r1, r0
731 ; V4T-NEXT: bic r0, r1, r1, asr #31
733 ; V4T-NEXT: .p2align 2
735 ; V4T-NEXT: .LCPI19_0:
736 ; V4T-NEXT: .long 8388607 @ 0x7fffff
738 ; V6-LABEL: mm_unsigned_sat_lower_upper_2:
739 ; V6: @ %bb.0: @ %entry
740 ; V6-NEXT: usat r0, #23, r0
743 ; V6T2-LABEL: mm_unsigned_sat_lower_upper_2:
744 ; V6T2: @ %bb.0: @ %entry
745 ; V6T2-NEXT: usat r0, #23, r0
748 %0 = call i32 @llvm.smin.i32(i32 %x, i32 8388607)
749 %1 = call i32 @llvm.smax.i32(i32 %0, i32 0)
753 define i32 @mm_unsigned_sat_upper_lower_1(i32 %x) {
754 ; V4T-LABEL: mm_unsigned_sat_upper_lower_1:
755 ; V4T: @ %bb.0: @ %entry
756 ; V4T-NEXT: bic r1, r0, r0, asr #31
757 ; V4T-NEXT: ldr r0, .LCPI20_0
758 ; V4T-NEXT: cmp r1, r0
759 ; V4T-NEXT: movlt r0, r1
761 ; V4T-NEXT: .p2align 2
763 ; V4T-NEXT: .LCPI20_0:
764 ; V4T-NEXT: .long 8388607 @ 0x7fffff
766 ; V6-LABEL: mm_unsigned_sat_upper_lower_1:
767 ; V6: @ %bb.0: @ %entry
768 ; V6-NEXT: usat r0, #23, r0
771 ; V6T2-LABEL: mm_unsigned_sat_upper_lower_1:
772 ; V6T2: @ %bb.0: @ %entry
773 ; V6T2-NEXT: usat r0, #23, r0
776 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)
777 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)
781 define i32 @mm_unsigned_sat_upper_lower_2(i32 %x) {
782 ; V4T-LABEL: mm_unsigned_sat_upper_lower_2:
783 ; V4T: @ %bb.0: @ %entry
784 ; V4T-NEXT: bic r1, r0, r0, asr #31
785 ; V4T-NEXT: ldr r0, .LCPI21_0
786 ; V4T-NEXT: cmp r1, r0
787 ; V4T-NEXT: movlt r0, r1
789 ; V4T-NEXT: .p2align 2
791 ; V4T-NEXT: .LCPI21_0:
792 ; V4T-NEXT: .long 8388607 @ 0x7fffff
794 ; V6-LABEL: mm_unsigned_sat_upper_lower_2:
795 ; V6: @ %bb.0: @ %entry
796 ; V6-NEXT: usat r0, #23, r0
799 ; V6T2-LABEL: mm_unsigned_sat_upper_lower_2:
800 ; V6T2: @ %bb.0: @ %entry
801 ; V6T2-NEXT: usat r0, #23, r0
804 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)
805 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)
809 define i32 @mm_unsigned_sat_upper_lower_3(i32 %x) {
810 ; V4T-LABEL: mm_unsigned_sat_upper_lower_3:
811 ; V4T: @ %bb.0: @ %entry
812 ; V4T-NEXT: bic r1, r0, r0, asr #31
813 ; V4T-NEXT: ldr r0, .LCPI22_0
814 ; V4T-NEXT: cmp r1, r0
815 ; V4T-NEXT: movlt r0, r1
817 ; V4T-NEXT: .p2align 2
819 ; V4T-NEXT: .LCPI22_0:
820 ; V4T-NEXT: .long 8388607 @ 0x7fffff
822 ; V6-LABEL: mm_unsigned_sat_upper_lower_3:
823 ; V6: @ %bb.0: @ %entry
824 ; V6-NEXT: usat r0, #23, r0
827 ; V6T2-LABEL: mm_unsigned_sat_upper_lower_3:
828 ; V6T2: @ %bb.0: @ %entry
829 ; V6T2-NEXT: usat r0, #23, r0
832 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)
833 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388607)
837 define i32 @mm_no_unsigned_sat_incorrect_constant(i32 %x) {
838 ; V4T-LABEL: mm_no_unsigned_sat_incorrect_constant:
839 ; V4T: @ %bb.0: @ %entry
840 ; V4T-NEXT: orr r1, r0, r0, asr #31
841 ; V4T-NEXT: ldr r0, .LCPI23_0
842 ; V4T-NEXT: cmp r1, r0
843 ; V4T-NEXT: movlt r0, r1
845 ; V4T-NEXT: .p2align 2
847 ; V4T-NEXT: .LCPI23_0:
848 ; V4T-NEXT: .long 8388607 @ 0x7fffff
850 ; V6-LABEL: mm_no_unsigned_sat_incorrect_constant:
851 ; V6: @ %bb.0: @ %entry
852 ; V6-NEXT: orr r1, r0, r0, asr #31
853 ; V6-NEXT: ldr r0, .LCPI23_0
854 ; V6-NEXT: cmp r1, r0
855 ; V6-NEXT: movlt r0, r1
857 ; V6-NEXT: .p2align 2
859 ; V6-NEXT: .LCPI23_0:
860 ; V6-NEXT: .long 8388607 @ 0x7fffff
862 ; V6T2-LABEL: mm_no_unsigned_sat_incorrect_constant:
863 ; V6T2: @ %bb.0: @ %entry
864 ; V6T2-NEXT: orr r1, r0, r0, asr #31
865 ; V6T2-NEXT: movw r0, #65535
866 ; V6T2-NEXT: movt r0, #127
867 ; V6T2-NEXT: cmp r1, r0
868 ; V6T2-NEXT: movlt r0, r1
871 %0 = call i32 @llvm.smax.i32(i32 %x, i32 -1)
872 %1 = call i32 @llvm.smin.i32(i32 %0, i32 8388607)
876 define i32 @mm_no_unsigned_sat_incorrect_constant2(i32 %x) {
877 ; V4T-LABEL: mm_no_unsigned_sat_incorrect_constant2:
878 ; V4T: @ %bb.0: @ %entry
879 ; V4T-NEXT: bic r1, r0, r0, asr #31
880 ; V4T-NEXT: mov r0, #1
881 ; V4T-NEXT: orr r0, r0, #8388608
882 ; V4T-NEXT: cmp r1, #8388608
883 ; V4T-NEXT: movle r0, r1
886 ; V6-LABEL: mm_no_unsigned_sat_incorrect_constant2:
887 ; V6: @ %bb.0: @ %entry
888 ; V6-NEXT: bic r1, r0, r0, asr #31
889 ; V6-NEXT: mov r0, #1
890 ; V6-NEXT: orr r0, r0, #8388608
891 ; V6-NEXT: cmp r1, #8388608
892 ; V6-NEXT: movle r0, r1
895 ; V6T2-LABEL: mm_no_unsigned_sat_incorrect_constant2:
896 ; V6T2: @ %bb.0: @ %entry
897 ; V6T2-NEXT: bic r1, r0, r0, asr #31
898 ; V6T2-NEXT: movw r0, #1
899 ; V6T2-NEXT: movt r0, #128
900 ; V6T2-NEXT: cmp r1, #8388608
901 ; V6T2-NEXT: movle r0, r1
904 %0 = call i32 @llvm.smax.i32(i32 %x, i32 0)
905 %1 = call i32 @llvm.umin.i32(i32 %0, i32 8388609)
909 define i32 @mm_no_unsigned_sat_incorrect_interval(i32 %x) {
910 ; V4T-LABEL: mm_no_unsigned_sat_incorrect_interval:
911 ; V4T: @ %bb.0: @ %entry
912 ; V4T-NEXT: ldr r1, .LCPI25_0
913 ; V4T-NEXT: cmn r0, #4
914 ; V4T-NEXT: mvnle r0, #3
915 ; V4T-NEXT: cmp r0, r1
916 ; V4T-NEXT: movge r0, r1
918 ; V4T-NEXT: .p2align 2
920 ; V4T-NEXT: .LCPI25_0:
921 ; V4T-NEXT: .long 8388607 @ 0x7fffff
923 ; V6-LABEL: mm_no_unsigned_sat_incorrect_interval:
924 ; V6: @ %bb.0: @ %entry
925 ; V6-NEXT: ldr r1, .LCPI25_0
926 ; V6-NEXT: cmn r0, #4
927 ; V6-NEXT: mvnle r0, #3
928 ; V6-NEXT: cmp r0, r1
929 ; V6-NEXT: movge r0, r1
931 ; V6-NEXT: .p2align 2
933 ; V6-NEXT: .LCPI25_0:
934 ; V6-NEXT: .long 8388607 @ 0x7fffff
936 ; V6T2-LABEL: mm_no_unsigned_sat_incorrect_interval:
937 ; V6T2: @ %bb.0: @ %entry
938 ; V6T2-NEXT: cmn r0, #4
939 ; V6T2-NEXT: movw r1, #65535
940 ; V6T2-NEXT: mvnle r0, #3
941 ; V6T2-NEXT: movt r1, #127
942 ; V6T2-NEXT: cmp r0, r1
943 ; V6T2-NEXT: movge r0, r1
946 %0 = call i32 @llvm.smax.i32(i32 %x, i32 -4)
947 %1 = call i32 @llvm.smin.i32(i32 %0, i32 8388607)
951 define i32 @test_umin_smax_usat(i32 %x) {
952 ; V4T-LABEL: test_umin_smax_usat:
953 ; V4T: @ %bb.0: @ %entry
954 ; V4T-NEXT: bic r0, r0, r0, asr #31
955 ; V4T-NEXT: cmp r0, #255
956 ; V4T-NEXT: movge r0, #255
959 ; V6-LABEL: test_umin_smax_usat:
960 ; V6: @ %bb.0: @ %entry
961 ; V6-NEXT: usat r0, #8, r0
964 ; V6T2-LABEL: test_umin_smax_usat:
965 ; V6T2: @ %bb.0: @ %entry
966 ; V6T2-NEXT: usat r0, #8, r0
969 %v1 = tail call i32 @llvm.smax.i32(i32 %x, i32 0)
970 %v2 = tail call i32 @llvm.umin.i32(i32 %v1, i32 255)
974 declare i32 @llvm.smin.i32(i32, i32)
975 declare i32 @llvm.smax.i32(i32, i32)
976 declare i16 @llvm.smin.i16(i16, i16)
977 declare i16 @llvm.smax.i16(i16, i16)
978 declare i8 @llvm.smin.i8(i8, i8)
979 declare i8 @llvm.smax.i8(i8, i8)
980 declare i32 @llvm.umin.i32(i32, i32)