xref: /llvm-project/llvm/test/CodeGen/Thumb/smul_fix_sat.ll (revision e30a4fc3e20bf5d9cc2f5bfcb61b4eb0e686a193)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv6m-none-unknown-eabi -mcpu=cortex-m0 | FileCheck %s --check-prefix=ARM
3
4declare  i4  @llvm.smul.fix.sat.i4   (i4,  i4, i32)
5declare  i32 @llvm.smul.fix.sat.i32  (i32, i32, i32)
6declare  i64 @llvm.smul.fix.sat.i64  (i64, i64, i32)
7
8define i32 @func(i32 %x, i32 %y) nounwind {
9; ARM-LABEL: func:
10; ARM:       @ %bb.0:
11; ARM-NEXT:    .save {r7, lr}
12; ARM-NEXT:    push {r7, lr}
13; ARM-NEXT:    mov r2, r1
14; ARM-NEXT:    asrs r1, r0, #31
15; ARM-NEXT:    asrs r3, r2, #31
16; ARM-NEXT:    bl __aeabi_lmul
17; ARM-NEXT:    cmp r1, #1
18; ARM-NEXT:    bgt .LBB0_2
19; ARM-NEXT:  @ %bb.1:
20; ARM-NEXT:    lsrs r0, r0, #2
21; ARM-NEXT:    lsls r2, r1, #30
22; ARM-NEXT:    adds r0, r2, r0
23; ARM-NEXT:    b .LBB0_3
24; ARM-NEXT:  .LBB0_2:
25; ARM-NEXT:    ldr r0, .LCPI0_0
26; ARM-NEXT:  .LBB0_3:
27; ARM-NEXT:    movs r2, #1
28; ARM-NEXT:    mvns r3, r2
29; ARM-NEXT:    cmp r1, r3
30; ARM-NEXT:    bge .LBB0_5
31; ARM-NEXT:  @ %bb.4:
32; ARM-NEXT:    lsls r0, r2, #31
33; ARM-NEXT:  .LBB0_5:
34; ARM-NEXT:    pop {r7, pc}
35; ARM-NEXT:    .p2align 2
36; ARM-NEXT:  @ %bb.6:
37; ARM-NEXT:  .LCPI0_0:
38; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
39  %tmp = call i32 @llvm.smul.fix.sat.i32(i32 %x, i32 %y, i32 2)
40  ret i32 %tmp
41}
42
43define i64 @func2(i64 %x, i64 %y) nounwind {
44; ARM-LABEL: func2:
45; ARM:       @ %bb.0:
46; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
47; ARM-NEXT:    push {r4, r5, r6, r7, lr}
48; ARM-NEXT:    .pad #28
49; ARM-NEXT:    sub sp, #28
50; ARM-NEXT:    str r3, [sp, #24] @ 4-byte Spill
51; ARM-NEXT:    mov r6, r2
52; ARM-NEXT:    mov r2, r1
53; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
54; ARM-NEXT:    mov r7, r0
55; ARM-NEXT:    asrs r1, r1, #31
56; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
57; ARM-NEXT:    movs r4, #0
58; ARM-NEXT:    mov r0, r2
59; ARM-NEXT:    mov r2, r6
60; ARM-NEXT:    mov r3, r4
61; ARM-NEXT:    bl __aeabi_lmul
62; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
63; ARM-NEXT:    mov r5, r1
64; ARM-NEXT:    mov r0, r7
65; ARM-NEXT:    mov r1, r4
66; ARM-NEXT:    mov r2, r6
67; ARM-NEXT:    mov r3, r4
68; ARM-NEXT:    bl __aeabi_lmul
69; ARM-NEXT:    str r0, [sp, #20] @ 4-byte Spill
70; ARM-NEXT:    ldr r0, [sp, #16] @ 4-byte Reload
71; ARM-NEXT:    adds r0, r0, r1
72; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
73; ARM-NEXT:    adcs r5, r4
74; ARM-NEXT:    asrs r0, r5, #31
75; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
76; ARM-NEXT:    ldr r2, [sp, #24] @ 4-byte Reload
77; ARM-NEXT:    asrs r6, r2, #31
78; ARM-NEXT:    mov r0, r7
79; ARM-NEXT:    mov r1, r4
80; ARM-NEXT:    mov r3, r6
81; ARM-NEXT:    bl __aeabi_lmul
82; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
83; ARM-NEXT:    adds r0, r0, r2
84; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
85; ARM-NEXT:    adcs r1, r4
86; ARM-NEXT:    asrs r7, r1, #31
87; ARM-NEXT:    adds r5, r5, r1
88; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
89; ARM-NEXT:    adcs r7, r0
90; ARM-NEXT:    ldr r0, [sp, #12] @ 4-byte Reload
91; ARM-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
92; ARM-NEXT:    ldr r2, [sp, #24] @ 4-byte Reload
93; ARM-NEXT:    mov r3, r6
94; ARM-NEXT:    bl __aeabi_lmul
95; ARM-NEXT:    adds r3, r0, r5
96; ARM-NEXT:    adcs r1, r7
97; ARM-NEXT:    rsbs r2, r1, #0
98; ARM-NEXT:    adcs r2, r1
99; ARM-NEXT:    movs r0, #1
100; ARM-NEXT:    cmp r3, #1
101; ARM-NEXT:    mov r5, r0
102; ARM-NEXT:    bhi .LBB1_2
103; ARM-NEXT:  @ %bb.1:
104; ARM-NEXT:    mov r5, r4
105; ARM-NEXT:  .LBB1_2:
106; ARM-NEXT:    ands r2, r5
107; ARM-NEXT:    cmp r1, #0
108; ARM-NEXT:    mov r5, r0
109; ARM-NEXT:    bgt .LBB1_4
110; ARM-NEXT:  @ %bb.3:
111; ARM-NEXT:    mov r5, r4
112; ARM-NEXT:  .LBB1_4:
113; ARM-NEXT:    orrs r5, r2
114; ARM-NEXT:    lsls r2, r3, #30
115; ARM-NEXT:    ldr r7, [sp, #16] @ 4-byte Reload
116; ARM-NEXT:    lsrs r6, r7, #2
117; ARM-NEXT:    adds r2, r2, r6
118; ARM-NEXT:    str r2, [sp, #24] @ 4-byte Spill
119; ARM-NEXT:    lsls r6, r7, #30
120; ARM-NEXT:    ldr r2, [sp, #20] @ 4-byte Reload
121; ARM-NEXT:    lsrs r7, r2, #2
122; ARM-NEXT:    adds r7, r6, r7
123; ARM-NEXT:    mvns r6, r4
124; ARM-NEXT:    cmp r5, #0
125; ARM-NEXT:    beq .LBB1_6
126; ARM-NEXT:  @ %bb.5:
127; ARM-NEXT:    ldr r2, .LCPI1_0
128; ARM-NEXT:    str r2, [sp, #24] @ 4-byte Spill
129; ARM-NEXT:  .LBB1_6:
130; ARM-NEXT:    mov r5, r6
131; ARM-NEXT:    bne .LBB1_8
132; ARM-NEXT:  @ %bb.7:
133; ARM-NEXT:    mov r5, r7
134; ARM-NEXT:  .LBB1_8:
135; ARM-NEXT:    adds r2, r1, #1
136; ARM-NEXT:    rsbs r7, r2, #0
137; ARM-NEXT:    adcs r7, r2
138; ARM-NEXT:    mvns r2, r0
139; ARM-NEXT:    cmp r3, r2
140; ARM-NEXT:    mov r3, r0
141; ARM-NEXT:    blo .LBB1_10
142; ARM-NEXT:  @ %bb.9:
143; ARM-NEXT:    mov r3, r4
144; ARM-NEXT:  .LBB1_10:
145; ARM-NEXT:    ands r7, r3
146; ARM-NEXT:    cmp r1, r6
147; ARM-NEXT:    mov r3, r0
148; ARM-NEXT:    blt .LBB1_12
149; ARM-NEXT:  @ %bb.11:
150; ARM-NEXT:    mov r3, r4
151; ARM-NEXT:  .LBB1_12:
152; ARM-NEXT:    orrs r3, r7
153; ARM-NEXT:    lsls r1, r0, #31
154; ARM-NEXT:    cmp r3, #0
155; ARM-NEXT:    bne .LBB1_14
156; ARM-NEXT:  @ %bb.13:
157; ARM-NEXT:    mov r4, r5
158; ARM-NEXT:  .LBB1_14:
159; ARM-NEXT:    bne .LBB1_16
160; ARM-NEXT:  @ %bb.15:
161; ARM-NEXT:    ldr r1, [sp, #24] @ 4-byte Reload
162; ARM-NEXT:  .LBB1_16:
163; ARM-NEXT:    mov r0, r4
164; ARM-NEXT:    add sp, #28
165; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
166; ARM-NEXT:    .p2align 2
167; ARM-NEXT:  @ %bb.17:
168; ARM-NEXT:  .LCPI1_0:
169; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
170  %tmp = call i64 @llvm.smul.fix.sat.i64(i64 %x, i64 %y, i32 2)
171  ret i64 %tmp
172}
173
174define i4 @func3(i4 %x, i4 %y) nounwind {
175; ARM-LABEL: func3:
176; ARM:       @ %bb.0:
177; ARM-NEXT:    .save {r4, lr}
178; ARM-NEXT:    push {r4, lr}
179; ARM-NEXT:    lsls r0, r0, #28
180; ARM-NEXT:    asrs r4, r0, #31
181; ARM-NEXT:    lsls r1, r1, #28
182; ARM-NEXT:    asrs r2, r1, #28
183; ARM-NEXT:    asrs r3, r1, #31
184; ARM-NEXT:    mov r1, r4
185; ARM-NEXT:    bl __aeabi_lmul
186; ARM-NEXT:    cmp r1, #1
187; ARM-NEXT:    bgt .LBB2_2
188; ARM-NEXT:  @ %bb.1:
189; ARM-NEXT:    lsrs r0, r0, #2
190; ARM-NEXT:    lsls r2, r1, #30
191; ARM-NEXT:    adds r0, r2, r0
192; ARM-NEXT:    b .LBB2_3
193; ARM-NEXT:  .LBB2_2:
194; ARM-NEXT:    ldr r0, .LCPI2_0
195; ARM-NEXT:  .LBB2_3:
196; ARM-NEXT:    movs r2, #1
197; ARM-NEXT:    mvns r3, r2
198; ARM-NEXT:    cmp r1, r3
199; ARM-NEXT:    bge .LBB2_5
200; ARM-NEXT:  @ %bb.4:
201; ARM-NEXT:    lsls r0, r2, #31
202; ARM-NEXT:  .LBB2_5:
203; ARM-NEXT:    asrs r0, r0, #28
204; ARM-NEXT:    pop {r4, pc}
205; ARM-NEXT:    .p2align 2
206; ARM-NEXT:  @ %bb.6:
207; ARM-NEXT:  .LCPI2_0:
208; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
209  %tmp = call i4 @llvm.smul.fix.sat.i4(i4 %x, i4 %y, i32 2)
210  ret i4 %tmp
211}
212
213;; These result in regular integer multiplication with a saturation check.
214define i32 @func4(i32 %x, i32 %y) nounwind {
215; ARM-LABEL: func4:
216; ARM:       @ %bb.0:
217; ARM-NEXT:    .save {r7, lr}
218; ARM-NEXT:    push {r7, lr}
219; ARM-NEXT:    mov r2, r1
220; ARM-NEXT:    asrs r1, r0, #31
221; ARM-NEXT:    asrs r3, r2, #31
222; ARM-NEXT:    bl __aeabi_lmul
223; ARM-NEXT:    cmp r1, #0
224; ARM-NEXT:    bmi .LBB3_2
225; ARM-NEXT:  @ %bb.1:
226; ARM-NEXT:    ldr r2, .LCPI3_0
227; ARM-NEXT:    b .LBB3_3
228; ARM-NEXT:  .LBB3_2:
229; ARM-NEXT:    movs r2, #1
230; ARM-NEXT:    lsls r2, r2, #31
231; ARM-NEXT:  .LBB3_3:
232; ARM-NEXT:    asrs r3, r0, #31
233; ARM-NEXT:    cmp r1, r3
234; ARM-NEXT:    bne .LBB3_5
235; ARM-NEXT:  @ %bb.4:
236; ARM-NEXT:    mov r2, r0
237; ARM-NEXT:  .LBB3_5:
238; ARM-NEXT:    mov r0, r2
239; ARM-NEXT:    pop {r7, pc}
240; ARM-NEXT:    .p2align 2
241; ARM-NEXT:  @ %bb.6:
242; ARM-NEXT:  .LCPI3_0:
243; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
244  %tmp = call i32 @llvm.smul.fix.sat.i32(i32 %x, i32 %y, i32 0)
245  ret i32 %tmp
246}
247
248define i64 @func5(i64 %x, i64 %y) {
249; ARM-LABEL: func5:
250; ARM:       @ %bb.0:
251; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
252; ARM-NEXT:    push {r4, r5, r6, r7, lr}
253; ARM-NEXT:    .pad #28
254; ARM-NEXT:    sub sp, #28
255; ARM-NEXT:    str r3, [sp, #24] @ 4-byte Spill
256; ARM-NEXT:    str r2, [sp, #12] @ 4-byte Spill
257; ARM-NEXT:    mov r5, r1
258; ARM-NEXT:    mov r4, r0
259; ARM-NEXT:    str r0, [sp, #8] @ 4-byte Spill
260; ARM-NEXT:    asrs r1, r1, #31
261; ARM-NEXT:    str r1, [sp, #20] @ 4-byte Spill
262; ARM-NEXT:    movs r6, #0
263; ARM-NEXT:    mov r0, r5
264; ARM-NEXT:    mov r3, r6
265; ARM-NEXT:    bl __aeabi_lmul
266; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
267; ARM-NEXT:    mov r7, r1
268; ARM-NEXT:    mov r0, r4
269; ARM-NEXT:    mov r1, r6
270; ARM-NEXT:    ldr r2, [sp, #12] @ 4-byte Reload
271; ARM-NEXT:    mov r3, r6
272; ARM-NEXT:    bl __aeabi_lmul
273; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
274; ARM-NEXT:    ldr r0, [sp, #16] @ 4-byte Reload
275; ARM-NEXT:    adds r0, r0, r1
276; ARM-NEXT:    str r0, [sp, #12] @ 4-byte Spill
277; ARM-NEXT:    adcs r7, r6
278; ARM-NEXT:    asrs r0, r7, #31
279; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
280; ARM-NEXT:    ldr r2, [sp, #24] @ 4-byte Reload
281; ARM-NEXT:    asrs r4, r2, #31
282; ARM-NEXT:    ldr r0, [sp, #8] @ 4-byte Reload
283; ARM-NEXT:    mov r1, r6
284; ARM-NEXT:    mov r3, r4
285; ARM-NEXT:    bl __aeabi_lmul
286; ARM-NEXT:    ldr r2, [sp, #12] @ 4-byte Reload
287; ARM-NEXT:    adds r0, r0, r2
288; ARM-NEXT:    str r0, [sp, #12] @ 4-byte Spill
289; ARM-NEXT:    adcs r1, r6
290; ARM-NEXT:    asrs r6, r1, #31
291; ARM-NEXT:    adds r0, r7, r1
292; ARM-NEXT:    str r0, [sp, #8] @ 4-byte Spill
293; ARM-NEXT:    ldr r0, [sp, #16] @ 4-byte Reload
294; ARM-NEXT:    adcs r6, r0
295; ARM-NEXT:    mov r0, r5
296; ARM-NEXT:    ldr r1, [sp, #20] @ 4-byte Reload
297; ARM-NEXT:    ldr r7, [sp, #24] @ 4-byte Reload
298; ARM-NEXT:    mov r2, r7
299; ARM-NEXT:    mov r3, r4
300; ARM-NEXT:    bl __aeabi_lmul
301; ARM-NEXT:    ldr r3, [sp, #12] @ 4-byte Reload
302; ARM-NEXT:    ldr r2, [sp, #8] @ 4-byte Reload
303; ARM-NEXT:    adds r2, r0, r2
304; ARM-NEXT:    adcs r1, r6
305; ARM-NEXT:    asrs r0, r3, #31
306; ARM-NEXT:    eors r1, r0
307; ARM-NEXT:    eors r2, r0
308; ARM-NEXT:    orrs r2, r1
309; ARM-NEXT:    eors r5, r7
310; ARM-NEXT:    asrs r0, r5, #31
311; ARM-NEXT:    ldr r1, .LCPI4_0
312; ARM-NEXT:    eors r1, r0
313; ARM-NEXT:    mvns r0, r0
314; ARM-NEXT:    cmp r2, #0
315; ARM-NEXT:    beq .LBB4_3
316; ARM-NEXT:  @ %bb.1:
317; ARM-NEXT:    beq .LBB4_4
318; ARM-NEXT:  .LBB4_2:
319; ARM-NEXT:    add sp, #28
320; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
321; ARM-NEXT:  .LBB4_3:
322; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
323; ARM-NEXT:    bne .LBB4_2
324; ARM-NEXT:  .LBB4_4:
325; ARM-NEXT:    mov r1, r3
326; ARM-NEXT:    add sp, #28
327; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
328; ARM-NEXT:    .p2align 2
329; ARM-NEXT:  @ %bb.5:
330; ARM-NEXT:  .LCPI4_0:
331; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
332  %tmp = call i64 @llvm.smul.fix.sat.i64(i64 %x, i64 %y, i32 0)
333  ret i64 %tmp
334}
335
336define i4 @func6(i4 %x, i4 %y) nounwind {
337; ARM-LABEL: func6:
338; ARM:       @ %bb.0:
339; ARM-NEXT:    .save {r4, lr}
340; ARM-NEXT:    push {r4, lr}
341; ARM-NEXT:    lsls r0, r0, #28
342; ARM-NEXT:    asrs r4, r0, #31
343; ARM-NEXT:    lsls r1, r1, #28
344; ARM-NEXT:    asrs r2, r1, #28
345; ARM-NEXT:    asrs r3, r1, #31
346; ARM-NEXT:    mov r1, r4
347; ARM-NEXT:    bl __aeabi_lmul
348; ARM-NEXT:    cmp r1, #0
349; ARM-NEXT:    bmi .LBB5_2
350; ARM-NEXT:  @ %bb.1:
351; ARM-NEXT:    ldr r2, .LCPI5_0
352; ARM-NEXT:    b .LBB5_3
353; ARM-NEXT:  .LBB5_2:
354; ARM-NEXT:    movs r2, #1
355; ARM-NEXT:    lsls r2, r2, #31
356; ARM-NEXT:  .LBB5_3:
357; ARM-NEXT:    asrs r3, r0, #31
358; ARM-NEXT:    cmp r1, r3
359; ARM-NEXT:    bne .LBB5_5
360; ARM-NEXT:  @ %bb.4:
361; ARM-NEXT:    mov r2, r0
362; ARM-NEXT:  .LBB5_5:
363; ARM-NEXT:    asrs r0, r2, #28
364; ARM-NEXT:    pop {r4, pc}
365; ARM-NEXT:    .p2align 2
366; ARM-NEXT:  @ %bb.6:
367; ARM-NEXT:  .LCPI5_0:
368; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
369  %tmp = call i4 @llvm.smul.fix.sat.i4(i4 %x, i4 %y, i32 0)
370  ret i4 %tmp
371}
372
373define i64 @func7(i64 %x, i64 %y) nounwind {
374; ARM-LABEL: func7:
375; ARM:       @ %bb.0:
376; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
377; ARM-NEXT:    push {r4, r5, r6, r7, lr}
378; ARM-NEXT:    .pad #20
379; ARM-NEXT:    sub sp, #20
380; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
381; ARM-NEXT:    mov r5, r2
382; ARM-NEXT:    mov r2, r1
383; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
384; ARM-NEXT:    mov r6, r0
385; ARM-NEXT:    asrs r1, r1, #31
386; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
387; ARM-NEXT:    movs r4, #0
388; ARM-NEXT:    mov r0, r2
389; ARM-NEXT:    mov r2, r5
390; ARM-NEXT:    mov r3, r4
391; ARM-NEXT:    bl __aeabi_lmul
392; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
393; ARM-NEXT:    mov r7, r1
394; ARM-NEXT:    mov r0, r6
395; ARM-NEXT:    mov r1, r4
396; ARM-NEXT:    mov r2, r5
397; ARM-NEXT:    mov r3, r4
398; ARM-NEXT:    bl __aeabi_lmul
399; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
400; ARM-NEXT:    adds r0, r0, r1
401; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
402; ARM-NEXT:    adcs r7, r4
403; ARM-NEXT:    asrs r0, r7, #31
404; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
405; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
406; ARM-NEXT:    asrs r5, r2, #31
407; ARM-NEXT:    mov r0, r6
408; ARM-NEXT:    mov r1, r4
409; ARM-NEXT:    mov r3, r5
410; ARM-NEXT:    bl __aeabi_lmul
411; ARM-NEXT:    ldr r2, [sp] @ 4-byte Reload
412; ARM-NEXT:    adds r0, r0, r2
413; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
414; ARM-NEXT:    adcs r1, r4
415; ARM-NEXT:    asrs r6, r1, #31
416; ARM-NEXT:    adds r7, r7, r1
417; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
418; ARM-NEXT:    adcs r6, r0
419; ARM-NEXT:    ldr r0, [sp, #12] @ 4-byte Reload
420; ARM-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
421; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
422; ARM-NEXT:    mov r3, r5
423; ARM-NEXT:    bl __aeabi_lmul
424; ARM-NEXT:    adds r0, r0, r7
425; ARM-NEXT:    adcs r1, r6
426; ARM-NEXT:    rsbs r5, r1, #0
427; ARM-NEXT:    adcs r5, r1
428; ARM-NEXT:    movs r2, #1
429; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
430; ARM-NEXT:    cmp r0, #0
431; ARM-NEXT:    mov r3, r2
432; ARM-NEXT:    bge .LBB6_2
433; ARM-NEXT:  @ %bb.1:
434; ARM-NEXT:    mov r3, r4
435; ARM-NEXT:  .LBB6_2:
436; ARM-NEXT:    mov r6, r2
437; ARM-NEXT:    bmi .LBB6_4
438; ARM-NEXT:  @ %bb.3:
439; ARM-NEXT:    mov r6, r4
440; ARM-NEXT:  .LBB6_4:
441; ARM-NEXT:    ands r5, r6
442; ARM-NEXT:    cmp r1, #0
443; ARM-NEXT:    mov r7, r2
444; ARM-NEXT:    bgt .LBB6_6
445; ARM-NEXT:  @ %bb.5:
446; ARM-NEXT:    mov r7, r4
447; ARM-NEXT:  .LBB6_6:
448; ARM-NEXT:    orrs r7, r5
449; ARM-NEXT:    mvns r6, r4
450; ARM-NEXT:    cmp r7, #0
451; ARM-NEXT:    beq .LBB6_8
452; ARM-NEXT:  @ %bb.7:
453; ARM-NEXT:    ldr r0, .LCPI6_0
454; ARM-NEXT:    str r0, [sp, #16] @ 4-byte Spill
455; ARM-NEXT:  .LBB6_8:
456; ARM-NEXT:    mov r5, r6
457; ARM-NEXT:    bne .LBB6_10
458; ARM-NEXT:  @ %bb.9:
459; ARM-NEXT:    ldr r5, [sp] @ 4-byte Reload
460; ARM-NEXT:  .LBB6_10:
461; ARM-NEXT:    adds r0, r1, #1
462; ARM-NEXT:    rsbs r7, r0, #0
463; ARM-NEXT:    adcs r7, r0
464; ARM-NEXT:    ands r7, r3
465; ARM-NEXT:    cmp r1, r6
466; ARM-NEXT:    mov r3, r2
467; ARM-NEXT:    blt .LBB6_12
468; ARM-NEXT:  @ %bb.11:
469; ARM-NEXT:    mov r3, r4
470; ARM-NEXT:  .LBB6_12:
471; ARM-NEXT:    orrs r3, r7
472; ARM-NEXT:    lsls r1, r2, #31
473; ARM-NEXT:    cmp r3, #0
474; ARM-NEXT:    bne .LBB6_14
475; ARM-NEXT:  @ %bb.13:
476; ARM-NEXT:    mov r4, r5
477; ARM-NEXT:  .LBB6_14:
478; ARM-NEXT:    bne .LBB6_16
479; ARM-NEXT:  @ %bb.15:
480; ARM-NEXT:    ldr r1, [sp, #16] @ 4-byte Reload
481; ARM-NEXT:  .LBB6_16:
482; ARM-NEXT:    mov r0, r4
483; ARM-NEXT:    add sp, #20
484; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
485; ARM-NEXT:    .p2align 2
486; ARM-NEXT:  @ %bb.17:
487; ARM-NEXT:  .LCPI6_0:
488; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
489  %tmp = call i64 @llvm.smul.fix.sat.i64(i64 %x, i64 %y, i32 32)
490  ret i64 %tmp
491}
492
493define i64 @func8(i64 %x, i64 %y) nounwind {
494; ARM-LABEL: func8:
495; ARM:       @ %bb.0:
496; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
497; ARM-NEXT:    push {r4, r5, r6, r7, lr}
498; ARM-NEXT:    .pad #20
499; ARM-NEXT:    sub sp, #20
500; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
501; ARM-NEXT:    mov r5, r2
502; ARM-NEXT:    mov r2, r1
503; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
504; ARM-NEXT:    mov r6, r0
505; ARM-NEXT:    asrs r1, r1, #31
506; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
507; ARM-NEXT:    movs r4, #0
508; ARM-NEXT:    mov r0, r2
509; ARM-NEXT:    mov r2, r5
510; ARM-NEXT:    mov r3, r4
511; ARM-NEXT:    bl __aeabi_lmul
512; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
513; ARM-NEXT:    mov r7, r1
514; ARM-NEXT:    mov r0, r6
515; ARM-NEXT:    mov r1, r4
516; ARM-NEXT:    mov r2, r5
517; ARM-NEXT:    mov r3, r4
518; ARM-NEXT:    bl __aeabi_lmul
519; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
520; ARM-NEXT:    adds r0, r0, r1
521; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
522; ARM-NEXT:    adcs r7, r4
523; ARM-NEXT:    asrs r0, r7, #31
524; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
525; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
526; ARM-NEXT:    asrs r5, r2, #31
527; ARM-NEXT:    mov r0, r6
528; ARM-NEXT:    mov r1, r4
529; ARM-NEXT:    mov r3, r5
530; ARM-NEXT:    bl __aeabi_lmul
531; ARM-NEXT:    ldr r2, [sp, #4] @ 4-byte Reload
532; ARM-NEXT:    adds r0, r0, r2
533; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
534; ARM-NEXT:    adcs r1, r4
535; ARM-NEXT:    asrs r6, r1, #31
536; ARM-NEXT:    adds r7, r7, r1
537; ARM-NEXT:    ldr r0, [sp] @ 4-byte Reload
538; ARM-NEXT:    adcs r6, r0
539; ARM-NEXT:    ldr r0, [sp, #12] @ 4-byte Reload
540; ARM-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
541; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
542; ARM-NEXT:    mov r3, r5
543; ARM-NEXT:    bl __aeabi_lmul
544; ARM-NEXT:    adds r2, r0, r7
545; ARM-NEXT:    adcs r1, r6
546; ARM-NEXT:    lsls r0, r1, #1
547; ARM-NEXT:    lsrs r3, r2, #31
548; ARM-NEXT:    adds r0, r0, r3
549; ARM-NEXT:    lsls r2, r2, #1
550; ARM-NEXT:    ldr r3, [sp, #4] @ 4-byte Reload
551; ARM-NEXT:    lsrs r3, r3, #31
552; ARM-NEXT:    adds r2, r2, r3
553; ARM-NEXT:    mvns r3, r4
554; ARM-NEXT:    ldr r5, .LCPI7_1
555; ARM-NEXT:    cmp r1, r5
556; ARM-NEXT:    ble .LBB7_2
557; ARM-NEXT:  @ %bb.1:
558; ARM-NEXT:    ldr r0, .LCPI7_0
559; ARM-NEXT:  .LBB7_2:
560; ARM-NEXT:    bgt .LBB7_4
561; ARM-NEXT:  @ %bb.3:
562; ARM-NEXT:    mov r3, r2
563; ARM-NEXT:  .LBB7_4:
564; ARM-NEXT:    movs r2, #1
565; ARM-NEXT:    lsls r2, r2, #31
566; ARM-NEXT:    movs r5, #3
567; ARM-NEXT:    lsls r5, r5, #30
568; ARM-NEXT:    cmp r1, r5
569; ARM-NEXT:    blt .LBB7_6
570; ARM-NEXT:  @ %bb.5:
571; ARM-NEXT:    mov r4, r3
572; ARM-NEXT:  .LBB7_6:
573; ARM-NEXT:    blt .LBB7_8
574; ARM-NEXT:  @ %bb.7:
575; ARM-NEXT:    mov r2, r0
576; ARM-NEXT:  .LBB7_8:
577; ARM-NEXT:    mov r0, r4
578; ARM-NEXT:    mov r1, r2
579; ARM-NEXT:    add sp, #20
580; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
581; ARM-NEXT:    .p2align 2
582; ARM-NEXT:  @ %bb.9:
583; ARM-NEXT:  .LCPI7_0:
584; ARM-NEXT:    .long 2147483647 @ 0x7fffffff
585; ARM-NEXT:  .LCPI7_1:
586; ARM-NEXT:    .long 1073741823 @ 0x3fffffff
587  %tmp = call i64 @llvm.smul.fix.sat.i64(i64 %x, i64 %y, i32 63)
588  ret i64 %tmp
589}
590