[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / CodeGen / ARM / usat.ll
blobdd0eca823a502e2702ff382e6f39a6a65c290a18
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)
19 ; 32-bit base test
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
27 ; V4T-NEXT:    bx lr
28 ; V4T-NEXT:    .p2align 2
29 ; V4T-NEXT:  @ %bb.1:
30 ; V4T-NEXT:  .LCPI0_0:
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
36 ; V6-NEXT:    bx lr
38 ; V6T2-LABEL: unsigned_sat_base_32bit:
39 ; V6T2:       @ %bb.0: @ %entry
40 ; V6T2-NEXT:    usat r0, #23, r0
41 ; V6T2-NEXT:    bx lr
42 entry:
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
47   ret i32 %saturateLow
50 ; x < 0 ? 0 : (x > k ? k : x)
51 ; 16-bit base test
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:    lsl r1, r0, #16
56 ; V4T-NEXT:    asr r2, r1, #16
57 ; V4T-NEXT:    mov r1, #255
58 ; V4T-NEXT:    orr r1, r1, #1792
59 ; V4T-NEXT:    cmp r2, r1
60 ; V4T-NEXT:    movlt r1, r0
61 ; V4T-NEXT:    lsl r0, r1, #16
62 ; V4T-NEXT:    asr r0, r0, #16
63 ; V4T-NEXT:    cmp r0, #0
64 ; V4T-NEXT:    movle r1, #0
65 ; V4T-NEXT:    mov r0, r1
66 ; V4T-NEXT:    bx lr
68 ; V6-LABEL: unsigned_sat_base_16bit:
69 ; V6:       @ %bb.0: @ %entry
70 ; V6-NEXT:    mov r1, #255
71 ; V6-NEXT:    sxth r2, r0
72 ; V6-NEXT:    orr r1, r1, #1792
73 ; V6-NEXT:    cmp r2, r1
74 ; V6-NEXT:    movlt r1, r0
75 ; V6-NEXT:    sxth r0, r1
76 ; V6-NEXT:    cmp r0, #0
77 ; V6-NEXT:    movle r1, #0
78 ; V6-NEXT:    mov r0, r1
79 ; V6-NEXT:    bx lr
81 ; V6T2-LABEL: unsigned_sat_base_16bit:
82 ; V6T2:       @ %bb.0: @ %entry
83 ; V6T2-NEXT:    sxth r2, r0
84 ; V6T2-NEXT:    movw r1, #2047
85 ; V6T2-NEXT:    cmp r2, r1
86 ; V6T2-NEXT:    movlt r1, r0
87 ; V6T2-NEXT:    sxth r0, r1
88 ; V6T2-NEXT:    cmp r0, #0
89 ; V6T2-NEXT:    movle r1, #0
90 ; V6T2-NEXT:    mov r0, r1
91 ; V6T2-NEXT:    bx lr
92 entry:
93   %0 = icmp slt i16 %x, 2047
94   %saturateUp = select i1 %0, i16 %x, i16 2047
95   %1 = icmp sgt i16 %saturateUp, 0
96   %saturateLow = select i1 %1, i16 %saturateUp, i16 0
97   ret i16 %saturateLow
100 ; x < 0 ? 0 : (x > k ? k : x)
101 ; 8-bit base test
102 define i8 @unsigned_sat_base_8bit(i8 %x) #0 {
103 ; V4T-LABEL: unsigned_sat_base_8bit:
104 ; V4T:       @ %bb.0: @ %entry
105 ; V4T-NEXT:    lsl r1, r0, #24
106 ; V4T-NEXT:    asr r1, r1, #24
107 ; V4T-NEXT:    cmp r1, #31
108 ; V4T-NEXT:    movge r0, #31
109 ; V4T-NEXT:    lsl r1, r0, #24
110 ; V4T-NEXT:    asr r1, r1, #24
111 ; V4T-NEXT:    cmp r1, #0
112 ; V4T-NEXT:    movle r0, #0
113 ; V4T-NEXT:    bx lr
115 ; V6-LABEL: unsigned_sat_base_8bit:
116 ; V6:       @ %bb.0: @ %entry
117 ; V6-NEXT:    sxtb r1, r0
118 ; V6-NEXT:    cmp r1, #31
119 ; V6-NEXT:    movge r0, #31
120 ; V6-NEXT:    sxtb r1, r0
121 ; V6-NEXT:    cmp r1, #0
122 ; V6-NEXT:    movle r0, #0
123 ; V6-NEXT:    bx lr
125 ; V6T2-LABEL: unsigned_sat_base_8bit:
126 ; V6T2:       @ %bb.0: @ %entry
127 ; V6T2-NEXT:    sxtb r1, r0
128 ; V6T2-NEXT:    cmp r1, #31
129 ; V6T2-NEXT:    movge r0, #31
130 ; V6T2-NEXT:    sxtb r1, r0
131 ; V6T2-NEXT:    cmp r1, #0
132 ; V6T2-NEXT:    movle r0, #0
133 ; V6T2-NEXT:    bx lr
134 entry:
135   %0 = icmp slt i8 %x, 31
136   %saturateUp = select i1 %0, i8 %x, i8 31
137   %1 = icmp sgt i8 %saturateUp, 0
138   %saturateLow = select i1 %1, i8 %saturateUp, i8 0
139   ret i8 %saturateLow
143 ; Tests where the conditionals that check for upper and lower bounds,
144 ; or the < and > operators, are arranged in different ways. Only some
145 ; of the possible combinations that lead to USAT are tested.
147 ; x < 0 ? 0 : (x < k ? x : k)
148 define i32 @unsigned_sat_lower_upper_1(i32 %x) #0 {
149 ; V4T-LABEL: unsigned_sat_lower_upper_1:
150 ; V4T:       @ %bb.0: @ %entry
151 ; V4T-NEXT:    ldr r1, .LCPI3_0
152 ; V4T-NEXT:    cmp r0, r1
153 ; V4T-NEXT:    movlt r1, r0
154 ; V4T-NEXT:    bic r0, r1, r1, asr #31
155 ; V4T-NEXT:    bx lr
156 ; V4T-NEXT:    .p2align 2
157 ; V4T-NEXT:  @ %bb.1:
158 ; V4T-NEXT:  .LCPI3_0:
159 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
161 ; V6-LABEL: unsigned_sat_lower_upper_1:
162 ; V6:       @ %bb.0: @ %entry
163 ; V6-NEXT:    usat r0, #23, r0
164 ; V6-NEXT:    bx lr
166 ; V6T2-LABEL: unsigned_sat_lower_upper_1:
167 ; V6T2:       @ %bb.0: @ %entry
168 ; V6T2-NEXT:    usat r0, #23, r0
169 ; V6T2-NEXT:    bx lr
170 entry:
171   %cmpUp = icmp slt i32 %x, 8388607
172   %saturateUp = select i1 %cmpUp, i32 %x, i32 8388607
173   %0 = icmp sgt i32 %saturateUp, 0
174   %saturateLow = select i1 %0, i32 %saturateUp, i32 0
175   ret i32 %saturateLow
178 ; x > 0 ? (x > k ? k : x) : 0
179 define i32 @unsigned_sat_lower_upper_2(i32 %x) #0 {
180 ; V4T-LABEL: unsigned_sat_lower_upper_2:
181 ; V4T:       @ %bb.0: @ %entry
182 ; V4T-NEXT:    ldr r1, .LCPI4_0
183 ; V4T-NEXT:    cmp r0, r1
184 ; V4T-NEXT:    movlt r1, r0
185 ; V4T-NEXT:    bic r0, r1, r1, asr #31
186 ; V4T-NEXT:    bx lr
187 ; V4T-NEXT:    .p2align 2
188 ; V4T-NEXT:  @ %bb.1:
189 ; V4T-NEXT:  .LCPI4_0:
190 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
192 ; V6-LABEL: unsigned_sat_lower_upper_2:
193 ; V6:       @ %bb.0: @ %entry
194 ; V6-NEXT:    usat r0, #23, r0
195 ; V6-NEXT:    bx lr
197 ; V6T2-LABEL: unsigned_sat_lower_upper_2:
198 ; V6T2:       @ %bb.0: @ %entry
199 ; V6T2-NEXT:    usat r0, #23, r0
200 ; V6T2-NEXT:    bx lr
201 entry:
202   %0 = icmp slt i32 %x, 8388607
203   %saturateUp = select i1 %0, i32 %x, i32 8388607
204   %1 = icmp sgt i32 %saturateUp, 0
205   %saturateLow = select i1 %1, i32 %saturateUp, i32 0
206   ret i32 %saturateLow
209 ; x < k ? (x < 0 ? 0 : x) : k
210 define i32 @unsigned_sat_upper_lower_1(i32 %x) #0 {
211 ; V4T-LABEL: unsigned_sat_upper_lower_1:
212 ; V4T:       @ %bb.0: @ %entry
213 ; V4T-NEXT:    bic r1, r0, r0, asr #31
214 ; V4T-NEXT:    ldr r0, .LCPI5_0
215 ; V4T-NEXT:    cmp r1, r0
216 ; V4T-NEXT:    movlt r0, r1
217 ; V4T-NEXT:    bx lr
218 ; V4T-NEXT:    .p2align 2
219 ; V4T-NEXT:  @ %bb.1:
220 ; V4T-NEXT:  .LCPI5_0:
221 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
223 ; V6-LABEL: unsigned_sat_upper_lower_1:
224 ; V6:       @ %bb.0: @ %entry
225 ; V6-NEXT:    usat r0, #23, r0
226 ; V6-NEXT:    bx lr
228 ; V6T2-LABEL: unsigned_sat_upper_lower_1:
229 ; V6T2:       @ %bb.0: @ %entry
230 ; V6T2-NEXT:    usat r0, #23, r0
231 ; V6T2-NEXT:    bx lr
232 entry:
233   %0 = icmp sgt i32 %x, 0
234   %saturateLow = select i1 %0, i32 %x, i32 0
235   %1 = icmp slt i32 %saturateLow, 8388607
236   %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
237   ret i32 %saturateUp
240 ; x > k ? k : (x < 0 ? 0 : x)
241 define i32 @unsigned_sat_upper_lower_2(i32 %x) #0 {
242 ; V4T-LABEL: unsigned_sat_upper_lower_2:
243 ; V4T:       @ %bb.0: @ %entry
244 ; V4T-NEXT:    bic r1, r0, r0, asr #31
245 ; V4T-NEXT:    ldr r0, .LCPI6_0
246 ; V4T-NEXT:    cmp r1, r0
247 ; V4T-NEXT:    movlt r0, r1
248 ; V4T-NEXT:    bx lr
249 ; V4T-NEXT:    .p2align 2
250 ; V4T-NEXT:  @ %bb.1:
251 ; V4T-NEXT:  .LCPI6_0:
252 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
254 ; V6-LABEL: unsigned_sat_upper_lower_2:
255 ; V6:       @ %bb.0: @ %entry
256 ; V6-NEXT:    usat r0, #23, r0
257 ; V6-NEXT:    bx lr
259 ; V6T2-LABEL: unsigned_sat_upper_lower_2:
260 ; V6T2:       @ %bb.0: @ %entry
261 ; V6T2-NEXT:    usat r0, #23, r0
262 ; V6T2-NEXT:    bx lr
263 entry:
264   %0 = icmp sgt i32 %x, 0
265   %saturateLow = select i1 %0, i32 %x, i32 0
266   %1 = icmp slt i32 %saturateLow, 8388607
267   %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
268   ret i32 %saturateUp
271 ; k < x ? k : (x > 0 ? x : 0)
272 define i32 @unsigned_sat_upper_lower_3(i32 %x) #0 {
273 ; V4T-LABEL: unsigned_sat_upper_lower_3:
274 ; V4T:       @ %bb.0: @ %entry
275 ; V4T-NEXT:    bic r1, r0, r0, asr #31
276 ; V4T-NEXT:    ldr r0, .LCPI7_0
277 ; V4T-NEXT:    cmp r1, r0
278 ; V4T-NEXT:    movlt r0, r1
279 ; V4T-NEXT:    bx lr
280 ; V4T-NEXT:    .p2align 2
281 ; V4T-NEXT:  @ %bb.1:
282 ; V4T-NEXT:  .LCPI7_0:
283 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
285 ; V6-LABEL: unsigned_sat_upper_lower_3:
286 ; V6:       @ %bb.0: @ %entry
287 ; V6-NEXT:    usat r0, #23, r0
288 ; V6-NEXT:    bx lr
290 ; V6T2-LABEL: unsigned_sat_upper_lower_3:
291 ; V6T2:       @ %bb.0: @ %entry
292 ; V6T2-NEXT:    usat r0, #23, r0
293 ; V6T2-NEXT:    bx lr
294 entry:
295   %cmpLow = icmp sgt i32 %x, 0
296   %saturateLow = select i1 %cmpLow, i32 %x, i32 0
297   %0 = icmp slt i32 %saturateLow, 8388607
298   %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607
299   ret i32 %saturateUp
303 ; The following tests check for patterns that should not transform
304 ; into USAT but are similar enough that could confuse the selector.
306 ; x > k ? k : (x > 0 ? 0 : x)
307 ; First condition upper-saturates, second doesn't lower-saturate.
308 define i32 @no_unsigned_sat_missing_lower(i32 %x) #0 {
309 ; V4T-LABEL: no_unsigned_sat_missing_lower:
310 ; V4T:       @ %bb.0: @ %entry
311 ; V4T-NEXT:    ldr r1, .LCPI8_0
312 ; V4T-NEXT:    cmp r0, #8388608
313 ; V4T-NEXT:    andlt r1, r0, r0, asr #31
314 ; V4T-NEXT:    mov r0, r1
315 ; V4T-NEXT:    bx lr
316 ; V4T-NEXT:    .p2align 2
317 ; V4T-NEXT:  @ %bb.1:
318 ; V4T-NEXT:  .LCPI8_0:
319 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
321 ; V6-LABEL: no_unsigned_sat_missing_lower:
322 ; V6:       @ %bb.0: @ %entry
323 ; V6-NEXT:    ldr r1, .LCPI8_0
324 ; V6-NEXT:    cmp r0, #8388608
325 ; V6-NEXT:    andlt r1, r0, r0, asr #31
326 ; V6-NEXT:    mov r0, r1
327 ; V6-NEXT:    bx lr
328 ; V6-NEXT:    .p2align 2
329 ; V6-NEXT:  @ %bb.1:
330 ; V6-NEXT:  .LCPI8_0:
331 ; V6-NEXT:    .long 8388607 @ 0x7fffff
333 ; V6T2-LABEL: no_unsigned_sat_missing_lower:
334 ; V6T2:       @ %bb.0: @ %entry
335 ; V6T2-NEXT:    and r1, r0, r0, asr #31
336 ; V6T2-NEXT:    cmp r0, #8388608
337 ; V6T2-NEXT:    movwge r1, #65535
338 ; V6T2-NEXT:    movtge r1, #127
339 ; V6T2-NEXT:    mov r0, r1
340 ; V6T2-NEXT:    bx lr
341 entry:
342   %cmpUp = icmp sgt i32 %x, 8388607
343   %0 = icmp slt i32 %x, 0
344   %saturateLow = select i1 %0, i32 %x, i32 0
345   %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
346   ret i32 %saturateUp
349 ; x < k ? k : (x < 0 ? 0 : x)
350 ; Second condition lower-saturates, first doesn't upper-saturate.
351 define i32 @no_unsigned_sat_missing_upper(i32 %x) #0 {
352 ; V4T-LABEL: no_unsigned_sat_missing_upper:
353 ; V4T:       @ %bb.0: @ %entry
354 ; V4T-NEXT:    ldr r1, .LCPI9_0
355 ; V4T-NEXT:    cmp r0, r1
356 ; V4T-NEXT:    bicge r1, r0, r0, asr #31
357 ; V4T-NEXT:    mov r0, r1
358 ; V4T-NEXT:    bx lr
359 ; V4T-NEXT:    .p2align 2
360 ; V4T-NEXT:  @ %bb.1:
361 ; V4T-NEXT:  .LCPI9_0:
362 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
364 ; V6-LABEL: no_unsigned_sat_missing_upper:
365 ; V6:       @ %bb.0: @ %entry
366 ; V6-NEXT:    ldr r1, .LCPI9_0
367 ; V6-NEXT:    cmp r0, r1
368 ; V6-NEXT:    bicge r1, r0, r0, asr #31
369 ; V6-NEXT:    mov r0, r1
370 ; V6-NEXT:    bx lr
371 ; V6-NEXT:    .p2align 2
372 ; V6-NEXT:  @ %bb.1:
373 ; V6-NEXT:  .LCPI9_0:
374 ; V6-NEXT:    .long 8388607 @ 0x7fffff
376 ; V6T2-LABEL: no_unsigned_sat_missing_upper:
377 ; V6T2:       @ %bb.0: @ %entry
378 ; V6T2-NEXT:    movw r2, #65535
379 ; V6T2-NEXT:    bic r1, r0, r0, asr #31
380 ; V6T2-NEXT:    movt r2, #127
381 ; V6T2-NEXT:    cmp r0, r2
382 ; V6T2-NEXT:    movwlt r1, #65535
383 ; V6T2-NEXT:    movtlt r1, #127
384 ; V6T2-NEXT:    mov r0, r1
385 ; V6T2-NEXT:    bx lr
386 entry:
387   %cmpUp = icmp slt i32 %x, 8388607
388   %0 = icmp sgt i32 %x, 0
389   %saturateLow = select i1 %0, i32 %x, i32 0
390   %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
391   ret i32 %saturateUp
394 ; Lower constant is different in the select and in the compare
395 define i32 @no_unsigned_sat_incorrect_constant(i32 %x) #0 {
396 ; V4T-LABEL: no_unsigned_sat_incorrect_constant:
397 ; V4T:       @ %bb.0: @ %entry
398 ; V4T-NEXT:    orr r1, r0, r0, asr #31
399 ; V4T-NEXT:    ldr r0, .LCPI10_0
400 ; V4T-NEXT:    cmp r1, r0
401 ; V4T-NEXT:    movlt r0, r1
402 ; V4T-NEXT:    bx lr
403 ; V4T-NEXT:    .p2align 2
404 ; V4T-NEXT:  @ %bb.1:
405 ; V4T-NEXT:  .LCPI10_0:
406 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
408 ; V6-LABEL: no_unsigned_sat_incorrect_constant:
409 ; V6:       @ %bb.0: @ %entry
410 ; V6-NEXT:    orr r1, r0, r0, asr #31
411 ; V6-NEXT:    ldr r0, .LCPI10_0
412 ; V6-NEXT:    cmp r1, r0
413 ; V6-NEXT:    movlt r0, r1
414 ; V6-NEXT:    bx lr
415 ; V6-NEXT:    .p2align 2
416 ; V6-NEXT:  @ %bb.1:
417 ; V6-NEXT:  .LCPI10_0:
418 ; V6-NEXT:    .long 8388607 @ 0x7fffff
420 ; V6T2-LABEL: no_unsigned_sat_incorrect_constant:
421 ; V6T2:       @ %bb.0: @ %entry
422 ; V6T2-NEXT:    orr r1, r0, r0, asr #31
423 ; V6T2-NEXT:    movw r0, #65535
424 ; V6T2-NEXT:    movt r0, #127
425 ; V6T2-NEXT:    cmp r1, r0
426 ; V6T2-NEXT:    movlt r0, r1
427 ; V6T2-NEXT:    bx lr
428 entry:
429   %cmpLow.inv = icmp sgt i32 %x, -1
430   %saturateLow = select i1 %cmpLow.inv, i32 %x, i32 -1
431   %0 = icmp slt i32 %saturateLow, 8388607
432   %saturateUp = select i1 %0, i32 %saturateLow, i32 8388607
433   ret i32 %saturateUp
436 ; The interval is [0, k] but k+1 is not a power of 2
437 define i32 @no_unsigned_sat_incorrect_constant2(i32 %x) #0 {
438 ; V4T-LABEL: no_unsigned_sat_incorrect_constant2:
439 ; V4T:       @ %bb.0: @ %entry
440 ; V4T-NEXT:    bic r1, r0, r0, asr #31
441 ; V4T-NEXT:    mov r0, #1
442 ; V4T-NEXT:    orr r0, r0, #8388608
443 ; V4T-NEXT:    cmp r1, #8388608
444 ; V4T-NEXT:    movle r0, r1
445 ; V4T-NEXT:    bx lr
447 ; V6-LABEL: no_unsigned_sat_incorrect_constant2:
448 ; V6:       @ %bb.0: @ %entry
449 ; V6-NEXT:    bic r1, r0, r0, asr #31
450 ; V6-NEXT:    mov r0, #1
451 ; V6-NEXT:    orr r0, r0, #8388608
452 ; V6-NEXT:    cmp r1, #8388608
453 ; V6-NEXT:    movle r0, r1
454 ; V6-NEXT:    bx lr
456 ; V6T2-LABEL: no_unsigned_sat_incorrect_constant2:
457 ; V6T2:       @ %bb.0: @ %entry
458 ; V6T2-NEXT:    bic r1, r0, r0, asr #31
459 ; V6T2-NEXT:    movw r0, #1
460 ; V6T2-NEXT:    movt r0, #128
461 ; V6T2-NEXT:    cmp r1, #8388608
462 ; V6T2-NEXT:    movle r0, r1
463 ; V6T2-NEXT:    bx lr
464 entry:
465   %0 = icmp sgt i32 %x, 0
466   %saturateLow = select i1 %0, i32 %x, i32 0
467   %1 = icmp slt i32 %saturateLow, 8388609
468   %saturateUp = select i1 %1, i32 %saturateLow, i32 8388609
469   ret i32 %saturateUp
472 ; The interval is not [0, k]
473 define i32 @no_unsigned_sat_incorrect_interval(i32 %x) #0 {
474 ; V4T-LABEL: no_unsigned_sat_incorrect_interval:
475 ; V4T:       @ %bb.0: @ %entry
476 ; V4T-NEXT:    ldr r1, .LCPI12_0
477 ; V4T-NEXT:    cmn r0, #4
478 ; V4T-NEXT:    mvnle r0, #3
479 ; V4T-NEXT:    cmp r0, r1
480 ; V4T-NEXT:    movge r0, r1
481 ; V4T-NEXT:    bx lr
482 ; V4T-NEXT:    .p2align 2
483 ; V4T-NEXT:  @ %bb.1:
484 ; V4T-NEXT:  .LCPI12_0:
485 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
487 ; V6-LABEL: no_unsigned_sat_incorrect_interval:
488 ; V6:       @ %bb.0: @ %entry
489 ; V6-NEXT:    ldr r1, .LCPI12_0
490 ; V6-NEXT:    cmn r0, #4
491 ; V6-NEXT:    mvnle r0, #3
492 ; V6-NEXT:    cmp r0, r1
493 ; V6-NEXT:    movge r0, r1
494 ; V6-NEXT:    bx lr
495 ; V6-NEXT:    .p2align 2
496 ; V6-NEXT:  @ %bb.1:
497 ; V6-NEXT:  .LCPI12_0:
498 ; V6-NEXT:    .long 8388607 @ 0x7fffff
500 ; V6T2-LABEL: no_unsigned_sat_incorrect_interval:
501 ; V6T2:       @ %bb.0: @ %entry
502 ; V6T2-NEXT:    cmn r0, #4
503 ; V6T2-NEXT:    movw r1, #65535
504 ; V6T2-NEXT:    mvnle r0, #3
505 ; V6T2-NEXT:    movt r1, #127
506 ; V6T2-NEXT:    cmp r0, r1
507 ; V6T2-NEXT:    movge r0, r1
508 ; V6T2-NEXT:    bx lr
509 entry:
510   %0 = icmp sgt i32 %x, -4
511   %saturateLow = select i1 %0, i32 %x, i32 -4
512   %1 = icmp slt i32 %saturateLow, 8388607
513   %saturateUp = select i1 %1, i32 %saturateLow, i32 8388607
514   ret i32 %saturateUp
517 ; The returned value (y) is not the same as the tested value (x).
518 define i32 @no_unsigned_sat_incorrect_return(i32 %x, i32 %y) #0 {
519 ; V4T-LABEL: no_unsigned_sat_incorrect_return:
520 ; V4T:       @ %bb.0: @ %entry
521 ; V4T-NEXT:    cmp r0, #0
522 ; V4T-NEXT:    ldr r2, .LCPI13_0
523 ; V4T-NEXT:    movmi r1, #0
524 ; V4T-NEXT:    cmp r0, #8388608
525 ; V4T-NEXT:    movlt r2, r1
526 ; V4T-NEXT:    mov r0, r2
527 ; V4T-NEXT:    bx lr
528 ; V4T-NEXT:    .p2align 2
529 ; V4T-NEXT:  @ %bb.1:
530 ; V4T-NEXT:  .LCPI13_0:
531 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
533 ; V6-LABEL: no_unsigned_sat_incorrect_return:
534 ; V6:       @ %bb.0: @ %entry
535 ; V6-NEXT:    cmp r0, #0
536 ; V6-NEXT:    ldr r2, .LCPI13_0
537 ; V6-NEXT:    movmi r1, #0
538 ; V6-NEXT:    cmp r0, #8388608
539 ; V6-NEXT:    movlt r2, r1
540 ; V6-NEXT:    mov r0, r2
541 ; V6-NEXT:    bx lr
542 ; V6-NEXT:    .p2align 2
543 ; V6-NEXT:  @ %bb.1:
544 ; V6-NEXT:  .LCPI13_0:
545 ; V6-NEXT:    .long 8388607 @ 0x7fffff
547 ; V6T2-LABEL: no_unsigned_sat_incorrect_return:
548 ; V6T2:       @ %bb.0: @ %entry
549 ; V6T2-NEXT:    cmp r0, #0
550 ; V6T2-NEXT:    movwmi r1, #0
551 ; V6T2-NEXT:    cmp r0, #8388608
552 ; V6T2-NEXT:    movwge r1, #65535
553 ; V6T2-NEXT:    movtge r1, #127
554 ; V6T2-NEXT:    mov r0, r1
555 ; V6T2-NEXT:    bx lr
556 entry:
557   %cmpUp = icmp sgt i32 %x, 8388607
558   %cmpLow = icmp slt i32 %x, 0
559   %saturateLow = select i1 %cmpLow, i32 0, i32 %y
560   %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
561   ret i32 %saturateUp
564 ; One of the values in a compare (y) is not the same as the rest
565 ; of the compare and select values (x).
566 define i32 @no_unsigned_sat_incorrect_compare(i32 %x, i32 %y) #0 {
567 ; V4T-LABEL: no_unsigned_sat_incorrect_compare:
568 ; V4T:       @ %bb.0: @ %entry
569 ; V4T-NEXT:    ldr r2, .LCPI14_0
570 ; V4T-NEXT:    cmp r1, #0
571 ; V4T-NEXT:    mov r1, r0
572 ; V4T-NEXT:    movmi r1, #0
573 ; V4T-NEXT:    cmp r0, #8388608
574 ; V4T-NEXT:    movge r1, r2
575 ; V4T-NEXT:    mov r0, r1
576 ; V4T-NEXT:    bx lr
577 ; V4T-NEXT:    .p2align 2
578 ; V4T-NEXT:  @ %bb.1:
579 ; V4T-NEXT:  .LCPI14_0:
580 ; V4T-NEXT:    .long 8388607 @ 0x7fffff
582 ; V6-LABEL: no_unsigned_sat_incorrect_compare:
583 ; V6:       @ %bb.0: @ %entry
584 ; V6-NEXT:    ldr r2, .LCPI14_0
585 ; V6-NEXT:    cmp r1, #0
586 ; V6-NEXT:    mov r1, r0
587 ; V6-NEXT:    movmi r1, #0
588 ; V6-NEXT:    cmp r0, #8388608
589 ; V6-NEXT:    movge r1, r2
590 ; V6-NEXT:    mov r0, r1
591 ; V6-NEXT:    bx lr
592 ; V6-NEXT:    .p2align 2
593 ; V6-NEXT:  @ %bb.1:
594 ; V6-NEXT:  .LCPI14_0:
595 ; V6-NEXT:    .long 8388607 @ 0x7fffff
597 ; V6T2-LABEL: no_unsigned_sat_incorrect_compare:
598 ; V6T2:       @ %bb.0: @ %entry
599 ; V6T2-NEXT:    cmp r1, #0
600 ; V6T2-NEXT:    mov r1, r0
601 ; V6T2-NEXT:    movwmi r1, #0
602 ; V6T2-NEXT:    cmp r0, #8388608
603 ; V6T2-NEXT:    movwge r1, #65535
604 ; V6T2-NEXT:    movtge r1, #127
605 ; V6T2-NEXT:    mov r0, r1
606 ; V6T2-NEXT:    bx lr
607 entry:
608   %cmpUp = icmp sgt i32 %x, 8388607
609   %cmpLow = icmp slt i32 %y, 0
610   %saturateLow = select i1 %cmpLow, i32 0, i32 %x
611   %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
612   ret i32 %saturateUp