1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=thumbv7k-linux-gnu | FileCheck %s
4 declare {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
5 declare {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64>, <2 x i64>)
6 declare {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
7 declare {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64>, <2 x i64>)
9 define <2 x i1> @uaddo(ptr %ptr, ptr %ptr2) {
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
25 ; CHECK-NEXT: movlo r2, #1
26 ; CHECK-NEXT: cmp r2, #0
28 ; CHECK-NEXT: movne.w r2, #-1
29 ; CHECK-NEXT: subs r3, r4, r6
30 ; CHECK-NEXT: sbcs.w r3, r5, r7
32 ; CHECK-NEXT: movlo r1, #1
33 ; CHECK-NEXT: cmp r1, #0
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
48 define <2 x i1> @usubo(ptr %ptr, ptr %ptr2) {
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
64 ; CHECK-NEXT: movlo r2, #1
65 ; CHECK-NEXT: cmp r2, #0
67 ; CHECK-NEXT: movne.w r2, #-1
68 ; CHECK-NEXT: subs r3, r4, r6
69 ; CHECK-NEXT: sbcs.w r3, r5, r7
71 ; CHECK-NEXT: movlo r1, #1
72 ; CHECK-NEXT: cmp r1, #0
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
87 define <2 x i1> @saddo(ptr %ptr, ptr %ptr2) {
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
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
112 define <2 x i1> @ssubo(ptr %ptr, ptr %ptr2) {
113 ; CHECK-LABEL: ssubo:
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
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