xref: /llvm-project/llvm/test/Transforms/SLPVectorizer/AArch64/reduce-add-i64.ll (revision 31eaf86a1e8f1870e6ee4c42088a5213bde294b8)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=slp-vectorizer %s --mtriple=aarch64-- | FileCheck %s
3
4; This test checks whether load-zext-add and load-add reduction patterns
5; get vectorized by SLP.
6
7define i64 @red_zext_ld_2xi64(ptr %ptr) {
8; CHECK-LABEL: @red_zext_ld_2xi64(
9; CHECK-NEXT:  entry:
10; CHECK-NEXT:    [[LD0:%.*]] = load i8, ptr [[PTR:%.*]], align 1
11; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[LD0]] to i64
12; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
13; CHECK-NEXT:    [[LD1:%.*]] = load i8, ptr [[GEP]], align 1
14; CHECK-NEXT:    [[ZEXT_1:%.*]] = zext i8 [[LD1]] to i64
15; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i64 [[ZEXT]], [[ZEXT_1]]
16; CHECK-NEXT:    ret i64 [[ADD_1]]
17;
18entry:
19  %ld0 = load i8, ptr %ptr
20  %zext = zext i8 %ld0 to i64
21  %gep = getelementptr inbounds i8, ptr %ptr, i64 1
22  %ld1 = load i8, ptr %gep
23  %zext.1 = zext i8 %ld1 to i64
24  %add.1 = add nuw nsw i64 %zext, %zext.1
25  ret i64 %add.1
26}
27
28define i64 @red_zext_ld_4xi64(ptr %ptr) {
29; CHECK-LABEL: @red_zext_ld_4xi64(
30; CHECK-NEXT:  entry:
31; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i8>, ptr [[PTR:%.*]], align 1
32; CHECK-NEXT:    [[TMP1:%.*]] = zext <4 x i8> [[TMP0]] to <4 x i16>
33; CHECK-NEXT:    [[TMP2:%.*]] = call i16 @llvm.vector.reduce.add.v4i16(<4 x i16> [[TMP1]])
34; CHECK-NEXT:    [[TMP3:%.*]] = zext i16 [[TMP2]] to i64
35; CHECK-NEXT:    ret i64 [[TMP3]]
36;
37entry:
38  %ld0 = load i8, ptr %ptr
39  %zext = zext i8 %ld0 to i64
40  %gep = getelementptr inbounds i8, ptr %ptr, i64 1
41  %ld1 = load i8, ptr %gep
42  %zext.1 = zext i8 %ld1 to i64
43  %add.1 = add nuw nsw i64 %zext, %zext.1
44  %gep.1 = getelementptr inbounds i8, ptr %ptr, i64 2
45  %ld2 = load i8, ptr %gep.1
46  %zext.2 = zext i8 %ld2 to i64
47  %add.2 = add nuw nsw i64 %add.1, %zext.2
48  %gep.2 = getelementptr inbounds i8, ptr %ptr, i64 3
49  %ld3 = load i8, ptr %gep.2
50  %zext.3 = zext i8 %ld3 to i64
51  %add.3 = add nuw nsw i64 %add.2, %zext.3
52  ret i64 %add.3
53}
54
55define i64 @red_zext_ld_8xi64(ptr %ptr) {
56; CHECK-LABEL: @red_zext_ld_8xi64(
57; CHECK-NEXT:  entry:
58; CHECK-NEXT:    [[TMP0:%.*]] = load <8 x i8>, ptr [[PTR:%.*]], align 1
59; CHECK-NEXT:    [[TMP1:%.*]] = zext <8 x i8> [[TMP0]] to <8 x i64>
60; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> [[TMP1]])
61; CHECK-NEXT:    ret i64 [[TMP2]]
62;
63entry:
64  %ld0 = load i8, ptr %ptr
65  %zext = zext i8 %ld0 to i64
66  %gep = getelementptr inbounds i8, ptr %ptr, i64 1
67  %ld1 = load i8, ptr %gep
68  %zext.1 = zext i8 %ld1 to i64
69  %add.1 = add nuw nsw i64 %zext, %zext.1
70  %gep.1 = getelementptr inbounds i8, ptr %ptr, i64 2
71  %ld2 = load i8, ptr %gep.1
72  %zext.2 = zext i8 %ld2 to i64
73  %add.2 = add nuw nsw i64 %add.1, %zext.2
74  %gep.2 = getelementptr inbounds i8, ptr %ptr, i64 3
75  %ld3 = load i8, ptr %gep.2
76  %zext.3 = zext i8 %ld3 to i64
77  %add.3 = add nuw nsw i64 %add.2, %zext.3
78  %gep.3 = getelementptr inbounds i8, ptr %ptr, i64 4
79  %ld4 = load i8, ptr %gep.3
80  %zext.4 = zext i8 %ld4 to i64
81  %add.4 = add nuw nsw i64 %add.3, %zext.4
82  %gep.4 = getelementptr inbounds i8, ptr %ptr, i64 5
83  %ld5 = load i8, ptr %gep.4
84  %zext.5 = zext i8 %ld5 to i64
85  %add.5 = add nuw nsw i64 %add.4, %zext.5
86  %gep.5 = getelementptr inbounds i8, ptr %ptr, i64 6
87  %ld6 = load i8, ptr %gep.5
88  %zext.6 = zext i8 %ld6 to i64
89  %add.6 = add nuw nsw i64 %add.5, %zext.6
90  %gep.6 = getelementptr inbounds i8, ptr %ptr, i64 7
91  %ld7 = load i8, ptr %gep.6
92  %zext.7 = zext i8 %ld7 to i64
93  %add.7 = add nuw nsw i64 %add.6, %zext.7
94  ret i64 %add.7
95}
96
97define i64 @red_zext_ld_16xi64(ptr %ptr) {
98; CHECK-LABEL: @red_zext_ld_16xi64(
99; CHECK-NEXT:  entry:
100; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[PTR:%.*]], align 1
101; CHECK-NEXT:    [[TMP1:%.*]] = zext <16 x i8> [[TMP0]] to <16 x i64>
102; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> [[TMP1]])
103; CHECK-NEXT:    ret i64 [[TMP2]]
104;
105entry:
106  %ld0 = load i8, ptr %ptr
107  %zext = zext i8 %ld0 to i64
108  %gep = getelementptr inbounds i8, ptr %ptr, i64 1
109  %ld1 = load i8, ptr %gep
110  %zext.1 = zext i8 %ld1 to i64
111  %add.1 = add nuw nsw i64 %zext, %zext.1
112  %gep.1 = getelementptr inbounds i8, ptr %ptr, i64 2
113  %ld2 = load i8, ptr %gep.1
114  %zext.2 = zext i8 %ld2 to i64
115  %add.2 = add nuw nsw i64 %add.1, %zext.2
116  %gep.2 = getelementptr inbounds i8, ptr %ptr, i64 3
117  %ld3 = load i8, ptr %gep.2
118  %zext.3 = zext i8 %ld3 to i64
119  %add.3 = add nuw nsw i64 %add.2, %zext.3
120  %gep.3 = getelementptr inbounds i8, ptr %ptr, i64 4
121  %ld4 = load i8, ptr %gep.3
122  %zext.4 = zext i8 %ld4 to i64
123  %add.4 = add nuw nsw i64 %add.3, %zext.4
124  %gep.4 = getelementptr inbounds i8, ptr %ptr, i64 5
125  %ld5 = load i8, ptr %gep.4
126  %zext.5 = zext i8 %ld5 to i64
127  %add.5 = add nuw nsw i64 %add.4, %zext.5
128  %gep.5 = getelementptr inbounds i8, ptr %ptr, i64 6
129  %ld6 = load i8, ptr %gep.5
130  %zext.6 = zext i8 %ld6 to i64
131  %add.6 = add nuw nsw i64 %add.5, %zext.6
132  %gep.6 = getelementptr inbounds i8, ptr %ptr, i64 7
133  %ld7 = load i8, ptr %gep.6
134  %zext.7 = zext i8 %ld7 to i64
135  %add.7 = add nuw nsw i64 %add.6, %zext.7
136  %gep.7 = getelementptr inbounds i8, ptr %ptr, i64 8
137  %ld8 = load i8, ptr %gep.7
138  %zext.8 = zext i8 %ld8 to i64
139  %add.8 = add nuw nsw i64 %add.7, %zext.8
140  %gep.8 = getelementptr inbounds i8, ptr %ptr, i64 9
141  %ld9 = load i8, ptr %gep.8
142  %zext.9 = zext i8 %ld9 to i64
143  %add.9 = add nuw nsw i64 %add.8, %zext.9
144  %gep.9 = getelementptr inbounds i8, ptr %ptr, i64 10
145  %ld10 = load i8, ptr %gep.9
146  %zext.10 = zext i8 %ld10 to i64
147  %add.10 = add nuw nsw i64 %add.9, %zext.10
148  %gep.10 = getelementptr inbounds i8, ptr %ptr, i64 11
149  %ld11 = load i8, ptr %gep.10
150  %zext.11 = zext i8 %ld11 to i64
151  %add.11 = add nuw nsw i64 %add.10, %zext.11
152  %gep.11 = getelementptr inbounds i8, ptr %ptr, i64 12
153  %ld12 = load i8, ptr %gep.11
154  %zext.12 = zext i8 %ld12 to i64
155  %add.12 = add nuw nsw i64 %add.11, %zext.12
156  %gep.12 = getelementptr inbounds i8, ptr %ptr, i64 13
157  %ld13 = load i8, ptr %gep.12
158  %zext.13 = zext i8 %ld13 to i64
159  %add.13 = add nuw nsw i64 %add.12, %zext.13
160  %gep.13 = getelementptr inbounds i8, ptr %ptr, i64 14
161  %ld14 = load i8, ptr %gep.13
162  %zext.14 = zext i8 %ld14 to i64
163  %add.14 = add nuw nsw i64 %add.13, %zext.14
164  %gep.14 = getelementptr inbounds i8, ptr %ptr, i64 15
165  %ld15 = load i8, ptr %gep.14
166  %zext.15 = zext i8 %ld15 to i64
167  %add.15 = add nuw nsw i64 %add.14, %zext.15
168  ret i64 %add.15
169}
170
171
172
173define i64 @red_ld_2xi64(ptr %ptr) {
174; CHECK-LABEL: @red_ld_2xi64(
175; CHECK-NEXT:  entry:
176; CHECK-NEXT:    [[LD0:%.*]] = load i64, ptr [[PTR:%.*]], align 8
177; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i64, ptr [[PTR]], i64 1
178; CHECK-NEXT:    [[LD1:%.*]] = load i64, ptr [[GEP]], align 8
179; CHECK-NEXT:    [[ADD_1:%.*]] = add nuw nsw i64 [[LD0]], [[LD1]]
180; CHECK-NEXT:    ret i64 [[ADD_1]]
181;
182entry:
183  %ld0 = load i64, ptr %ptr
184  %gep = getelementptr inbounds i64, ptr %ptr, i64 1
185  %ld1 = load i64, ptr %gep
186  %add.1 = add nuw nsw i64 %ld0, %ld1
187  ret i64 %add.1
188}
189
190define i64 @red_ld_4xi64(ptr %ptr) {
191; CHECK-LABEL: @red_ld_4xi64(
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i64>, ptr [[PTR:%.*]], align 8
194; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vector.reduce.add.v4i64(<4 x i64> [[TMP0]])
195; CHECK-NEXT:    ret i64 [[TMP1]]
196;
197entry:
198  %ld0 = load i64, ptr %ptr
199  %gep = getelementptr inbounds i64, ptr %ptr, i64 1
200  %ld1 = load i64, ptr %gep
201  %add.1 = add nuw nsw i64 %ld0, %ld1
202  %gep.1 = getelementptr inbounds i64, ptr %ptr, i64 2
203  %ld2 = load i64, ptr %gep.1
204  %add.2 = add nuw nsw i64 %add.1, %ld2
205  %gep.2 = getelementptr inbounds i64, ptr %ptr, i64 3
206  %ld3 = load i64, ptr %gep.2
207  %add.3 = add nuw nsw i64 %add.2, %ld3
208  ret i64 %add.3
209}
210
211define i64 @red_ld_8xi64(ptr %ptr) {
212; CHECK-LABEL: @red_ld_8xi64(
213; CHECK-NEXT:  entry:
214; CHECK-NEXT:    [[TMP0:%.*]] = load <8 x i64>, ptr [[PTR:%.*]], align 8
215; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vector.reduce.add.v8i64(<8 x i64> [[TMP0]])
216; CHECK-NEXT:    ret i64 [[TMP1]]
217;
218entry:
219  %ld0 = load i64, ptr %ptr
220  %gep = getelementptr inbounds i64, ptr %ptr, i64 1
221  %ld1 = load i64, ptr %gep
222  %add.1 = add nuw nsw i64 %ld0, %ld1
223  %gep.1 = getelementptr inbounds i64, ptr %ptr, i64 2
224  %ld2 = load i64, ptr %gep.1
225  %add.2 = add nuw nsw i64 %add.1, %ld2
226  %gep.2 = getelementptr inbounds i64, ptr %ptr, i64 3
227  %ld3 = load i64, ptr %gep.2
228  %add.3 = add nuw nsw i64 %add.2, %ld3
229  %gep.3 = getelementptr inbounds i64, ptr %ptr, i64 4
230  %ld4 = load i64, ptr %gep.3
231  %add.4 = add nuw nsw i64 %add.3, %ld4
232  %gep.4 = getelementptr inbounds i64, ptr %ptr, i64 5
233  %ld5 = load i64, ptr %gep.4
234  %add.5 = add nuw nsw i64 %add.4, %ld5
235  %gep.5 = getelementptr inbounds i64, ptr %ptr, i64 6
236  %ld6 = load i64, ptr %gep.5
237  %add.6 = add nuw nsw i64 %add.5, %ld6
238  %gep.6 = getelementptr inbounds i64, ptr %ptr, i64 7
239  %ld7 = load i64, ptr %gep.6
240  %add.7 = add nuw nsw i64 %add.6, %ld7
241  ret i64 %add.7
242}
243
244define i64 @red_ld_16xi64(ptr %ptr) {
245; CHECK-LABEL: @red_ld_16xi64(
246; CHECK-NEXT:  entry:
247; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i64>, ptr [[PTR:%.*]], align 8
248; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vector.reduce.add.v16i64(<16 x i64> [[TMP0]])
249; CHECK-NEXT:    ret i64 [[TMP1]]
250;
251entry:
252  %ld0 = load i64, ptr %ptr
253  %gep = getelementptr inbounds i64, ptr %ptr, i64 1
254  %ld1 = load i64, ptr %gep
255  %add.1 = add nuw nsw i64 %ld0, %ld1
256  %gep.1 = getelementptr inbounds i64, ptr %ptr, i64 2
257  %ld2 = load i64, ptr %gep.1
258  %add.2 = add nuw nsw i64 %add.1, %ld2
259  %gep.2 = getelementptr inbounds i64, ptr %ptr, i64 3
260  %ld3 = load i64, ptr %gep.2
261  %add.3 = add nuw nsw i64 %add.2, %ld3
262  %gep.3 = getelementptr inbounds i64, ptr %ptr, i64 4
263  %ld4 = load i64, ptr %gep.3
264  %add.4 = add nuw nsw i64 %add.3, %ld4
265  %gep.4 = getelementptr inbounds i64, ptr %ptr, i64 5
266  %ld5 = load i64, ptr %gep.4
267  %add.5 = add nuw nsw i64 %add.4, %ld5
268  %gep.5 = getelementptr inbounds i64, ptr %ptr, i64 6
269  %ld6 = load i64, ptr %gep.5
270  %add.6 = add nuw nsw i64 %add.5, %ld6
271  %gep.6 = getelementptr inbounds i64, ptr %ptr, i64 7
272  %ld7 = load i64, ptr %gep.6
273  %add.7 = add nuw nsw i64 %add.6, %ld7
274  %gep.7 = getelementptr inbounds i64, ptr %ptr, i64 8
275  %ld8 = load i64, ptr %gep.7
276  %add.8 = add nuw nsw i64 %add.7, %ld8
277  %gep.8 = getelementptr inbounds i64, ptr %ptr, i64 9
278  %ld9 = load i64, ptr %gep.8
279  %add.9 = add nuw nsw i64 %add.8, %ld9
280  %gep.9 = getelementptr inbounds i64, ptr %ptr, i64 10
281  %ld10 = load i64, ptr %gep.9
282  %add.10 = add nuw nsw i64 %add.9, %ld10
283  %gep.10 = getelementptr inbounds i64, ptr %ptr, i64 11
284  %ld11 = load i64, ptr %gep.10
285  %add.11 = add nuw nsw i64 %add.10, %ld11
286  %gep.11 = getelementptr inbounds i64, ptr %ptr, i64 12
287  %ld12 = load i64, ptr %gep.11
288  %add.12 = add nuw nsw i64 %add.11, %ld12
289  %gep.12 = getelementptr inbounds i64, ptr %ptr, i64 13
290  %ld13 = load i64, ptr %gep.12
291  %add.13 = add nuw nsw i64 %add.12, %ld13
292  %gep.13 = getelementptr inbounds i64, ptr %ptr, i64 14
293  %ld14 = load i64, ptr %gep.13
294  %add.14 = add nuw nsw i64 %add.13, %ld14
295  %gep.14 = getelementptr inbounds i64, ptr %ptr, i64 15
296  %ld15 = load i64, ptr %gep.14
297  %add.15 = add nuw nsw i64 %add.14, %ld15
298  ret i64 %add.15
299}
300