summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/ARM/addsubo-legalization.ll
blob: e3a48ed0c14f1d91eb45caaa760ff88fb1064cb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=thumbv7k-linux-gnu | FileCheck %s

declare {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
declare {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64>, <2 x i64>)
declare {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64>, <2 x i64>)
declare {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64>, <2 x i64>)

define <2 x i1> @uaddo(<2 x i64> *%ptr, <2 x i64> *%ptr2) {
; CHECK-LABEL: uaddo:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    push {r4, r5, r6, r7, lr}
; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
; CHECK-NEXT:    movs r1, #0
; CHECK-NEXT:    vadd.i64 q8, q9, q8
; CHECK-NEXT:    vmov.32 r3, d18[0]
; CHECK-NEXT:    vmov.32 r2, d18[1]
; CHECK-NEXT:    vmov.32 r12, d16[0]
; CHECK-NEXT:    vmov.32 lr, d16[1]
; CHECK-NEXT:    vmov.32 r4, d17[0]
; CHECK-NEXT:    vmov.32 r5, d19[0]
; CHECK-NEXT:    vmov.32 r6, d17[1]
; CHECK-NEXT:    vmov.32 r7, d19[1]
; CHECK-NEXT:    subs.w r3, r12, r3
; CHECK-NEXT:    sbcs.w r2, lr, r2
; CHECK-NEXT:    mov.w r2, #0
; CHECK-NEXT:    it lo
; CHECK-NEXT:    movlo r2, #1
; CHECK-NEXT:    cmp r2, #0
; CHECK-NEXT:    it ne
; CHECK-NEXT:    movne.w r2, #-1
; CHECK-NEXT:    subs r3, r4, r5
; CHECK-NEXT:    sbcs.w r3, r6, r7
; CHECK-NEXT:    it lo
; CHECK-NEXT:    movlo r1, #1
; CHECK-NEXT:    cmp r1, #0
; CHECK-NEXT:    it ne
; CHECK-NEXT:    movne.w r1, #-1
; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
; CHECK-NEXT:    mov r0, r2
; CHECK-NEXT:    pop {r4, r5, r6, r7, pc}
  %x = load <2 x i64>, <2 x i64>* %ptr, align 8
  %y = load <2 x i64>, <2 x i64>* %ptr2, align 8
  %s = call {<2 x i64>, <2 x i1>} @llvm.uadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
  store <2 x i64> %m, <2 x i64>* %ptr
  ret <2 x i1> %o
}

define <2 x i1> @usubo(<2 x i64> *%ptr, <2 x i64> *%ptr2) {
; CHECK-LABEL: usubo:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    push {r4, r5, r6, r7, lr}
; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
; CHECK-NEXT:    movs r1, #0
; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
; CHECK-NEXT:    vsub.i64 q8, q9, q8
; CHECK-NEXT:    vmov.32 r12, d18[0]
; CHECK-NEXT:    vmov.32 lr, d18[1]
; CHECK-NEXT:    vmov.32 r3, d16[0]
; CHECK-NEXT:    vmov.32 r2, d16[1]
; CHECK-NEXT:    vmov.32 r4, d19[0]
; CHECK-NEXT:    vmov.32 r5, d17[0]
; CHECK-NEXT:    vmov.32 r6, d19[1]
; CHECK-NEXT:    vmov.32 r7, d17[1]
; CHECK-NEXT:    subs.w r3, r12, r3
; CHECK-NEXT:    sbcs.w r2, lr, r2
; CHECK-NEXT:    mov.w r2, #0
; CHECK-NEXT:    it lo
; CHECK-NEXT:    movlo r2, #1
; CHECK-NEXT:    cmp r2, #0
; CHECK-NEXT:    it ne
; CHECK-NEXT:    movne.w r2, #-1
; CHECK-NEXT:    subs r3, r4, r5
; CHECK-NEXT:    sbcs.w r3, r6, r7
; CHECK-NEXT:    it lo
; CHECK-NEXT:    movlo r1, #1
; CHECK-NEXT:    cmp r1, #0
; CHECK-NEXT:    it ne
; CHECK-NEXT:    movne.w r1, #-1
; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
; CHECK-NEXT:    mov r0, r2
; CHECK-NEXT:    pop {r4, r5, r6, r7, pc}
  %x = load <2 x i64>, <2 x i64>* %ptr, align 8
  %y = load <2 x i64>, <2 x i64>* %ptr2, align 8
  %s = call {<2 x i64>, <2 x i1>} @llvm.usub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
  store <2 x i64> %m, <2 x i64>* %ptr
  ret <2 x i1> %o
}

define <2 x i1> @saddo(<2 x i64> *%ptr, <2 x i64> *%ptr2) {
; CHECK-LABEL: saddo:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
; CHECK-NEXT:    vqadd.s64 q10, q9, q8
; CHECK-NEXT:    vadd.i64 q8, q9, q8
; CHECK-NEXT:    vceq.i32 q9, q8, q10
; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
; CHECK-NEXT:    vrev64.32 q10, q9
; CHECK-NEXT:    vand q9, q9, q10
; CHECK-NEXT:    vmvn q9, q9
; CHECK-NEXT:    vmovn.i64 d18, q9
; CHECK-NEXT:    vmov r2, r1, d18
; CHECK-NEXT:    mov r0, r2
; CHECK-NEXT:    bx lr
  %x = load <2 x i64>, <2 x i64>* %ptr, align 8
  %y = load <2 x i64>, <2 x i64>* %ptr2, align 8
  %s = call {<2 x i64>, <2 x i1>} @llvm.sadd.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
  store <2 x i64> %m, <2 x i64>* %ptr
  ret <2 x i1> %o
}

define <2 x i1> @ssubo(<2 x i64> *%ptr, <2 x i64> *%ptr2) {
; CHECK-LABEL: ssubo:
; CHECK:       @ %bb.0:
; CHECK-NEXT:    vld1.64 {d16, d17}, [r1]
; CHECK-NEXT:    vld1.64 {d18, d19}, [r0]
; CHECK-NEXT:    vqsub.s64 q10, q9, q8
; CHECK-NEXT:    vsub.i64 q8, q9, q8
; CHECK-NEXT:    vceq.i32 q9, q8, q10
; CHECK-NEXT:    vst1.64 {d16, d17}, [r0]
; CHECK-NEXT:    vrev64.32 q10, q9
; CHECK-NEXT:    vand q9, q9, q10
; CHECK-NEXT:    vmvn q9, q9
; CHECK-NEXT:    vmovn.i64 d18, q9
; CHECK-NEXT:    vmov r2, r1, d18
; CHECK-NEXT:    mov r0, r2
; CHECK-NEXT:    bx lr
  %x = load <2 x i64>, <2 x i64>* %ptr, align 8
  %y = load <2 x i64>, <2 x i64>* %ptr2, align 8
  %s = call {<2 x i64>, <2 x i1>} @llvm.ssub.with.overflow.v2i64(<2 x i64> %x, <2 x i64> %y)
  %m = extractvalue {<2 x i64>, <2 x i1>} %s, 0
  %o = extractvalue {<2 x i64>, <2 x i1>} %s, 1
  store <2 x i64> %m, <2 x i64>* %ptr
  ret <2 x i1> %o
}
OpenPOWER on IntegriCloud