xref: /llvm-project/llvm/test/CodeGen/ARM/addsubo-legalization.ll (revision 7b3bbd83c0c24087072ec5b22a76799ab31f87d5)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv7k-linux-gnu | FileCheck %s
3
4declare {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
5declare {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64>, <2 x i64>)
6declare {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
7declare {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64>, <2 x i64>)
8
9define <2 x i1> @uaddo(ptr %ptr, ptr %ptr2) {
10; CHECK-LABEL: uaddo:
11; CHECK:       @ %bb.0:
12; CHECK-NEXT:    push {r4, r5, r6, r7, lr}
13; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
14; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
15; CHECK-NEXT:    vmov r3, r2, d18
16; CHECK-NEXT:    vadd.i64 q8, q9, q8
17; CHECK-NEXT:    movs r1, #0
18; CHECK-NEXT:    vmov r6, r7, d19
19; CHECK-NEXT:    vmov lr, r12, d16
20; CHECK-NEXT:    vmov r4, r5, d17
21; CHECK-NEXT:    subs.w r3, lr, r3
22; CHECK-NEXT:    sbcs.w r2, r12, r2
23; CHECK-NEXT:    mov.w r2, #0
24; CHECK-NEXT:    it lo
25; CHECK-NEXT:    movlo r2, #1
26; CHECK-NEXT:    cmp r2, #0
27; CHECK-NEXT:    it ne
28; CHECK-NEXT:    movne.w r2, #-1
29; CHECK-NEXT:    subs r3, r4, r6
30; CHECK-NEXT:    sbcs.w r3, r5, r7
31; CHECK-NEXT:    it lo
32; CHECK-NEXT:    movlo r1, #1
33; CHECK-NEXT:    cmp r1, #0
34; CHECK-NEXT:    it ne
35; CHECK-NEXT:    movne.w r1, #-1
36; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
37; CHECK-NEXT:    mov r0, r2
38; CHECK-NEXT:    pop {r4, r5, r6, r7, pc}
39  %x = load <2 x i64>, ptr %ptr, align 8
40  %y = load <2 x i64>, ptr %ptr2, align 8
41  %s = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
42  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
43  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
44  store <2 x i64> %m, ptr %ptr
45  ret <2 x i1> %o
46}
47
48define <2 x i1> @usubo(ptr %ptr, ptr %ptr2) {
49; CHECK-LABEL: usubo:
50; CHECK:       @ %bb.0:
51; CHECK-NEXT:    push {r4, r5, r6, r7, lr}
52; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
53; CHECK-NEXT:    movs r1, #0
54; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
55; CHECK-NEXT:    vsub.i64 q8, q9, q8
56; CHECK-NEXT:    vmov lr, r12, d18
57; CHECK-NEXT:    vmov r4, r5, d19
58; CHECK-NEXT:    vmov r3, r2, d16
59; CHECK-NEXT:    vmov r6, r7, d17
60; CHECK-NEXT:    subs.w r3, lr, r3
61; CHECK-NEXT:    sbcs.w r2, r12, r2
62; CHECK-NEXT:    mov.w r2, #0
63; CHECK-NEXT:    it lo
64; CHECK-NEXT:    movlo r2, #1
65; CHECK-NEXT:    cmp r2, #0
66; CHECK-NEXT:    it ne
67; CHECK-NEXT:    movne.w r2, #-1
68; CHECK-NEXT:    subs r3, r4, r6
69; CHECK-NEXT:    sbcs.w r3, r5, r7
70; CHECK-NEXT:    it lo
71; CHECK-NEXT:    movlo r1, #1
72; CHECK-NEXT:    cmp r1, #0
73; CHECK-NEXT:    it ne
74; CHECK-NEXT:    movne.w r1, #-1
75; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
76; CHECK-NEXT:    mov r0, r2
77; CHECK-NEXT:    pop {r4, r5, r6, r7, pc}
78  %x = load <2 x i64>, ptr %ptr, align 8
79  %y = load <2 x i64>, ptr %ptr2, align 8
80  %s = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
81  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
82  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
83  store <2 x i64> %m, ptr %ptr
84  ret <2 x i1> %o
85}
86
87define <2 x i1> @saddo(ptr %ptr, ptr %ptr2) {
88; CHECK-LABEL: saddo:
89; CHECK:       @ %bb.0:
90; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
91; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
92; CHECK-NEXT:    vqadd.s64 q10, q9, q8
93; CHECK-NEXT:    vadd.i64 q8, q9, q8
94; CHECK-NEXT:    vceq.i32 q9, q8, q10
95; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
96; CHECK-NEXT:    vrev64.32 q10, q9
97; CHECK-NEXT:    vand q9, q9, q10
98; CHECK-NEXT:    vmvn q9, q9
99; CHECK-NEXT:    vmovn.i64 d18, q9
100; CHECK-NEXT:    vmov r2, r1, d18
101; CHECK-NEXT:    mov r0, r2
102; CHECK-NEXT:    bx lr
103  %x = load <2 x i64>, ptr %ptr, align 8
104  %y = load <2 x i64>, ptr %ptr2, align 8
105  %s = call {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
106  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
107  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
108  store <2 x i64> %m, ptr %ptr
109  ret <2 x i1> %o
110}
111
112define <2 x i1> @ssubo(ptr %ptr, ptr %ptr2) {
113; CHECK-LABEL: ssubo:
114; CHECK:       @ %bb.0:
115; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
116; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
117; CHECK-NEXT:    vqsub.s64 q10, q9, q8
118; CHECK-NEXT:    vsub.i64 q8, q9, q8
119; CHECK-NEXT:    vceq.i32 q9, q8, q10
120; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
121; CHECK-NEXT:    vrev64.32 q10, q9
122; CHECK-NEXT:    vand q9, q9, q10
123; CHECK-NEXT:    vmvn q9, q9
124; CHECK-NEXT:    vmovn.i64 d18, q9
125; CHECK-NEXT:    vmov r2, r1, d18
126; CHECK-NEXT:    mov r0, r2
127; CHECK-NEXT:    bx lr
128  %x = load <2 x i64>, ptr %ptr, align 8
129  %y = load <2 x i64>, ptr %ptr2, align 8
130  %s = call {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
131  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
132  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
133  store <2 x i64> %m, ptr %ptr
134  ret <2 x i1> %o
135}
136