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
5
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.
13
14;
15; Base tests with different bit widths
16;
17
18; x < 0 ? 0 : (x > k ? k : x)
19; 32-bit base test
20define 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
32;
33; V6-LABEL: unsigned_sat_base_32bit:
34; V6:       @ %bb.0: @ %entry
35; V6-NEXT:    usat r0, #23, r0
36; V6-NEXT:    bx lr
37;
38; V6T2-LABEL: unsigned_sat_base_32bit:
39; V6T2:       @ %bb.0: @ %entry
40; V6T2-NEXT:    usat r0, #23, r0
41; V6T2-NEXT:    bx lr
42entry:
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
48}
49
50; x < 0 ? 0 : (x > k ? k : x)
51; 16-bit base test
52define 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
67;
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
80;
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
92entry:
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
98}
99
100; x < 0 ? 0 : (x > k ? k : x)
101; 8-bit base test
102define 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
114;
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
124;
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
134entry:
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
140}
141
142;
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.
146;
147; x < 0 ? 0 : (x < k ? x : k)
148define 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
160;
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
165;
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
170entry:
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
176}
177
178; x > 0 ? (x > k ? k : x) : 0
179define 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
191;
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
196;
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
201entry:
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
207}
208
209; x < k ? (x < 0 ? 0 : x) : k
210define 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
222;
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
227;
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
232entry:
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
238}
239
240; x > k ? k : (x < 0 ? 0 : x)
241define 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
253;
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
258;
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
263entry:
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
269}
270
271; k < x ? k : (x > 0 ? x : 0)
272define 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
284;
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
289;
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
294entry:
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
300}
301
302;
303; The following tests check for patterns that should not transform
304; into USAT but are similar enough that could confuse the selector.
305;
306; x > k ? k : (x > 0 ? 0 : x)
307; First condition upper-saturates, second doesn't lower-saturate.
308define 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
320;
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
332;
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
341entry:
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
347}
348
349; x < k ? k : (x < 0 ? 0 : x)
350; Second condition lower-saturates, first doesn't upper-saturate.
351define 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
363;
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
375;
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
386entry:
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
392}
393
394; Lower constant is different in the select and in the compare
395define 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
407;
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
419;
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
428entry:
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
434}
435
436; The interval is [0, k] but k+1 is not a power of 2
437define 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
446;
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
455;
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
464entry:
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
470}
471
472; The interval is not [0, k]
473define 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
486;
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
499;
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
509entry:
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
515}
516
517; The returned value (y) is not the same as the tested value (x).
518define 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
532;
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
546;
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
556entry:
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
562}
563
564; One of the values in a compare (y) is not the same as the rest
565; of the compare and select values (x).
566define 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
581;
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
596;
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
607entry:
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
613}
614