1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp -float-abi=hard -verify-machineinstrs %s -o - | FileCheck %s
4 define float @add_f32(<8 x float> %a, <4 x float> %b) {
5 ; CHECK-LABEL: add_f32:
7 ; CHECK-NEXT: vadd.f32 q0, q0, q1
8 ; CHECK-NEXT: vadd.f32 q0, q0, q2
9 ; CHECK-NEXT: vadd.f32 s2, s2, s3
10 ; CHECK-NEXT: vadd.f32 s0, s0, s1
11 ; CHECK-NEXT: vadd.f32 s0, s0, s2
13 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %a)
14 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)
15 %r = fadd fast float %r1, %r2
19 define float @fmul_f32(<8 x float> %a, <4 x float> %b) {
20 ; CHECK-LABEL: fmul_f32:
22 ; CHECK-NEXT: vmul.f32 q0, q0, q1
23 ; CHECK-NEXT: vmul.f32 q0, q0, q2
24 ; CHECK-NEXT: vmul.f32 s2, s2, s3
25 ; CHECK-NEXT: vmul.f32 s0, s0, s1
26 ; CHECK-NEXT: vmul.f32 s0, s0, s2
28 %r1 = call fast float @llvm.vector.reduce.fmul.f32.v8f32(float 1.0, <8 x float> %a)
29 %r2 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %b)
30 %r = fmul fast float %r1, %r2
34 define float @fmin_f32(<8 x float> %a, <4 x float> %b) {
35 ; CHECK-LABEL: fmin_f32:
37 ; CHECK-NEXT: vminnm.f32 q0, q0, q1
38 ; CHECK-NEXT: vminnm.f32 q0, q0, q2
39 ; CHECK-NEXT: vminnm.f32 s2, s2, s3
40 ; CHECK-NEXT: vminnm.f32 s0, s0, s1
41 ; CHECK-NEXT: vminnm.f32 s0, s0, s2
43 %r1 = call fast float @llvm.vector.reduce.fmin.v8f32(<8 x float> %a)
44 %r2 = call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> %b)
45 %r = call float @llvm.minnum.f32(float %r1, float %r2)
49 define float @fmax_f32(<8 x float> %a, <4 x float> %b) {
50 ; CHECK-LABEL: fmax_f32:
52 ; CHECK-NEXT: vmaxnm.f32 q0, q0, q1
53 ; CHECK-NEXT: vmaxnm.f32 q0, q0, q2
54 ; CHECK-NEXT: vmaxnm.f32 s2, s2, s3
55 ; CHECK-NEXT: vmaxnm.f32 s0, s0, s1
56 ; CHECK-NEXT: vmaxnm.f32 s0, s0, s2
58 %r1 = call fast float @llvm.vector.reduce.fmax.v8f32(<8 x float> %a)
59 %r2 = call fast float @llvm.vector.reduce.fmax.v4f32(<4 x float> %b)
60 %r = call float @llvm.maxnum.f32(float %r1, float %r2)
65 define i32 @add_i32(<8 x i32> %a, <4 x i32> %b) {
66 ; CHECK-LABEL: add_i32:
68 ; CHECK-NEXT: vaddv.u32 r0, q1
69 ; CHECK-NEXT: vaddva.u32 r0, q0
70 ; CHECK-NEXT: vaddva.u32 r0, q2
72 %r1 = call i32 @llvm.vector.reduce.add.i32.v8i32(<8 x i32> %a)
73 %r2 = call i32 @llvm.vector.reduce.add.i32.v4i32(<4 x i32> %b)
78 define i16 @add_ext_i16(<16 x i8> %a, <16 x i8> %b) {
79 ; CHECK-LABEL: add_ext_i16:
81 ; CHECK-NEXT: vaddv.u8 r0, q1
82 ; CHECK-NEXT: vaddva.u8 r0, q0
84 %ae = zext <16 x i8> %a to <16 x i16>
85 %be = zext <16 x i8> %b to <16 x i16>
86 %r1 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %ae)
87 %r2 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %be)
92 define i16 @add_ext_v32i16(<32 x i8> %a, <16 x i8> %b) {
93 ; CHECK-LABEL: add_ext_v32i16:
95 ; CHECK-NEXT: .pad #32
96 ; CHECK-NEXT: sub sp, #32
97 ; CHECK-NEXT: mov r1, sp
98 ; CHECK-NEXT: add r2, sp, #16
99 ; CHECK-NEXT: vstrw.32 q0, [r1]
100 ; CHECK-NEXT: vstrw.32 q1, [r2]
101 ; CHECK-NEXT: vldrb.u16 q1, [r2]
102 ; CHECK-NEXT: vldrb.u16 q0, [r1]
103 ; CHECK-NEXT: vaddv.u16 r0, q1
104 ; CHECK-NEXT: vaddva.u16 r0, q0
105 ; CHECK-NEXT: vldrb.u16 q0, [r1, #8]
106 ; CHECK-NEXT: vaddva.u16 r0, q0
107 ; CHECK-NEXT: vldrb.u16 q0, [r2, #8]
108 ; CHECK-NEXT: vaddva.u16 r0, q0
109 ; CHECK-NEXT: vaddva.u8 r0, q2
110 ; CHECK-NEXT: add sp, #32
112 %ae = zext <32 x i8> %a to <32 x i16>
113 %be = zext <16 x i8> %b to <16 x i16>
114 %r1 = call i16 @llvm.vector.reduce.add.i16.v32i16(<32 x i16> %ae)
115 %r2 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %be)
116 %r = add i16 %r1, %r2
120 define i32 @mul_i32(<8 x i32> %a, <4 x i32> %b) {
121 ; CHECK-LABEL: mul_i32:
123 ; CHECK-NEXT: vmul.i32 q0, q0, q1
124 ; CHECK-NEXT: vmul.i32 q0, q0, q2
125 ; CHECK-NEXT: vmov r0, r1, d1
126 ; CHECK-NEXT: vmov r2, r3, d0
127 ; CHECK-NEXT: muls r0, r1, r0
128 ; CHECK-NEXT: mul r1, r2, r3
129 ; CHECK-NEXT: muls r0, r1, r0
131 %r1 = call i32 @llvm.vector.reduce.mul.i32.v8i32(<8 x i32> %a)
132 %r2 = call i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32> %b)
133 %r = mul i32 %r1, %r2
137 define i32 @and_i32(<8 x i32> %a, <4 x i32> %b) {
138 ; CHECK-LABEL: and_i32:
140 ; CHECK-NEXT: vand q0, q0, q1
141 ; CHECK-NEXT: vand q0, q0, q2
142 ; CHECK-NEXT: vmov r0, r1, d1
143 ; CHECK-NEXT: vmov r2, r3, d0
144 ; CHECK-NEXT: ands r0, r1
145 ; CHECK-NEXT: and.w r1, r2, r3
146 ; CHECK-NEXT: ands r0, r1
148 %r1 = call i32 @llvm.vector.reduce.and.i32.v8i32(<8 x i32> %a)
149 %r2 = call i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32> %b)
150 %r = and i32 %r1, %r2
154 define i32 @or_i32(<8 x i32> %a, <4 x i32> %b) {
155 ; CHECK-LABEL: or_i32:
157 ; CHECK-NEXT: vorr q0, q0, q1
158 ; CHECK-NEXT: vorr q0, q0, q2
159 ; CHECK-NEXT: vmov r0, r1, d1
160 ; CHECK-NEXT: vmov r2, r3, d0
161 ; CHECK-NEXT: orrs r0, r1
162 ; CHECK-NEXT: orr.w r1, r2, r3
163 ; CHECK-NEXT: orrs r0, r1
165 %r1 = call i32 @llvm.vector.reduce.or.i32.v8i32(<8 x i32> %a)
166 %r2 = call i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32> %b)
171 define i32 @xor_i32(<8 x i32> %a, <4 x i32> %b) {
172 ; CHECK-LABEL: xor_i32:
174 ; CHECK-NEXT: veor q0, q0, q1
175 ; CHECK-NEXT: veor q0, q0, q2
176 ; CHECK-NEXT: vmov r0, r1, d1
177 ; CHECK-NEXT: vmov r2, r3, d0
178 ; CHECK-NEXT: eors r0, r1
179 ; CHECK-NEXT: eor.w r1, r2, r3
180 ; CHECK-NEXT: eors r0, r1
182 %r1 = call i32 @llvm.vector.reduce.xor.i32.v8i32(<8 x i32> %a)
183 %r2 = call i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32> %b)
184 %r = xor i32 %r1, %r2
188 define i32 @umin_i32(<8 x i32> %a, <4 x i32> %b) {
189 ; CHECK-LABEL: umin_i32:
191 ; CHECK-NEXT: vmin.u32 q0, q0, q1
192 ; CHECK-NEXT: mov.w r0, #-1
193 ; CHECK-NEXT: vmin.u32 q0, q0, q2
194 ; CHECK-NEXT: vminv.u32 r0, q0
196 %r1 = call i32 @llvm.vector.reduce.umin.i32.v8i32(<8 x i32> %a)
197 %r2 = call i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32> %b)
198 %r = call i32 @llvm.umin.i32(i32 %r1, i32 %r2)
202 define i32 @umax_i32(<8 x i32> %a, <4 x i32> %b) {
203 ; CHECK-LABEL: umax_i32:
205 ; CHECK-NEXT: vmax.u32 q0, q0, q1
206 ; CHECK-NEXT: movs r0, #0
207 ; CHECK-NEXT: vmax.u32 q0, q0, q2
208 ; CHECK-NEXT: vmaxv.u32 r0, q0
210 %r1 = call i32 @llvm.vector.reduce.umax.i32.v8i32(<8 x i32> %a)
211 %r2 = call i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32> %b)
212 %r = call i32 @llvm.umax.i32(i32 %r1, i32 %r2)
216 define i32 @smin_i32(<8 x i32> %a, <4 x i32> %b) {
217 ; CHECK-LABEL: smin_i32:
219 ; CHECK-NEXT: vmin.s32 q0, q0, q1
220 ; CHECK-NEXT: mvn r0, #-2147483648
221 ; CHECK-NEXT: vmin.s32 q0, q0, q2
222 ; CHECK-NEXT: vminv.s32 r0, q0
224 %r1 = call i32 @llvm.vector.reduce.smin.i32.v8i32(<8 x i32> %a)
225 %r2 = call i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32> %b)
226 %r = call i32 @llvm.smin.i32(i32 %r1, i32 %r2)
230 define i32 @smax_i32(<8 x i32> %a, <4 x i32> %b) {
231 ; CHECK-LABEL: smax_i32:
233 ; CHECK-NEXT: vmax.s32 q0, q0, q1
234 ; CHECK-NEXT: mov.w r0, #-2147483648
235 ; CHECK-NEXT: vmax.s32 q0, q0, q2
236 ; CHECK-NEXT: vmaxv.s32 r0, q0
238 %r1 = call i32 @llvm.vector.reduce.smax.i32.v8i32(<8 x i32> %a)
239 %r2 = call i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32> %b)
240 %r = call i32 @llvm.smax.i32(i32 %r1, i32 %r2)
244 declare float @llvm.vector.reduce.fadd.f32.v8f32(float, <8 x float>)
245 declare float @llvm.vector.reduce.fadd.f32.v4f32(float, <4 x float>)
246 declare float @llvm.vector.reduce.fmul.f32.v8f32(float, <8 x float>)
247 declare float @llvm.vector.reduce.fmul.f32.v4f32(float, <4 x float>)
248 declare float @llvm.vector.reduce.fmin.v8f32(<8 x float>)
249 declare float @llvm.vector.reduce.fmin.v4f32(<4 x float>)
250 declare float @llvm.vector.reduce.fmax.v8f32(<8 x float>)
251 declare float @llvm.vector.reduce.fmax.v4f32(<4 x float>)
252 declare i32 @llvm.vector.reduce.add.i32.v8i32(<8 x i32>)
253 declare i32 @llvm.vector.reduce.add.i32.v4i32(<4 x i32>)
254 declare i16 @llvm.vector.reduce.add.i16.v32i16(<32 x i16>)
255 declare i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16>)
256 declare i32 @llvm.vector.reduce.mul.i32.v8i32(<8 x i32>)
257 declare i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32>)
258 declare i32 @llvm.vector.reduce.and.i32.v8i32(<8 x i32>)
259 declare i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32>)
260 declare i32 @llvm.vector.reduce.or.i32.v8i32(<8 x i32>)
261 declare i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32>)
262 declare i32 @llvm.vector.reduce.xor.i32.v8i32(<8 x i32>)
263 declare i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32>)
264 declare i32 @llvm.vector.reduce.umin.i32.v8i32(<8 x i32>)
265 declare i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32>)
266 declare i32 @llvm.vector.reduce.umax.i32.v8i32(<8 x i32>)
267 declare i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32>)
268 declare i32 @llvm.vector.reduce.smin.i32.v8i32(<8 x i32>)
269 declare i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32>)
270 declare i32 @llvm.vector.reduce.smax.i32.v8i32(<8 x i32>)
271 declare i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32>)
272 declare float @llvm.minnum.f32(float, float)
273 declare float @llvm.maxnum.f32(float, float)
274 declare i32 @llvm.umin.i32(i32, i32)
275 declare i32 @llvm.umax.i32(i32, i32)
276 declare i32 @llvm.smin.i32(i32, i32)
277 declare i32 @llvm.smax.i32(i32, i32)