ARM64: initial backend import
[oota-llvm.git] / test / CodeGen / ARM64 / vaddv.ll
1 ; RUN: llc -march=arm64 -arm64-neon-syntax=apple < %s | FileCheck %s
2
3 define signext i8 @test_vaddv_s8(<8 x i8> %a1) {
4 ; CHECK-LABEL: test_vaddv_s8:
5 ; CHECK: addv.8b b[[REGNUM:[0-9]+]], v0
6 ; CHECK-NEXT: smov.b w0, v[[REGNUM]][0]
7 ; CHECK-NEXT: ret
8 entry:
9   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v8i8(<8 x i8> %a1)
10   %0 = trunc i32 %vaddv.i to i8
11   ret i8 %0
12 }
13
14 define signext i16 @test_vaddv_s16(<4 x i16> %a1) {
15 ; CHECK-LABEL: test_vaddv_s16:
16 ; CHECK: addv.4h h[[REGNUM:[0-9]+]], v0
17 ; CHECK-NEXT: smov.h w0, v[[REGNUM]][0]
18 ; CHECK-NEXT: ret
19 entry:
20   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v4i16(<4 x i16> %a1)
21   %0 = trunc i32 %vaddv.i to i16
22   ret i16 %0
23 }
24
25 define i32 @test_vaddv_s32(<2 x i32> %a1) {
26 ; CHECK-LABEL: test_vaddv_s32:
27 ; 2 x i32 is not supported by the ISA, thus, this is a special case
28 ; CHECK: addp.2s v[[REGNUM:[0-9]+]], v0, v0
29 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
30 ; CHECK-NEXT: ret
31 entry:
32   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v2i32(<2 x i32> %a1)
33   ret i32 %vaddv.i
34 }
35
36 define i64 @test_vaddv_s64(<2 x i64> %a1) {
37 ; CHECK-LABEL: test_vaddv_s64:
38 ; CHECK: addp.2d [[REGNUM:d[0-9]+]], v0
39 ; CHECK-NEXT: fmov x0, [[REGNUM]]
40 ; CHECK-NEXT: ret
41 entry:
42   %vaddv.i = tail call i64 @llvm.arm64.neon.saddv.i64.v2i64(<2 x i64> %a1)
43   ret i64 %vaddv.i
44 }
45
46 define zeroext i8 @test_vaddv_u8(<8 x i8> %a1) {
47 ; CHECK-LABEL: test_vaddv_u8:
48 ; CHECK: addv.8b b[[REGNUM:[0-9]+]], v0
49 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
50 ; CHECK-NEXT: ret
51 entry:
52   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v8i8(<8 x i8> %a1)
53   %0 = trunc i32 %vaddv.i to i8
54   ret i8 %0
55 }
56
57 define i32 @test_vaddv_u8_masked(<8 x i8> %a1) {
58 ; CHECK-LABEL: test_vaddv_u8_masked:
59 ; CHECK: addv.8b b[[REGNUM:[0-9]+]], v0
60 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
61 ; CHECK-NEXT: ret
62 entry:
63   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v8i8(<8 x i8> %a1)
64   %0 = and i32 %vaddv.i, 511 ; 0x1ff
65   ret i32 %0
66 }
67
68 define zeroext i16 @test_vaddv_u16(<4 x i16> %a1) {
69 ; CHECK-LABEL: test_vaddv_u16:
70 ; CHECK: addv.4h h[[REGNUM:[0-9]+]], v0
71 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
72 ; CHECK-NEXT: ret
73 entry:
74   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v4i16(<4 x i16> %a1)
75   %0 = trunc i32 %vaddv.i to i16
76   ret i16 %0
77 }
78
79 define i32 @test_vaddv_u16_masked(<4 x i16> %a1) {
80 ; CHECK-LABEL: test_vaddv_u16_masked:
81 ; CHECK: addv.4h h[[REGNUM:[0-9]+]], v0
82 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
83 ; CHECK-NEXT: ret
84 entry:
85   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v4i16(<4 x i16> %a1)
86   %0 = and i32 %vaddv.i, 3276799 ; 0x31ffff
87   ret i32 %0
88 }
89
90 define i32 @test_vaddv_u32(<2 x i32> %a1) {
91 ; CHECK-LABEL: test_vaddv_u32:
92 ; 2 x i32 is not supported by the ISA, thus, this is a special case
93 ; CHECK: addp.2s v[[REGNUM:[0-9]+]], v0, v0
94 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
95 ; CHECK-NEXT: ret
96 entry:
97   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v2i32(<2 x i32> %a1)
98   ret i32 %vaddv.i
99 }
100
101 define float @test_vaddv_f32(<2 x float> %a1) {
102 ; CHECK-LABEL: test_vaddv_f32:
103 ; CHECK: faddp.2s s0, v0
104 ; CHECK-NEXT: ret
105 entry:
106   %vaddv.i = tail call float @llvm.arm64.neon.faddv.f32.v2f32(<2 x float> %a1)
107   ret float %vaddv.i
108 }
109
110 define float @test_vaddv_v4f32(<4 x float> %a1) {
111 ; CHECK-LABEL: test_vaddv_v4f32:
112 ; CHECK: faddp.4s [[REGNUM:v[0-9]+]], v0, v0
113 ; CHECK: faddp.2s s0, [[REGNUM]]
114 ; CHECK-NEXT: ret
115 entry:
116   %vaddv.i = tail call float @llvm.arm64.neon.faddv.f32.v4f32(<4 x float> %a1)
117   ret float %vaddv.i
118 }
119
120 define double @test_vaddv_f64(<2 x double> %a1) {
121 ; CHECK-LABEL: test_vaddv_f64:
122 ; CHECK: faddp.2d d0, v0
123 ; CHECK-NEXT: ret
124 entry:
125   %vaddv.i = tail call double @llvm.arm64.neon.faddv.f64.v2f64(<2 x double> %a1)
126   ret double %vaddv.i
127 }
128
129 define i64 @test_vaddv_u64(<2 x i64> %a1) {
130 ; CHECK-LABEL: test_vaddv_u64:
131 ; CHECK: addp.2d [[REGNUM:d[0-9]+]], v0
132 ; CHECK-NEXT: fmov x0, [[REGNUM]]
133 ; CHECK-NEXT: ret
134 entry:
135   %vaddv.i = tail call i64 @llvm.arm64.neon.uaddv.i64.v2i64(<2 x i64> %a1)
136   ret i64 %vaddv.i
137 }
138
139 define signext i8 @test_vaddvq_s8(<16 x i8> %a1) {
140 ; CHECK-LABEL: test_vaddvq_s8:
141 ; CHECK: addv.16b b[[REGNUM:[0-9]+]], v0
142 ; CHECK-NEXT: smov.b w0, v[[REGNUM]][0]
143 ; CHECK-NEXT: ret
144 entry:
145   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v16i8(<16 x i8> %a1)
146   %0 = trunc i32 %vaddv.i to i8
147   ret i8 %0
148 }
149
150 define signext i16 @test_vaddvq_s16(<8 x i16> %a1) {
151 ; CHECK-LABEL: test_vaddvq_s16:
152 ; CHECK: addv.8h h[[REGNUM:[0-9]+]], v0
153 ; CHECK-NEXT: smov.h w0, v[[REGNUM]][0]
154 ; CHECK-NEXT: ret
155 entry:
156   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v8i16(<8 x i16> %a1)
157   %0 = trunc i32 %vaddv.i to i16
158   ret i16 %0
159 }
160
161 define i32 @test_vaddvq_s32(<4 x i32> %a1) {
162 ; CHECK-LABEL: test_vaddvq_s32:
163 ; CHECK: addv.4s [[REGNUM:s[0-9]+]], v0
164 ; CHECK-NEXT: fmov w0, [[REGNUM]]
165 ; CHECK-NEXT: ret
166 entry:
167   %vaddv.i = tail call i32 @llvm.arm64.neon.saddv.i32.v4i32(<4 x i32> %a1)
168   ret i32 %vaddv.i
169 }
170
171 define zeroext i8 @test_vaddvq_u8(<16 x i8> %a1) {
172 ; CHECK-LABEL: test_vaddvq_u8:
173 ; CHECK: addv.16b b[[REGNUM:[0-9]+]], v0
174 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
175 ; CHECK-NEXT: ret
176 entry:
177   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v16i8(<16 x i8> %a1)
178   %0 = trunc i32 %vaddv.i to i8
179   ret i8 %0
180 }
181
182 define zeroext i16 @test_vaddvq_u16(<8 x i16> %a1) {
183 ; CHECK-LABEL: test_vaddvq_u16:
184 ; CHECK: addv.8h h[[REGNUM:[0-9]+]], v0
185 ; CHECK-NEXT: fmov w0, s[[REGNUM]]
186 ; CHECK-NEXT: ret
187 entry:
188   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v8i16(<8 x i16> %a1)
189   %0 = trunc i32 %vaddv.i to i16
190   ret i16 %0
191 }
192
193 define i32 @test_vaddvq_u32(<4 x i32> %a1) {
194 ; CHECK-LABEL: test_vaddvq_u32:
195 ; CHECK: addv.4s [[REGNUM:s[0-9]+]], v0
196 ; CHECK-NEXT: fmov [[FMOVRES:w[0-9]+]], [[REGNUM]]
197 ; CHECK-NEXT: ret
198 entry:
199   %vaddv.i = tail call i32 @llvm.arm64.neon.uaddv.i32.v4i32(<4 x i32> %a1)
200   ret i32 %vaddv.i
201 }
202
203 declare i32 @llvm.arm64.neon.uaddv.i32.v4i32(<4 x i32>)
204
205 declare i32 @llvm.arm64.neon.uaddv.i32.v8i16(<8 x i16>)
206
207 declare i32 @llvm.arm64.neon.uaddv.i32.v16i8(<16 x i8>)
208
209 declare i32 @llvm.arm64.neon.saddv.i32.v4i32(<4 x i32>)
210
211 declare i32 @llvm.arm64.neon.saddv.i32.v8i16(<8 x i16>)
212
213 declare i32 @llvm.arm64.neon.saddv.i32.v16i8(<16 x i8>)
214
215 declare i64 @llvm.arm64.neon.uaddv.i64.v2i64(<2 x i64>)
216
217 declare i32 @llvm.arm64.neon.uaddv.i32.v2i32(<2 x i32>)
218
219 declare i32 @llvm.arm64.neon.uaddv.i32.v4i16(<4 x i16>)
220
221 declare i32 @llvm.arm64.neon.uaddv.i32.v8i8(<8 x i8>)
222
223 declare i32 @llvm.arm64.neon.saddv.i32.v2i32(<2 x i32>)
224
225 declare i64 @llvm.arm64.neon.saddv.i64.v2i64(<2 x i64>)
226
227 declare i32 @llvm.arm64.neon.saddv.i32.v4i16(<4 x i16>)
228
229 declare i32 @llvm.arm64.neon.saddv.i32.v8i8(<8 x i8>)
230
231 declare float @llvm.arm64.neon.faddv.f32.v2f32(<2 x float> %a1)
232 declare float @llvm.arm64.neon.faddv.f32.v4f32(<4 x float> %a1)
233 declare double @llvm.arm64.neon.faddv.f64.v2f64(<2 x double> %a1)