1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=CHECK-T1
3; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2NODSP
4; RUN: llc < %s -mtriple=thumbv7em-none-eabi | FileCheck %s --check-prefix=CHECK-T2 --check-prefix=CHECK-T2DSP
5; RUN: llc < %s -mtriple=armv5t-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMNODPS
6; RUN: llc < %s -mtriple=armv5te-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMBASEDSP
7; RUN: llc < %s -mtriple=armv6-none-eabi | FileCheck %s --check-prefix=CHECK-ARM --check-prefix=CHECK-ARMDSP
8
9declare i4 @llvm.ssub.sat.i4(i4, i4)
10declare i8 @llvm.ssub.sat.i8(i8, i8)
11declare i16 @llvm.ssub.sat.i16(i16, i16)
12declare i32 @llvm.ssub.sat.i32(i32, i32)
13declare i64 @llvm.ssub.sat.i64(i64, i64)
14declare <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32>, <4 x i32>)
15
16define i32 @func(i32 %x, i32 %y) nounwind {
17; CHECK-T1-LABEL: func:
18; CHECK-T1:       @ %bb.0:
19; CHECK-T1-NEXT:    .save {r4, lr}
20; CHECK-T1-NEXT:    push {r4, lr}
21; CHECK-T1-NEXT:    mov r2, r0
22; CHECK-T1-NEXT:    movs r3, #1
23; CHECK-T1-NEXT:    subs r0, r0, r1
24; CHECK-T1-NEXT:    mov r4, r3
25; CHECK-T1-NEXT:    bmi .LBB0_2
26; CHECK-T1-NEXT:  @ %bb.1:
27; CHECK-T1-NEXT:    movs r4, #0
28; CHECK-T1-NEXT:  .LBB0_2:
29; CHECK-T1-NEXT:    cmp r4, #0
30; CHECK-T1-NEXT:    bne .LBB0_4
31; CHECK-T1-NEXT:  @ %bb.3:
32; CHECK-T1-NEXT:    lsls r3, r3, #31
33; CHECK-T1-NEXT:    cmp r2, r1
34; CHECK-T1-NEXT:    bvs .LBB0_5
35; CHECK-T1-NEXT:    b .LBB0_6
36; CHECK-T1-NEXT:  .LBB0_4:
37; CHECK-T1-NEXT:    ldr r3, .LCPI0_0
38; CHECK-T1-NEXT:    cmp r2, r1
39; CHECK-T1-NEXT:    bvc .LBB0_6
40; CHECK-T1-NEXT:  .LBB0_5:
41; CHECK-T1-NEXT:    mov r0, r3
42; CHECK-T1-NEXT:  .LBB0_6:
43; CHECK-T1-NEXT:    pop {r4, pc}
44; CHECK-T1-NEXT:    .p2align 2
45; CHECK-T1-NEXT:  @ %bb.7:
46; CHECK-T1-NEXT:  .LCPI0_0:
47; CHECK-T1-NEXT:    .long 2147483647 @ 0x7fffffff
48;
49; CHECK-T2NODSP-LABEL: func:
50; CHECK-T2NODSP:       @ %bb.0:
51; CHECK-T2NODSP-NEXT:    subs.w r12, r0, r1
52; CHECK-T2NODSP-NEXT:    mov.w r3, #0
53; CHECK-T2NODSP-NEXT:    mov.w r2, #-2147483648
54; CHECK-T2NODSP-NEXT:    it mi
55; CHECK-T2NODSP-NEXT:    movmi r3, #1
56; CHECK-T2NODSP-NEXT:    cmp r3, #0
57; CHECK-T2NODSP-NEXT:    it ne
58; CHECK-T2NODSP-NEXT:    mvnne r2, #-2147483648
59; CHECK-T2NODSP-NEXT:    cmp r0, r1
60; CHECK-T2NODSP-NEXT:    it vc
61; CHECK-T2NODSP-NEXT:    movvc r2, r12
62; CHECK-T2NODSP-NEXT:    mov r0, r2
63; CHECK-T2NODSP-NEXT:    bx lr
64;
65; CHECK-T2DSP-LABEL: func:
66; CHECK-T2DSP:       @ %bb.0:
67; CHECK-T2DSP-NEXT:    qsub r0, r0, r1
68; CHECK-T2DSP-NEXT:    bx lr
69;
70; CHECK-ARMNODPS-LABEL: func:
71; CHECK-ARMNODPS:       @ %bb.0:
72; CHECK-ARMNODPS-NEXT:    subs r12, r0, r1
73; CHECK-ARMNODPS-NEXT:    mov r3, #0
74; CHECK-ARMNODPS-NEXT:    movmi r3, #1
75; CHECK-ARMNODPS-NEXT:    mov r2, #-2147483648
76; CHECK-ARMNODPS-NEXT:    cmp r3, #0
77; CHECK-ARMNODPS-NEXT:    mvnne r2, #-2147483648
78; CHECK-ARMNODPS-NEXT:    cmp r0, r1
79; CHECK-ARMNODPS-NEXT:    movvc r2, r12
80; CHECK-ARMNODPS-NEXT:    mov r0, r2
81; CHECK-ARMNODPS-NEXT:    bx lr
82;
83; CHECK-ARMBASEDSP-LABEL: func:
84; CHECK-ARMBASEDSP:       @ %bb.0:
85; CHECK-ARMBASEDSP-NEXT:    qsub r0, r0, r1
86; CHECK-ARMBASEDSP-NEXT:    bx lr
87;
88; CHECK-ARMDSP-LABEL: func:
89; CHECK-ARMDSP:       @ %bb.0:
90; CHECK-ARMDSP-NEXT:    qsub r0, r0, r1
91; CHECK-ARMDSP-NEXT:    bx lr
92  %tmp = call i32 @llvm.ssub.sat.i32(i32 %x, i32 %y)
93  ret i32 %tmp
94}
95
96define i64 @func2(i64 %x, i64 %y) nounwind {
97; CHECK-T1-LABEL: func2:
98; CHECK-T1:       @ %bb.0:
99; CHECK-T1-NEXT:    .save {r4, r5, r6, r7, lr}
100; CHECK-T1-NEXT:    push {r4, r5, r6, r7, lr}
101; CHECK-T1-NEXT:    .pad #4
102; CHECK-T1-NEXT:    sub sp, #4
103; CHECK-T1-NEXT:    str r2, [sp] @ 4-byte Spill
104; CHECK-T1-NEXT:    mov r2, r0
105; CHECK-T1-NEXT:    movs r4, #1
106; CHECK-T1-NEXT:    movs r0, #0
107; CHECK-T1-NEXT:    cmp r3, #0
108; CHECK-T1-NEXT:    mov r5, r4
109; CHECK-T1-NEXT:    bge .LBB1_2
110; CHECK-T1-NEXT:  @ %bb.1:
111; CHECK-T1-NEXT:    mov r5, r0
112; CHECK-T1-NEXT:  .LBB1_2:
113; CHECK-T1-NEXT:    cmp r1, #0
114; CHECK-T1-NEXT:    mov r7, r4
115; CHECK-T1-NEXT:    bge .LBB1_4
116; CHECK-T1-NEXT:  @ %bb.3:
117; CHECK-T1-NEXT:    mov r7, r0
118; CHECK-T1-NEXT:  .LBB1_4:
119; CHECK-T1-NEXT:    subs r5, r7, r5
120; CHECK-T1-NEXT:    subs r6, r5, #1
121; CHECK-T1-NEXT:    sbcs r5, r6
122; CHECK-T1-NEXT:    ldr r6, [sp] @ 4-byte Reload
123; CHECK-T1-NEXT:    subs r6, r2, r6
124; CHECK-T1-NEXT:    sbcs r1, r3
125; CHECK-T1-NEXT:    cmp r1, #0
126; CHECK-T1-NEXT:    mov r2, r4
127; CHECK-T1-NEXT:    bge .LBB1_6
128; CHECK-T1-NEXT:  @ %bb.5:
129; CHECK-T1-NEXT:    mov r2, r0
130; CHECK-T1-NEXT:  .LBB1_6:
131; CHECK-T1-NEXT:    subs r0, r7, r2
132; CHECK-T1-NEXT:    subs r2, r0, #1
133; CHECK-T1-NEXT:    sbcs r0, r2
134; CHECK-T1-NEXT:    ands r5, r0
135; CHECK-T1-NEXT:    beq .LBB1_8
136; CHECK-T1-NEXT:  @ %bb.7:
137; CHECK-T1-NEXT:    asrs r6, r1, #31
138; CHECK-T1-NEXT:  .LBB1_8:
139; CHECK-T1-NEXT:    cmp r1, #0
140; CHECK-T1-NEXT:    bmi .LBB1_10
141; CHECK-T1-NEXT:  @ %bb.9:
142; CHECK-T1-NEXT:    lsls r2, r4, #31
143; CHECK-T1-NEXT:    cmp r5, #0
144; CHECK-T1-NEXT:    beq .LBB1_11
145; CHECK-T1-NEXT:    b .LBB1_12
146; CHECK-T1-NEXT:  .LBB1_10:
147; CHECK-T1-NEXT:    ldr r2, .LCPI1_0
148; CHECK-T1-NEXT:    cmp r5, #0
149; CHECK-T1-NEXT:    bne .LBB1_12
150; CHECK-T1-NEXT:  .LBB1_11:
151; CHECK-T1-NEXT:    mov r2, r1
152; CHECK-T1-NEXT:  .LBB1_12:
153; CHECK-T1-NEXT:    mov r0, r6
154; CHECK-T1-NEXT:    mov r1, r2
155; CHECK-T1-NEXT:    add sp, #4
156; CHECK-T1-NEXT:    pop {r4, r5, r6, r7, pc}
157; CHECK-T1-NEXT:    .p2align 2
158; CHECK-T1-NEXT:  @ %bb.13:
159; CHECK-T1-NEXT:  .LCPI1_0:
160; CHECK-T1-NEXT:    .long 2147483647 @ 0x7fffffff
161;
162; CHECK-T2-LABEL: func2:
163; CHECK-T2:       @ %bb.0:
164; CHECK-T2-NEXT:    .save {r4, lr}
165; CHECK-T2-NEXT:    push {r4, lr}
166; CHECK-T2-NEXT:    cmp.w r3, #-1
167; CHECK-T2-NEXT:    mov.w lr, #0
168; CHECK-T2-NEXT:    it gt
169; CHECK-T2-NEXT:    movgt.w lr, #1
170; CHECK-T2-NEXT:    cmp.w r1, #-1
171; CHECK-T2-NEXT:    mov.w r4, #0
172; CHECK-T2-NEXT:    mov.w r12, #0
173; CHECK-T2-NEXT:    it gt
174; CHECK-T2-NEXT:    movgt r4, #1
175; CHECK-T2-NEXT:    subs.w lr, r4, lr
176; CHECK-T2-NEXT:    it ne
177; CHECK-T2-NEXT:    movne.w lr, #1
178; CHECK-T2-NEXT:    subs r0, r0, r2
179; CHECK-T2-NEXT:    sbc.w r2, r1, r3
180; CHECK-T2-NEXT:    cmp.w r2, #-1
181; CHECK-T2-NEXT:    it gt
182; CHECK-T2-NEXT:    movgt.w r12, #1
183; CHECK-T2-NEXT:    subs.w r1, r4, r12
184; CHECK-T2-NEXT:    it ne
185; CHECK-T2-NEXT:    movne r1, #1
186; CHECK-T2-NEXT:    ands.w r3, lr, r1
187; CHECK-T2-NEXT:    mov.w r1, #-2147483648
188; CHECK-T2-NEXT:    it ne
189; CHECK-T2-NEXT:    asrne r0, r2, #31
190; CHECK-T2-NEXT:    cmp r2, #0
191; CHECK-T2-NEXT:    it mi
192; CHECK-T2-NEXT:    mvnmi r1, #-2147483648
193; CHECK-T2-NEXT:    cmp r3, #0
194; CHECK-T2-NEXT:    it eq
195; CHECK-T2-NEXT:    moveq r1, r2
196; CHECK-T2-NEXT:    pop {r4, pc}
197;
198; CHECK-ARM-LABEL: func2:
199; CHECK-ARM:       @ %bb.0:
200; CHECK-ARM-NEXT:    .save {r4, lr}
201; CHECK-ARM-NEXT:    push {r4, lr}
202; CHECK-ARM-NEXT:    cmn r3, #1
203; CHECK-ARM-NEXT:    mov lr, #0
204; CHECK-ARM-NEXT:    movgt lr, #1
205; CHECK-ARM-NEXT:    cmn r1, #1
206; CHECK-ARM-NEXT:    mov r4, #0
207; CHECK-ARM-NEXT:    mov r12, #0
208; CHECK-ARM-NEXT:    movgt r4, #1
209; CHECK-ARM-NEXT:    subs lr, r4, lr
210; CHECK-ARM-NEXT:    movne lr, #1
211; CHECK-ARM-NEXT:    subs r0, r0, r2
212; CHECK-ARM-NEXT:    sbc r2, r1, r3
213; CHECK-ARM-NEXT:    cmn r2, #1
214; CHECK-ARM-NEXT:    movgt r12, #1
215; CHECK-ARM-NEXT:    subs r1, r4, r12
216; CHECK-ARM-NEXT:    movne r1, #1
217; CHECK-ARM-NEXT:    ands r3, lr, r1
218; CHECK-ARM-NEXT:    asrne r0, r2, #31
219; CHECK-ARM-NEXT:    mov r1, #-2147483648
220; CHECK-ARM-NEXT:    cmp r2, #0
221; CHECK-ARM-NEXT:    mvnmi r1, #-2147483648
222; CHECK-ARM-NEXT:    cmp r3, #0
223; CHECK-ARM-NEXT:    moveq r1, r2
224; CHECK-ARM-NEXT:    pop {r4, pc}
225  %tmp = call i64 @llvm.ssub.sat.i64(i64 %x, i64 %y)
226  ret i64 %tmp
227}
228
229define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
230; CHECK-T1-LABEL: func16:
231; CHECK-T1:       @ %bb.0:
232; CHECK-T1-NEXT:    subs r0, r0, r1
233; CHECK-T1-NEXT:    ldr r1, .LCPI2_0
234; CHECK-T1-NEXT:    cmp r0, r1
235; CHECK-T1-NEXT:    blt .LBB2_2
236; CHECK-T1-NEXT:  @ %bb.1:
237; CHECK-T1-NEXT:    mov r0, r1
238; CHECK-T1-NEXT:  .LBB2_2:
239; CHECK-T1-NEXT:    ldr r1, .LCPI2_1
240; CHECK-T1-NEXT:    cmp r0, r1
241; CHECK-T1-NEXT:    bgt .LBB2_4
242; CHECK-T1-NEXT:  @ %bb.3:
243; CHECK-T1-NEXT:    mov r0, r1
244; CHECK-T1-NEXT:  .LBB2_4:
245; CHECK-T1-NEXT:    bx lr
246; CHECK-T1-NEXT:    .p2align 2
247; CHECK-T1-NEXT:  @ %bb.5:
248; CHECK-T1-NEXT:  .LCPI2_0:
249; CHECK-T1-NEXT:    .long 32767 @ 0x7fff
250; CHECK-T1-NEXT:  .LCPI2_1:
251; CHECK-T1-NEXT:    .long 4294934528 @ 0xffff8000
252;
253; CHECK-T2NODSP-LABEL: func16:
254; CHECK-T2NODSP:       @ %bb.0:
255; CHECK-T2NODSP-NEXT:    subs r0, r0, r1
256; CHECK-T2NODSP-NEXT:    movw r1, #32767
257; CHECK-T2NODSP-NEXT:    cmp r0, r1
258; CHECK-T2NODSP-NEXT:    it lt
259; CHECK-T2NODSP-NEXT:    movlt r1, r0
260; CHECK-T2NODSP-NEXT:    movw r0, #32768
261; CHECK-T2NODSP-NEXT:    cmn.w r1, #32768
262; CHECK-T2NODSP-NEXT:    movt r0, #65535
263; CHECK-T2NODSP-NEXT:    it gt
264; CHECK-T2NODSP-NEXT:    movgt r0, r1
265; CHECK-T2NODSP-NEXT:    bx lr
266;
267; CHECK-T2DSP-LABEL: func16:
268; CHECK-T2DSP:       @ %bb.0:
269; CHECK-T2DSP-NEXT:    qsub16 r0, r0, r1
270; CHECK-T2DSP-NEXT:    sxth r0, r0
271; CHECK-T2DSP-NEXT:    bx lr
272;
273; CHECK-ARMNODPS-LABEL: func16:
274; CHECK-ARMNODPS:       @ %bb.0:
275; CHECK-ARMNODPS-NEXT:    sub r0, r0, r1
276; CHECK-ARMNODPS-NEXT:    mov r1, #255
277; CHECK-ARMNODPS-NEXT:    orr r1, r1, #32512
278; CHECK-ARMNODPS-NEXT:    cmp r0, r1
279; CHECK-ARMNODPS-NEXT:    movlt r1, r0
280; CHECK-ARMNODPS-NEXT:    ldr r0, .LCPI2_0
281; CHECK-ARMNODPS-NEXT:    cmn r1, #32768
282; CHECK-ARMNODPS-NEXT:    movgt r0, r1
283; CHECK-ARMNODPS-NEXT:    bx lr
284; CHECK-ARMNODPS-NEXT:    .p2align 2
285; CHECK-ARMNODPS-NEXT:  @ %bb.1:
286; CHECK-ARMNODPS-NEXT:  .LCPI2_0:
287; CHECK-ARMNODPS-NEXT:    .long 4294934528 @ 0xffff8000
288;
289; CHECK-ARMBASEDSP-LABEL: func16:
290; CHECK-ARMBASEDSP:       @ %bb.0:
291; CHECK-ARMBASEDSP-NEXT:    lsl r0, r0, #16
292; CHECK-ARMBASEDSP-NEXT:    lsl r1, r1, #16
293; CHECK-ARMBASEDSP-NEXT:    qsub r0, r0, r1
294; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #16
295; CHECK-ARMBASEDSP-NEXT:    bx lr
296;
297; CHECK-ARMDSP-LABEL: func16:
298; CHECK-ARMDSP:       @ %bb.0:
299; CHECK-ARMDSP-NEXT:    qsub16 r0, r0, r1
300; CHECK-ARMDSP-NEXT:    sxth r0, r0
301; CHECK-ARMDSP-NEXT:    bx lr
302  %tmp = call i16 @llvm.ssub.sat.i16(i16 %x, i16 %y)
303  ret i16 %tmp
304}
305
306define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
307; CHECK-T1-LABEL: func8:
308; CHECK-T1:       @ %bb.0:
309; CHECK-T1-NEXT:    subs r0, r0, r1
310; CHECK-T1-NEXT:    movs r1, #127
311; CHECK-T1-NEXT:    cmp r0, #127
312; CHECK-T1-NEXT:    blt .LBB3_2
313; CHECK-T1-NEXT:  @ %bb.1:
314; CHECK-T1-NEXT:    mov r0, r1
315; CHECK-T1-NEXT:  .LBB3_2:
316; CHECK-T1-NEXT:    mvns r1, r1
317; CHECK-T1-NEXT:    cmp r0, r1
318; CHECK-T1-NEXT:    bgt .LBB3_4
319; CHECK-T1-NEXT:  @ %bb.3:
320; CHECK-T1-NEXT:    mov r0, r1
321; CHECK-T1-NEXT:  .LBB3_4:
322; CHECK-T1-NEXT:    bx lr
323;
324; CHECK-T2NODSP-LABEL: func8:
325; CHECK-T2NODSP:       @ %bb.0:
326; CHECK-T2NODSP-NEXT:    subs r0, r0, r1
327; CHECK-T2NODSP-NEXT:    cmp r0, #127
328; CHECK-T2NODSP-NEXT:    it ge
329; CHECK-T2NODSP-NEXT:    movge r0, #127
330; CHECK-T2NODSP-NEXT:    cmn.w r0, #128
331; CHECK-T2NODSP-NEXT:    it le
332; CHECK-T2NODSP-NEXT:    mvnle r0, #127
333; CHECK-T2NODSP-NEXT:    bx lr
334;
335; CHECK-T2DSP-LABEL: func8:
336; CHECK-T2DSP:       @ %bb.0:
337; CHECK-T2DSP-NEXT:    qsub8 r0, r0, r1
338; CHECK-T2DSP-NEXT:    sxtb r0, r0
339; CHECK-T2DSP-NEXT:    bx lr
340;
341; CHECK-ARMNODPS-LABEL: func8:
342; CHECK-ARMNODPS:       @ %bb.0:
343; CHECK-ARMNODPS-NEXT:    sub r0, r0, r1
344; CHECK-ARMNODPS-NEXT:    cmp r0, #127
345; CHECK-ARMNODPS-NEXT:    movge r0, #127
346; CHECK-ARMNODPS-NEXT:    cmn r0, #128
347; CHECK-ARMNODPS-NEXT:    mvnle r0, #127
348; CHECK-ARMNODPS-NEXT:    bx lr
349;
350; CHECK-ARMBASEDSP-LABEL: func8:
351; CHECK-ARMBASEDSP:       @ %bb.0:
352; CHECK-ARMBASEDSP-NEXT:    lsl r0, r0, #24
353; CHECK-ARMBASEDSP-NEXT:    lsl r1, r1, #24
354; CHECK-ARMBASEDSP-NEXT:    qsub r0, r0, r1
355; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #24
356; CHECK-ARMBASEDSP-NEXT:    bx lr
357;
358; CHECK-ARMDSP-LABEL: func8:
359; CHECK-ARMDSP:       @ %bb.0:
360; CHECK-ARMDSP-NEXT:    qsub8 r0, r0, r1
361; CHECK-ARMDSP-NEXT:    sxtb r0, r0
362; CHECK-ARMDSP-NEXT:    bx lr
363  %tmp = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y)
364  ret i8 %tmp
365}
366
367define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
368; CHECK-T1-LABEL: func3:
369; CHECK-T1:       @ %bb.0:
370; CHECK-T1-NEXT:    subs r0, r0, r1
371; CHECK-T1-NEXT:    movs r1, #7
372; CHECK-T1-NEXT:    cmp r0, #7
373; CHECK-T1-NEXT:    blt .LBB4_2
374; CHECK-T1-NEXT:  @ %bb.1:
375; CHECK-T1-NEXT:    mov r0, r1
376; CHECK-T1-NEXT:  .LBB4_2:
377; CHECK-T1-NEXT:    mvns r1, r1
378; CHECK-T1-NEXT:    cmp r0, r1
379; CHECK-T1-NEXT:    bgt .LBB4_4
380; CHECK-T1-NEXT:  @ %bb.3:
381; CHECK-T1-NEXT:    mov r0, r1
382; CHECK-T1-NEXT:  .LBB4_4:
383; CHECK-T1-NEXT:    bx lr
384;
385; CHECK-T2NODSP-LABEL: func3:
386; CHECK-T2NODSP:       @ %bb.0:
387; CHECK-T2NODSP-NEXT:    subs r0, r0, r1
388; CHECK-T2NODSP-NEXT:    cmp r0, #7
389; CHECK-T2NODSP-NEXT:    it ge
390; CHECK-T2NODSP-NEXT:    movge r0, #7
391; CHECK-T2NODSP-NEXT:    cmn.w r0, #8
392; CHECK-T2NODSP-NEXT:    it le
393; CHECK-T2NODSP-NEXT:    mvnle r0, #7
394; CHECK-T2NODSP-NEXT:    bx lr
395;
396; CHECK-T2DSP-LABEL: func3:
397; CHECK-T2DSP:       @ %bb.0:
398; CHECK-T2DSP-NEXT:    lsls r1, r1, #28
399; CHECK-T2DSP-NEXT:    lsls r0, r0, #28
400; CHECK-T2DSP-NEXT:    qsub r0, r0, r1
401; CHECK-T2DSP-NEXT:    asrs r0, r0, #28
402; CHECK-T2DSP-NEXT:    bx lr
403;
404; CHECK-ARMNODPS-LABEL: func3:
405; CHECK-ARMNODPS:       @ %bb.0:
406; CHECK-ARMNODPS-NEXT:    sub r0, r0, r1
407; CHECK-ARMNODPS-NEXT:    cmp r0, #7
408; CHECK-ARMNODPS-NEXT:    movge r0, #7
409; CHECK-ARMNODPS-NEXT:    cmn r0, #8
410; CHECK-ARMNODPS-NEXT:    mvnle r0, #7
411; CHECK-ARMNODPS-NEXT:    bx lr
412;
413; CHECK-ARMBASEDSP-LABEL: func3:
414; CHECK-ARMBASEDSP:       @ %bb.0:
415; CHECK-ARMBASEDSP-NEXT:    lsl r0, r0, #28
416; CHECK-ARMBASEDSP-NEXT:    lsl r1, r1, #28
417; CHECK-ARMBASEDSP-NEXT:    qsub r0, r0, r1
418; CHECK-ARMBASEDSP-NEXT:    asr r0, r0, #28
419; CHECK-ARMBASEDSP-NEXT:    bx lr
420;
421; CHECK-ARMDSP-LABEL: func3:
422; CHECK-ARMDSP:       @ %bb.0:
423; CHECK-ARMDSP-NEXT:    lsl r0, r0, #28
424; CHECK-ARMDSP-NEXT:    lsl r1, r1, #28
425; CHECK-ARMDSP-NEXT:    qsub r0, r0, r1
426; CHECK-ARMDSP-NEXT:    asr r0, r0, #28
427; CHECK-ARMDSP-NEXT:    bx lr
428  %tmp = call i4 @llvm.ssub.sat.i4(i4 %x, i4 %y)
429  ret i4 %tmp
430}
431
432define <4 x i32> @vec(<4 x i32> %x, <4 x i32> %y) nounwind {
433; CHECK-T1-LABEL: vec:
434; CHECK-T1:       @ %bb.0:
435; CHECK-T1-NEXT:    .save {r4, r5, r6, r7, lr}
436; CHECK-T1-NEXT:    push {r4, r5, r6, r7, lr}
437; CHECK-T1-NEXT:    .pad #12
438; CHECK-T1-NEXT:    sub sp, #12
439; CHECK-T1-NEXT:    str r3, [sp] @ 4-byte Spill
440; CHECK-T1-NEXT:    mov r4, r1
441; CHECK-T1-NEXT:    mov r1, r0
442; CHECK-T1-NEXT:    ldr r5, [sp, #32]
443; CHECK-T1-NEXT:    movs r7, #1
444; CHECK-T1-NEXT:    movs r0, #0
445; CHECK-T1-NEXT:    str r0, [sp, #8] @ 4-byte Spill
446; CHECK-T1-NEXT:    subs r0, r1, r5
447; CHECK-T1-NEXT:    str r0, [sp, #4] @ 4-byte Spill
448; CHECK-T1-NEXT:    mov r6, r7
449; CHECK-T1-NEXT:    bmi .LBB5_2
450; CHECK-T1-NEXT:  @ %bb.1:
451; CHECK-T1-NEXT:    ldr r6, [sp, #8] @ 4-byte Reload
452; CHECK-T1-NEXT:  .LBB5_2:
453; CHECK-T1-NEXT:    lsls r3, r7, #31
454; CHECK-T1-NEXT:    ldr r0, .LCPI5_0
455; CHECK-T1-NEXT:    cmp r6, #0
456; CHECK-T1-NEXT:    mov r6, r0
457; CHECK-T1-NEXT:    bne .LBB5_4
458; CHECK-T1-NEXT:  @ %bb.3:
459; CHECK-T1-NEXT:    mov r6, r3
460; CHECK-T1-NEXT:  .LBB5_4:
461; CHECK-T1-NEXT:    cmp r1, r5
462; CHECK-T1-NEXT:    bvc .LBB5_6
463; CHECK-T1-NEXT:  @ %bb.5:
464; CHECK-T1-NEXT:    str r6, [sp, #4] @ 4-byte Spill
465; CHECK-T1-NEXT:  .LBB5_6:
466; CHECK-T1-NEXT:    ldr r5, [sp, #36]
467; CHECK-T1-NEXT:    subs r1, r4, r5
468; CHECK-T1-NEXT:    mov r6, r7
469; CHECK-T1-NEXT:    bmi .LBB5_8
470; CHECK-T1-NEXT:  @ %bb.7:
471; CHECK-T1-NEXT:    ldr r6, [sp, #8] @ 4-byte Reload
472; CHECK-T1-NEXT:  .LBB5_8:
473; CHECK-T1-NEXT:    cmp r6, #0
474; CHECK-T1-NEXT:    mov r6, r0
475; CHECK-T1-NEXT:    bne .LBB5_10
476; CHECK-T1-NEXT:  @ %bb.9:
477; CHECK-T1-NEXT:    mov r6, r3
478; CHECK-T1-NEXT:  .LBB5_10:
479; CHECK-T1-NEXT:    cmp r4, r5
480; CHECK-T1-NEXT:    bvc .LBB5_12
481; CHECK-T1-NEXT:  @ %bb.11:
482; CHECK-T1-NEXT:    mov r1, r6
483; CHECK-T1-NEXT:  .LBB5_12:
484; CHECK-T1-NEXT:    ldr r5, [sp, #40]
485; CHECK-T1-NEXT:    subs r4, r2, r5
486; CHECK-T1-NEXT:    mov r6, r7
487; CHECK-T1-NEXT:    bmi .LBB5_14
488; CHECK-T1-NEXT:  @ %bb.13:
489; CHECK-T1-NEXT:    ldr r6, [sp, #8] @ 4-byte Reload
490; CHECK-T1-NEXT:  .LBB5_14:
491; CHECK-T1-NEXT:    cmp r6, #0
492; CHECK-T1-NEXT:    mov r6, r0
493; CHECK-T1-NEXT:    bne .LBB5_16
494; CHECK-T1-NEXT:  @ %bb.15:
495; CHECK-T1-NEXT:    mov r6, r3
496; CHECK-T1-NEXT:  .LBB5_16:
497; CHECK-T1-NEXT:    cmp r2, r5
498; CHECK-T1-NEXT:    bvc .LBB5_18
499; CHECK-T1-NEXT:  @ %bb.17:
500; CHECK-T1-NEXT:    mov r4, r6
501; CHECK-T1-NEXT:  .LBB5_18:
502; CHECK-T1-NEXT:    ldr r2, [sp, #44]
503; CHECK-T1-NEXT:    ldr r6, [sp] @ 4-byte Reload
504; CHECK-T1-NEXT:    subs r5, r6, r2
505; CHECK-T1-NEXT:    bpl .LBB5_23
506; CHECK-T1-NEXT:  @ %bb.19:
507; CHECK-T1-NEXT:    cmp r7, #0
508; CHECK-T1-NEXT:    beq .LBB5_24
509; CHECK-T1-NEXT:  .LBB5_20:
510; CHECK-T1-NEXT:    cmp r6, r2
511; CHECK-T1-NEXT:    bvc .LBB5_22
512; CHECK-T1-NEXT:  .LBB5_21:
513; CHECK-T1-NEXT:    mov r5, r0
514; CHECK-T1-NEXT:  .LBB5_22:
515; CHECK-T1-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
516; CHECK-T1-NEXT:    mov r2, r4
517; CHECK-T1-NEXT:    mov r3, r5
518; CHECK-T1-NEXT:    add sp, #12
519; CHECK-T1-NEXT:    pop {r4, r5, r6, r7, pc}
520; CHECK-T1-NEXT:  .LBB5_23:
521; CHECK-T1-NEXT:    ldr r7, [sp, #8] @ 4-byte Reload
522; CHECK-T1-NEXT:    cmp r7, #0
523; CHECK-T1-NEXT:    bne .LBB5_20
524; CHECK-T1-NEXT:  .LBB5_24:
525; CHECK-T1-NEXT:    mov r0, r3
526; CHECK-T1-NEXT:    cmp r6, r2
527; CHECK-T1-NEXT:    bvs .LBB5_21
528; CHECK-T1-NEXT:    b .LBB5_22
529; CHECK-T1-NEXT:    .p2align 2
530; CHECK-T1-NEXT:  @ %bb.25:
531; CHECK-T1-NEXT:  .LCPI5_0:
532; CHECK-T1-NEXT:    .long 2147483647 @ 0x7fffffff
533;
534; CHECK-T2NODSP-LABEL: vec:
535; CHECK-T2NODSP:       @ %bb.0:
536; CHECK-T2NODSP-NEXT:    .save {r4, r5, r6, r7, lr}
537; CHECK-T2NODSP-NEXT:    push {r4, r5, r6, r7, lr}
538; CHECK-T2NODSP-NEXT:    .pad #4
539; CHECK-T2NODSP-NEXT:    sub sp, #4
540; CHECK-T2NODSP-NEXT:    ldr r4, [sp, #24]
541; CHECK-T2NODSP-NEXT:    mov lr, r0
542; CHECK-T2NODSP-NEXT:    ldr r7, [sp, #28]
543; CHECK-T2NODSP-NEXT:    movs r5, #0
544; CHECK-T2NODSP-NEXT:    subs r6, r0, r4
545; CHECK-T2NODSP-NEXT:    mov.w r0, #0
546; CHECK-T2NODSP-NEXT:    it mi
547; CHECK-T2NODSP-NEXT:    movmi r0, #1
548; CHECK-T2NODSP-NEXT:    cmp r0, #0
549; CHECK-T2NODSP-NEXT:    mov.w r0, #-2147483648
550; CHECK-T2NODSP-NEXT:    mov.w r12, #-2147483648
551; CHECK-T2NODSP-NEXT:    it ne
552; CHECK-T2NODSP-NEXT:    mvnne r0, #-2147483648
553; CHECK-T2NODSP-NEXT:    cmp lr, r4
554; CHECK-T2NODSP-NEXT:    it vc
555; CHECK-T2NODSP-NEXT:    movvc r0, r6
556; CHECK-T2NODSP-NEXT:    subs r6, r1, r7
557; CHECK-T2NODSP-NEXT:    mov.w r4, #0
558; CHECK-T2NODSP-NEXT:    mov.w lr, #-2147483648
559; CHECK-T2NODSP-NEXT:    it mi
560; CHECK-T2NODSP-NEXT:    movmi r4, #1
561; CHECK-T2NODSP-NEXT:    cmp r4, #0
562; CHECK-T2NODSP-NEXT:    it ne
563; CHECK-T2NODSP-NEXT:    mvnne lr, #-2147483648
564; CHECK-T2NODSP-NEXT:    cmp r1, r7
565; CHECK-T2NODSP-NEXT:    ldr r1, [sp, #32]
566; CHECK-T2NODSP-NEXT:    mov.w r4, #0
567; CHECK-T2NODSP-NEXT:    it vc
568; CHECK-T2NODSP-NEXT:    movvc lr, r6
569; CHECK-T2NODSP-NEXT:    subs r6, r2, r1
570; CHECK-T2NODSP-NEXT:    it mi
571; CHECK-T2NODSP-NEXT:    movmi r4, #1
572; CHECK-T2NODSP-NEXT:    cmp r4, #0
573; CHECK-T2NODSP-NEXT:    mov.w r4, #-2147483648
574; CHECK-T2NODSP-NEXT:    it ne
575; CHECK-T2NODSP-NEXT:    mvnne r4, #-2147483648
576; CHECK-T2NODSP-NEXT:    cmp r2, r1
577; CHECK-T2NODSP-NEXT:    ldr r1, [sp, #36]
578; CHECK-T2NODSP-NEXT:    it vc
579; CHECK-T2NODSP-NEXT:    movvc r4, r6
580; CHECK-T2NODSP-NEXT:    subs r2, r3, r1
581; CHECK-T2NODSP-NEXT:    it mi
582; CHECK-T2NODSP-NEXT:    movmi r5, #1
583; CHECK-T2NODSP-NEXT:    cmp r5, #0
584; CHECK-T2NODSP-NEXT:    it ne
585; CHECK-T2NODSP-NEXT:    mvnne r12, #-2147483648
586; CHECK-T2NODSP-NEXT:    cmp r3, r1
587; CHECK-T2NODSP-NEXT:    it vc
588; CHECK-T2NODSP-NEXT:    movvc r12, r2
589; CHECK-T2NODSP-NEXT:    mov r1, lr
590; CHECK-T2NODSP-NEXT:    mov r2, r4
591; CHECK-T2NODSP-NEXT:    mov r3, r12
592; CHECK-T2NODSP-NEXT:    add sp, #4
593; CHECK-T2NODSP-NEXT:    pop {r4, r5, r6, r7, pc}
594;
595; CHECK-T2DSP-LABEL: vec:
596; CHECK-T2DSP:       @ %bb.0:
597; CHECK-T2DSP-NEXT:    ldr.w r12, [sp]
598; CHECK-T2DSP-NEXT:    qsub r0, r0, r12
599; CHECK-T2DSP-NEXT:    ldr.w r12, [sp, #4]
600; CHECK-T2DSP-NEXT:    qsub r1, r1, r12
601; CHECK-T2DSP-NEXT:    ldr.w r12, [sp, #8]
602; CHECK-T2DSP-NEXT:    qsub r2, r2, r12
603; CHECK-T2DSP-NEXT:    ldr.w r12, [sp, #12]
604; CHECK-T2DSP-NEXT:    qsub r3, r3, r12
605; CHECK-T2DSP-NEXT:    bx lr
606;
607; CHECK-ARMNODPS-LABEL: vec:
608; CHECK-ARMNODPS:       @ %bb.0:
609; CHECK-ARMNODPS-NEXT:    .save {r4, r5, r6, r7, r11, lr}
610; CHECK-ARMNODPS-NEXT:    push {r4, r5, r6, r7, r11, lr}
611; CHECK-ARMNODPS-NEXT:    ldr r4, [sp, #24]
612; CHECK-ARMNODPS-NEXT:    mov lr, r0
613; CHECK-ARMNODPS-NEXT:    ldr r7, [sp, #28]
614; CHECK-ARMNODPS-NEXT:    mov r5, #0
615; CHECK-ARMNODPS-NEXT:    subs r6, r0, r4
616; CHECK-ARMNODPS-NEXT:    mov r0, #0
617; CHECK-ARMNODPS-NEXT:    movmi r0, #1
618; CHECK-ARMNODPS-NEXT:    cmp r0, #0
619; CHECK-ARMNODPS-NEXT:    mov r0, #-2147483648
620; CHECK-ARMNODPS-NEXT:    mov r12, #-2147483648
621; CHECK-ARMNODPS-NEXT:    mvnne r0, #-2147483648
622; CHECK-ARMNODPS-NEXT:    cmp lr, r4
623; CHECK-ARMNODPS-NEXT:    movvc r0, r6
624; CHECK-ARMNODPS-NEXT:    subs r6, r1, r7
625; CHECK-ARMNODPS-NEXT:    mov r4, #0
626; CHECK-ARMNODPS-NEXT:    mov lr, #-2147483648
627; CHECK-ARMNODPS-NEXT:    movmi r4, #1
628; CHECK-ARMNODPS-NEXT:    cmp r4, #0
629; CHECK-ARMNODPS-NEXT:    mvnne lr, #-2147483648
630; CHECK-ARMNODPS-NEXT:    cmp r1, r7
631; CHECK-ARMNODPS-NEXT:    ldr r1, [sp, #32]
632; CHECK-ARMNODPS-NEXT:    movvc lr, r6
633; CHECK-ARMNODPS-NEXT:    mov r4, #0
634; CHECK-ARMNODPS-NEXT:    subs r6, r2, r1
635; CHECK-ARMNODPS-NEXT:    movmi r4, #1
636; CHECK-ARMNODPS-NEXT:    cmp r4, #0
637; CHECK-ARMNODPS-NEXT:    mov r4, #-2147483648
638; CHECK-ARMNODPS-NEXT:    mvnne r4, #-2147483648
639; CHECK-ARMNODPS-NEXT:    cmp r2, r1
640; CHECK-ARMNODPS-NEXT:    ldr r1, [sp, #36]
641; CHECK-ARMNODPS-NEXT:    movvc r4, r6
642; CHECK-ARMNODPS-NEXT:    subs r2, r3, r1
643; CHECK-ARMNODPS-NEXT:    movmi r5, #1
644; CHECK-ARMNODPS-NEXT:    cmp r5, #0
645; CHECK-ARMNODPS-NEXT:    mvnne r12, #-2147483648
646; CHECK-ARMNODPS-NEXT:    cmp r3, r1
647; CHECK-ARMNODPS-NEXT:    movvc r12, r2
648; CHECK-ARMNODPS-NEXT:    mov r1, lr
649; CHECK-ARMNODPS-NEXT:    mov r2, r4
650; CHECK-ARMNODPS-NEXT:    mov r3, r12
651; CHECK-ARMNODPS-NEXT:    pop {r4, r5, r6, r7, r11, pc}
652;
653; CHECK-ARMBASEDSP-LABEL: vec:
654; CHECK-ARMBASEDSP:       @ %bb.0:
655; CHECK-ARMBASEDSP-NEXT:    ldr r12, [sp]
656; CHECK-ARMBASEDSP-NEXT:    qsub r0, r0, r12
657; CHECK-ARMBASEDSP-NEXT:    ldr r12, [sp, #4]
658; CHECK-ARMBASEDSP-NEXT:    qsub r1, r1, r12
659; CHECK-ARMBASEDSP-NEXT:    ldr r12, [sp, #8]
660; CHECK-ARMBASEDSP-NEXT:    qsub r2, r2, r12
661; CHECK-ARMBASEDSP-NEXT:    ldr r12, [sp, #12]
662; CHECK-ARMBASEDSP-NEXT:    qsub r3, r3, r12
663; CHECK-ARMBASEDSP-NEXT:    bx lr
664;
665; CHECK-ARMDSP-LABEL: vec:
666; CHECK-ARMDSP:       @ %bb.0:
667; CHECK-ARMDSP-NEXT:    ldr r12, [sp]
668; CHECK-ARMDSP-NEXT:    qsub r0, r0, r12
669; CHECK-ARMDSP-NEXT:    ldr r12, [sp, #4]
670; CHECK-ARMDSP-NEXT:    qsub r1, r1, r12
671; CHECK-ARMDSP-NEXT:    ldr r12, [sp, #8]
672; CHECK-ARMDSP-NEXT:    qsub r2, r2, r12
673; CHECK-ARMDSP-NEXT:    ldr r12, [sp, #12]
674; CHECK-ARMDSP-NEXT:    qsub r3, r3, r12
675; CHECK-ARMDSP-NEXT:    bx lr
676  %tmp = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %x, <4 x i32> %y)
677  ret <4 x i32> %tmp
678}
679