xref: /llvm-project/llvm/test/Transforms/PhaseOrdering/AArch64/interleavevectorization.ll (revision 1157187496afbbb203b8ec7aa320769ec6eed8c4)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes="default<O3>" -S -o - %s | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5target triple = "aarch64"
6
7; for(int i =0; i < 1024; i+=4) {
8;   x[i] += y[i];
9;   x[i+1] += y[i+1];
10;   x[i+2] += y[i+2];
11;   x[i+3] += y[i+3];
12; }
13define void @add4(ptr noalias noundef %x, ptr noalias noundef %y, i32 noundef %n) {
14; CHECK-LABEL: @add4(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
17; CHECK:       vector.body:
18; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
19; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
20; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
21; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
22; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
23; CHECK-NEXT:    [[WIDE_VEC24:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
24; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = add <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
25; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP1]], align 2
26; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
27; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
28; CHECK-NEXT:    br i1 [[TMP3]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
29; CHECK:       for.end:
30; CHECK-NEXT:    ret void
31;
32entry:
33  %x.addr = alloca ptr, align 8
34  %y.addr = alloca ptr, align 8
35  %n.addr = alloca i32, align 4
36  %i = alloca i32, align 4
37  store ptr %x, ptr %x.addr, align 8
38  store ptr %y, ptr %y.addr, align 8
39  store i32 %n, ptr %n.addr, align 4
40  store i32 0, ptr %i, align 4
41  br label %for.cond
42
43for.cond:
44  %0 = load i32, ptr %i, align 4
45  %cmp = icmp slt i32 %0, 1024
46  br i1 %cmp, label %for.body, label %for.end
47
48for.body:
49  %1 = load ptr, ptr %y.addr, align 8
50  %2 = load i32, ptr %i, align 4
51  %idxprom = sext i32 %2 to i64
52  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
53  %3 = load i16, ptr %arrayidx, align 2
54  %conv = sext i16 %3 to i32
55  %4 = load ptr, ptr %x.addr, align 8
56  %5 = load i32, ptr %i, align 4
57  %idxprom1 = sext i32 %5 to i64
58  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
59  %6 = load i16, ptr %arrayidx2, align 2
60  %conv3 = sext i16 %6 to i32
61  %add = add nsw i32 %conv3, %conv
62  %conv4 = trunc i32 %add to i16
63  store i16 %conv4, ptr %arrayidx2, align 2
64  %7 = load ptr, ptr %y.addr, align 8
65  %8 = load i32, ptr %i, align 4
66  %add5 = add nsw i32 %8, 1
67  %idxprom6 = sext i32 %add5 to i64
68  %arrayidx7 = getelementptr inbounds i16, ptr %7, i64 %idxprom6
69  %9 = load i16, ptr %arrayidx7, align 2
70  %conv8 = sext i16 %9 to i32
71  %10 = load ptr, ptr %x.addr, align 8
72  %11 = load i32, ptr %i, align 4
73  %add9 = add nsw i32 %11, 1
74  %idxprom10 = sext i32 %add9 to i64
75  %arrayidx11 = getelementptr inbounds i16, ptr %10, i64 %idxprom10
76  %12 = load i16, ptr %arrayidx11, align 2
77  %conv12 = sext i16 %12 to i32
78  %add13 = add nsw i32 %conv12, %conv8
79  %conv14 = trunc i32 %add13 to i16
80  store i16 %conv14, ptr %arrayidx11, align 2
81  %13 = load ptr, ptr %y.addr, align 8
82  %14 = load i32, ptr %i, align 4
83  %add15 = add nsw i32 %14, 2
84  %idxprom16 = sext i32 %add15 to i64
85  %arrayidx17 = getelementptr inbounds i16, ptr %13, i64 %idxprom16
86  %15 = load i16, ptr %arrayidx17, align 2
87  %conv18 = sext i16 %15 to i32
88  %16 = load ptr, ptr %x.addr, align 8
89  %17 = load i32, ptr %i, align 4
90  %add19 = add nsw i32 %17, 2
91  %idxprom20 = sext i32 %add19 to i64
92  %arrayidx21 = getelementptr inbounds i16, ptr %16, i64 %idxprom20
93  %18 = load i16, ptr %arrayidx21, align 2
94  %conv22 = sext i16 %18 to i32
95  %add23 = add nsw i32 %conv22, %conv18
96  %conv24 = trunc i32 %add23 to i16
97  store i16 %conv24, ptr %arrayidx21, align 2
98  %19 = load ptr, ptr %y.addr, align 8
99  %20 = load i32, ptr %i, align 4
100  %add25 = add nsw i32 %20, 3
101  %idxprom26 = sext i32 %add25 to i64
102  %arrayidx27 = getelementptr inbounds i16, ptr %19, i64 %idxprom26
103  %21 = load i16, ptr %arrayidx27, align 2
104  %conv28 = sext i16 %21 to i32
105  %22 = load ptr, ptr %x.addr, align 8
106  %23 = load i32, ptr %i, align 4
107  %add29 = add nsw i32 %23, 3
108  %idxprom30 = sext i32 %add29 to i64
109  %arrayidx31 = getelementptr inbounds i16, ptr %22, i64 %idxprom30
110  %24 = load i16, ptr %arrayidx31, align 2
111  %conv32 = sext i16 %24 to i32
112  %add33 = add nsw i32 %conv32, %conv28
113  %conv34 = trunc i32 %add33 to i16
114  store i16 %conv34, ptr %arrayidx31, align 2
115  br label %for.inc
116
117for.inc:
118  %25 = load i32, ptr %i, align 4
119  %add35 = add nsw i32 %25, 4
120  store i32 %add35, ptr %i, align 4
121  br label %for.cond
122
123for.end:
124  ret void
125}
126
127; for(int i =0; i < 1024; i+=4) {
128;   x[i] += y[i];
129;   x[i+1] -= y[i+1];
130;   x[i+2] += y[i+2];
131;   x[i+3] -= y[i+3];
132; }
133define void @addsubs(ptr noalias noundef %x, ptr noundef %y, i32 noundef %n) {
134; CHECK-LABEL: @addsubs(
135; CHECK-NEXT:  entry:
136; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
137; CHECK:       vector.body:
138; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
139; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
140; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
141; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
142; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
143; CHECK-NEXT:    [[WIDE_VEC24:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
144; CHECK-NEXT:    [[TMP2:%.*]] = add <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
145; CHECK-NEXT:    [[TMP3:%.*]] = sub <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
146; CHECK-NEXT:    [[TMP4:%.*]] = add <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
147; CHECK-NEXT:    [[TMP6:%.*]] = sub <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
148; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <32 x i16> [[TMP2]], <32 x i16> [[TMP3]], <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 33, i32 37, i32 41, i32 45, i32 49, i32 53, i32 57, i32 61>
149; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <32 x i16> [[TMP4]], <32 x i16> [[TMP6]], <16 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 35, i32 39, i32 43, i32 47, i32 51, i32 55, i32 59, i32 63>
150; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = shufflevector <16 x i16> [[TMP7]], <16 x i16> [[TMP8]], <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
151; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP1]], align 2
152; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
153; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
154; CHECK-NEXT:    br i1 [[TMP9]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
155; CHECK:       for.end:
156; CHECK-NEXT:    ret void
157;
158entry:
159  %x.addr = alloca ptr, align 8
160  %y.addr = alloca ptr, align 8
161  %n.addr = alloca i32, align 4
162  %i = alloca i32, align 4
163  store ptr %x, ptr %x.addr, align 8
164  store ptr %y, ptr %y.addr, align 8
165  store i32 %n, ptr %n.addr, align 4
166  store i32 0, ptr %i, align 4
167  br label %for.cond
168
169for.cond:
170  %0 = load i32, ptr %i, align 4
171  %cmp = icmp slt i32 %0, 1024
172  br i1 %cmp, label %for.body, label %for.end
173
174for.body:
175  %1 = load ptr, ptr %y.addr, align 8
176  %2 = load i32, ptr %i, align 4
177  %idxprom = sext i32 %2 to i64
178  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
179  %3 = load i16, ptr %arrayidx, align 2
180  %conv = sext i16 %3 to i32
181  %4 = load ptr, ptr %x.addr, align 8
182  %5 = load i32, ptr %i, align 4
183  %idxprom1 = sext i32 %5 to i64
184  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
185  %6 = load i16, ptr %arrayidx2, align 2
186  %conv3 = sext i16 %6 to i32
187  %add = add nsw i32 %conv3, %conv
188  %conv4 = trunc i32 %add to i16
189  store i16 %conv4, ptr %arrayidx2, align 2
190  %7 = load ptr, ptr %y.addr, align 8
191  %8 = load i32, ptr %i, align 4
192  %add5 = add nsw i32 %8, 1
193  %idxprom6 = sext i32 %add5 to i64
194  %arrayidx7 = getelementptr inbounds i16, ptr %7, i64 %idxprom6
195  %9 = load i16, ptr %arrayidx7, align 2
196  %conv8 = sext i16 %9 to i32
197  %10 = load ptr, ptr %x.addr, align 8
198  %11 = load i32, ptr %i, align 4
199  %add9 = add nsw i32 %11, 1
200  %idxprom10 = sext i32 %add9 to i64
201  %arrayidx11 = getelementptr inbounds i16, ptr %10, i64 %idxprom10
202  %12 = load i16, ptr %arrayidx11, align 2
203  %conv12 = sext i16 %12 to i32
204  %sub = sub nsw i32 %conv12, %conv8
205  %conv13 = trunc i32 %sub to i16
206  store i16 %conv13, ptr %arrayidx11, align 2
207  %13 = load ptr, ptr %y.addr, align 8
208  %14 = load i32, ptr %i, align 4
209  %add14 = add nsw i32 %14, 2
210  %idxprom15 = sext i32 %add14 to i64
211  %arrayidx16 = getelementptr inbounds i16, ptr %13, i64 %idxprom15
212  %15 = load i16, ptr %arrayidx16, align 2
213  %conv17 = sext i16 %15 to i32
214  %16 = load ptr, ptr %x.addr, align 8
215  %17 = load i32, ptr %i, align 4
216  %add18 = add nsw i32 %17, 2
217  %idxprom19 = sext i32 %add18 to i64
218  %arrayidx20 = getelementptr inbounds i16, ptr %16, i64 %idxprom19
219  %18 = load i16, ptr %arrayidx20, align 2
220  %conv21 = sext i16 %18 to i32
221  %add22 = add nsw i32 %conv21, %conv17
222  %conv23 = trunc i32 %add22 to i16
223  store i16 %conv23, ptr %arrayidx20, align 2
224  %19 = load ptr, ptr %y.addr, align 8
225  %20 = load i32, ptr %i, align 4
226  %add24 = add nsw i32 %20, 3
227  %idxprom25 = sext i32 %add24 to i64
228  %arrayidx26 = getelementptr inbounds i16, ptr %19, i64 %idxprom25
229  %21 = load i16, ptr %arrayidx26, align 2
230  %conv27 = sext i16 %21 to i32
231  %22 = load ptr, ptr %x.addr, align 8
232  %23 = load i32, ptr %i, align 4
233  %add28 = add nsw i32 %23, 3
234  %idxprom29 = sext i32 %add28 to i64
235  %arrayidx30 = getelementptr inbounds i16, ptr %22, i64 %idxprom29
236  %24 = load i16, ptr %arrayidx30, align 2
237  %conv31 = sext i16 %24 to i32
238  %sub32 = sub nsw i32 %conv31, %conv27
239  %conv33 = trunc i32 %sub32 to i16
240  store i16 %conv33, ptr %arrayidx30, align 2
241  br label %for.inc
242
243for.inc:
244  %25 = load i32, ptr %i, align 4
245  %add34 = add nsw i32 %25, 4
246  store i32 %add34, ptr %i, align 4
247  br label %for.cond
248
249for.end:
250  ret void
251}
252
253; for(int i =0; i < 1024; i+=4) {
254;   x[i] += y[i];
255;   x[i+1] += y[i+1];
256;   x[i+2] -= y[i+2];
257;   x[i+3] -= y[i+3];
258; }
259define void @add2sub2(ptr noalias noundef %x, ptr noundef %y, i32 noundef %n) {
260; CHECK-LABEL: @add2sub2(
261; CHECK-NEXT:  entry:
262; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
263; CHECK:       vector.body:
264; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
265; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
266; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
267; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
268; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
269; CHECK-NEXT:    [[WIDE_VEC24:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
270; CHECK-NEXT:    [[TMP2:%.*]] = add <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
271; CHECK-NEXT:    [[TMP3:%.*]] = add <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
272; CHECK-NEXT:    [[TMP4:%.*]] = sub <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
273; CHECK-NEXT:    [[TMP6:%.*]] = sub <32 x i16> [[WIDE_VEC24]], [[WIDE_VEC]]
274; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <32 x i16> [[TMP2]], <32 x i16> [[TMP3]], <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 33, i32 37, i32 41, i32 45, i32 49, i32 53, i32 57, i32 61>
275; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <32 x i16> [[TMP4]], <32 x i16> [[TMP6]], <16 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 35, i32 39, i32 43, i32 47, i32 51, i32 55, i32 59, i32 63>
276; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = shufflevector <16 x i16> [[TMP7]], <16 x i16> [[TMP8]], <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
277; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP1]], align 2
278; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
279; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
280; CHECK-NEXT:    br i1 [[TMP9]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
281; CHECK:       for.end:
282; CHECK-NEXT:    ret void
283;
284entry:
285  %x.addr = alloca ptr, align 8
286  %y.addr = alloca ptr, align 8
287  %n.addr = alloca i32, align 4
288  %i = alloca i32, align 4
289  store ptr %x, ptr %x.addr, align 8
290  store ptr %y, ptr %y.addr, align 8
291  store i32 %n, ptr %n.addr, align 4
292  store i32 0, ptr %i, align 4
293  br label %for.cond
294
295for.cond:
296  %0 = load i32, ptr %i, align 4
297  %cmp = icmp slt i32 %0, 1024
298  br i1 %cmp, label %for.body, label %for.end
299
300for.body:
301  %1 = load ptr, ptr %y.addr, align 8
302  %2 = load i32, ptr %i, align 4
303  %idxprom = sext i32 %2 to i64
304  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
305  %3 = load i16, ptr %arrayidx, align 2
306  %conv = sext i16 %3 to i32
307  %4 = load ptr, ptr %x.addr, align 8
308  %5 = load i32, ptr %i, align 4
309  %idxprom1 = sext i32 %5 to i64
310  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
311  %6 = load i16, ptr %arrayidx2, align 2
312  %conv3 = sext i16 %6 to i32
313  %add = add nsw i32 %conv3, %conv
314  %conv4 = trunc i32 %add to i16
315  store i16 %conv4, ptr %arrayidx2, align 2
316  %7 = load ptr, ptr %y.addr, align 8
317  %8 = load i32, ptr %i, align 4
318  %add5 = add nsw i32 %8, 1
319  %idxprom6 = sext i32 %add5 to i64
320  %arrayidx7 = getelementptr inbounds i16, ptr %7, i64 %idxprom6
321  %9 = load i16, ptr %arrayidx7, align 2
322  %conv8 = sext i16 %9 to i32
323  %10 = load ptr, ptr %x.addr, align 8
324  %11 = load i32, ptr %i, align 4
325  %add9 = add nsw i32 %11, 1
326  %idxprom10 = sext i32 %add9 to i64
327  %arrayidx11 = getelementptr inbounds i16, ptr %10, i64 %idxprom10
328  %12 = load i16, ptr %arrayidx11, align 2
329  %conv12 = sext i16 %12 to i32
330  %add13 = add nsw i32 %conv12, %conv8
331  %conv14 = trunc i32 %add13 to i16
332  store i16 %conv14, ptr %arrayidx11, align 2
333  %13 = load ptr, ptr %y.addr, align 8
334  %14 = load i32, ptr %i, align 4
335  %add15 = add nsw i32 %14, 2
336  %idxprom16 = sext i32 %add15 to i64
337  %arrayidx17 = getelementptr inbounds i16, ptr %13, i64 %idxprom16
338  %15 = load i16, ptr %arrayidx17, align 2
339  %conv18 = sext i16 %15 to i32
340  %16 = load ptr, ptr %x.addr, align 8
341  %17 = load i32, ptr %i, align 4
342  %add19 = add nsw i32 %17, 2
343  %idxprom20 = sext i32 %add19 to i64
344  %arrayidx21 = getelementptr inbounds i16, ptr %16, i64 %idxprom20
345  %18 = load i16, ptr %arrayidx21, align 2
346  %conv22 = sext i16 %18 to i32
347  %sub = sub nsw i32 %conv22, %conv18
348  %conv23 = trunc i32 %sub to i16
349  store i16 %conv23, ptr %arrayidx21, align 2
350  %19 = load ptr, ptr %y.addr, align 8
351  %20 = load i32, ptr %i, align 4
352  %add24 = add nsw i32 %20, 3
353  %idxprom25 = sext i32 %add24 to i64
354  %arrayidx26 = getelementptr inbounds i16, ptr %19, i64 %idxprom25
355  %21 = load i16, ptr %arrayidx26, align 2
356  %conv27 = sext i16 %21 to i32
357  %22 = load ptr, ptr %x.addr, align 8
358  %23 = load i32, ptr %i, align 4
359  %add28 = add nsw i32 %23, 3
360  %idxprom29 = sext i32 %add28 to i64
361  %arrayidx30 = getelementptr inbounds i16, ptr %22, i64 %idxprom29
362  %24 = load i16, ptr %arrayidx30, align 2
363  %conv31 = sext i16 %24 to i32
364  %sub32 = sub nsw i32 %conv31, %conv27
365  %conv33 = trunc i32 %sub32 to i16
366  store i16 %conv33, ptr %arrayidx30, align 2
367  br label %for.inc
368
369for.inc:
370  %25 = load i32, ptr %i, align 4
371  %add34 = add nsw i32 %25, 4
372  store i32 %add34, ptr %i, align 4
373  br label %for.cond
374
375for.end:
376  ret void
377}
378
379; for(int i =0; i < 1024; i+=4) {
380;   x[i] += y[i] * z[i];
381;   x[i+1] += y[i+1] * z[i+1];
382;   x[i+2] += y[i+2] * z[i+2];
383;   x[i+3] += y[i+3] * z[i+3];
384; }
385define void @addmul(ptr noalias noundef %x, ptr noundef %y, ptr noundef %z, i32 noundef %n) {
386; CHECK-LABEL: @addmul(
387; CHECK-NEXT:  entry:
388; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
389; CHECK:       vector.body:
390; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
391; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
392; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
393; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
394; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[Z:%.*]], i64 [[OFFSET_IDX]]
395; CHECK-NEXT:    [[WIDE_VEC31:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
396; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
397; CHECK-NEXT:    [[WIDE_VEC36:%.*]] = load <32 x i16>, ptr [[TMP2]], align 2
398; CHECK-NEXT:    [[TMP4:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
399; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = add <32 x i16> [[TMP4]], [[WIDE_VEC36]]
400; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP2]], align 2
401; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
402; CHECK-NEXT:    [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
403; CHECK-NEXT:    br i1 [[TMP5]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
404; CHECK:       for.end:
405; CHECK-NEXT:    ret void
406;
407entry:
408  %x.addr = alloca ptr, align 8
409  %y.addr = alloca ptr, align 8
410  %z.addr = alloca ptr, align 8
411  %n.addr = alloca i32, align 4
412  %i = alloca i32, align 4
413  store ptr %x, ptr %x.addr, align 8
414  store ptr %y, ptr %y.addr, align 8
415  store ptr %z, ptr %z.addr, align 8
416  store i32 %n, ptr %n.addr, align 4
417  store i32 0, ptr %i, align 4
418  br label %for.cond
419
420for.cond:
421  %0 = load i32, ptr %i, align 4
422  %cmp = icmp slt i32 %0, 1024
423  br i1 %cmp, label %for.body, label %for.end
424
425for.body:
426  %1 = load ptr, ptr %y.addr, align 8
427  %2 = load i32, ptr %i, align 4
428  %idxprom = sext i32 %2 to i64
429  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
430  %3 = load i16, ptr %arrayidx, align 2
431  %conv = sext i16 %3 to i32
432  %4 = load ptr, ptr %z.addr, align 8
433  %5 = load i32, ptr %i, align 4
434  %idxprom1 = sext i32 %5 to i64
435  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
436  %6 = load i16, ptr %arrayidx2, align 2
437  %conv3 = sext i16 %6 to i32
438  %mul = mul nsw i32 %conv, %conv3
439  %7 = load ptr, ptr %x.addr, align 8
440  %8 = load i32, ptr %i, align 4
441  %idxprom4 = sext i32 %8 to i64
442  %arrayidx5 = getelementptr inbounds i16, ptr %7, i64 %idxprom4
443  %9 = load i16, ptr %arrayidx5, align 2
444  %conv6 = sext i16 %9 to i32
445  %add = add nsw i32 %conv6, %mul
446  %conv7 = trunc i32 %add to i16
447  store i16 %conv7, ptr %arrayidx5, align 2
448  %10 = load ptr, ptr %y.addr, align 8
449  %11 = load i32, ptr %i, align 4
450  %add8 = add nsw i32 %11, 1
451  %idxprom9 = sext i32 %add8 to i64
452  %arrayidx10 = getelementptr inbounds i16, ptr %10, i64 %idxprom9
453  %12 = load i16, ptr %arrayidx10, align 2
454  %conv11 = sext i16 %12 to i32
455  %13 = load ptr, ptr %z.addr, align 8
456  %14 = load i32, ptr %i, align 4
457  %add12 = add nsw i32 %14, 1
458  %idxprom13 = sext i32 %add12 to i64
459  %arrayidx14 = getelementptr inbounds i16, ptr %13, i64 %idxprom13
460  %15 = load i16, ptr %arrayidx14, align 2
461  %conv15 = sext i16 %15 to i32
462  %mul16 = mul nsw i32 %conv11, %conv15
463  %16 = load ptr, ptr %x.addr, align 8
464  %17 = load i32, ptr %i, align 4
465  %add17 = add nsw i32 %17, 1
466  %idxprom18 = sext i32 %add17 to i64
467  %arrayidx19 = getelementptr inbounds i16, ptr %16, i64 %idxprom18
468  %18 = load i16, ptr %arrayidx19, align 2
469  %conv20 = sext i16 %18 to i32
470  %add21 = add nsw i32 %conv20, %mul16
471  %conv22 = trunc i32 %add21 to i16
472  store i16 %conv22, ptr %arrayidx19, align 2
473  %19 = load ptr, ptr %y.addr, align 8
474  %20 = load i32, ptr %i, align 4
475  %add23 = add nsw i32 %20, 2
476  %idxprom24 = sext i32 %add23 to i64
477  %arrayidx25 = getelementptr inbounds i16, ptr %19, i64 %idxprom24
478  %21 = load i16, ptr %arrayidx25, align 2
479  %conv26 = sext i16 %21 to i32
480  %22 = load ptr, ptr %z.addr, align 8
481  %23 = load i32, ptr %i, align 4
482  %add27 = add nsw i32 %23, 2
483  %idxprom28 = sext i32 %add27 to i64
484  %arrayidx29 = getelementptr inbounds i16, ptr %22, i64 %idxprom28
485  %24 = load i16, ptr %arrayidx29, align 2
486  %conv30 = sext i16 %24 to i32
487  %mul31 = mul nsw i32 %conv26, %conv30
488  %25 = load ptr, ptr %x.addr, align 8
489  %26 = load i32, ptr %i, align 4
490  %add32 = add nsw i32 %26, 2
491  %idxprom33 = sext i32 %add32 to i64
492  %arrayidx34 = getelementptr inbounds i16, ptr %25, i64 %idxprom33
493  %27 = load i16, ptr %arrayidx34, align 2
494  %conv35 = sext i16 %27 to i32
495  %add36 = add nsw i32 %conv35, %mul31
496  %conv37 = trunc i32 %add36 to i16
497  store i16 %conv37, ptr %arrayidx34, align 2
498  %28 = load ptr, ptr %y.addr, align 8
499  %29 = load i32, ptr %i, align 4
500  %add38 = add nsw i32 %29, 3
501  %idxprom39 = sext i32 %add38 to i64
502  %arrayidx40 = getelementptr inbounds i16, ptr %28, i64 %idxprom39
503  %30 = load i16, ptr %arrayidx40, align 2
504  %conv41 = sext i16 %30 to i32
505  %31 = load ptr, ptr %z.addr, align 8
506  %32 = load i32, ptr %i, align 4
507  %add42 = add nsw i32 %32, 3
508  %idxprom43 = sext i32 %add42 to i64
509  %arrayidx44 = getelementptr inbounds i16, ptr %31, i64 %idxprom43
510  %33 = load i16, ptr %arrayidx44, align 2
511  %conv45 = sext i16 %33 to i32
512  %mul46 = mul nsw i32 %conv41, %conv45
513  %34 = load ptr, ptr %x.addr, align 8
514  %35 = load i32, ptr %i, align 4
515  %add47 = add nsw i32 %35, 3
516  %idxprom48 = sext i32 %add47 to i64
517  %arrayidx49 = getelementptr inbounds i16, ptr %34, i64 %idxprom48
518  %36 = load i16, ptr %arrayidx49, align 2
519  %conv50 = sext i16 %36 to i32
520  %add51 = add nsw i32 %conv50, %mul46
521  %conv52 = trunc i32 %add51 to i16
522  store i16 %conv52, ptr %arrayidx49, align 2
523  br label %for.inc
524
525for.inc:
526  %37 = load i32, ptr %i, align 4
527  %add53 = add nsw i32 %37, 4
528  store i32 %add53, ptr %i, align 4
529  br label %for.cond
530
531for.end:
532  ret void
533}
534
535; for(int i =0; i < 1024; i+=4) {
536;   x[i] += y[i] * z[i];
537;   x[i+1] -= y[i+1] * z[i+1];
538;   x[i+2] += y[i+2] * z[i+2];
539;   x[i+3] -= y[i+3] * z[i+3];
540; }
541define void @addsubsmul(ptr noalias noundef %x, ptr noundef %y, ptr noundef %z, i32 noundef %n) {
542; CHECK-LABEL: @addsubsmul(
543; CHECK-NEXT:  entry:
544; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
545; CHECK:       vector.body:
546; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
547; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
548; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
549; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
550; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[Z:%.*]], i64 [[OFFSET_IDX]]
551; CHECK-NEXT:    [[WIDE_VEC31:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
552; CHECK-NEXT:    [[TMP2:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
553; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
554; CHECK-NEXT:    [[WIDE_VEC36:%.*]] = load <32 x i16>, ptr [[TMP3]], align 2
555; CHECK-NEXT:    [[TMP4:%.*]] = add <32 x i16> [[TMP2]], [[WIDE_VEC36]]
556; CHECK-NEXT:    [[TMP5:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
557; CHECK-NEXT:    [[TMP6:%.*]] = sub <32 x i16> [[WIDE_VEC36]], [[TMP5]]
558; CHECK-NEXT:    [[TMP7:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
559; CHECK-NEXT:    [[TMP8:%.*]] = add <32 x i16> [[TMP7]], [[WIDE_VEC36]]
560; CHECK-NEXT:    [[TMP10:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
561; CHECK-NEXT:    [[TMP11:%.*]] = sub <32 x i16> [[WIDE_VEC36]], [[TMP10]]
562; CHECK-NEXT:    [[TMP12:%.*]] = shufflevector <32 x i16> [[TMP4]], <32 x i16> [[TMP6]], <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 33, i32 37, i32 41, i32 45, i32 49, i32 53, i32 57, i32 61>
563; CHECK-NEXT:    [[TMP13:%.*]] = shufflevector <32 x i16> [[TMP8]], <32 x i16> [[TMP11]], <16 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 35, i32 39, i32 43, i32 47, i32 51, i32 55, i32 59, i32 63>
564; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = shufflevector <16 x i16> [[TMP12]], <16 x i16> [[TMP13]], <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
565; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP3]], align 2
566; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
567; CHECK-NEXT:    [[TMP14:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
568; CHECK-NEXT:    br i1 [[TMP14]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
569; CHECK:       for.end:
570; CHECK-NEXT:    ret void
571;
572entry:
573  %x.addr = alloca ptr, align 8
574  %y.addr = alloca ptr, align 8
575  %z.addr = alloca ptr, align 8
576  %n.addr = alloca i32, align 4
577  %i = alloca i32, align 4
578  store ptr %x, ptr %x.addr, align 8
579  store ptr %y, ptr %y.addr, align 8
580  store ptr %z, ptr %z.addr, align 8
581  store i32 %n, ptr %n.addr, align 4
582  store i32 0, ptr %i, align 4
583  br label %for.cond
584
585for.cond:
586  %0 = load i32, ptr %i, align 4
587  %cmp = icmp slt i32 %0, 1024
588  br i1 %cmp, label %for.body, label %for.end
589
590for.body:
591  %1 = load ptr, ptr %y.addr, align 8
592  %2 = load i32, ptr %i, align 4
593  %idxprom = sext i32 %2 to i64
594  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
595  %3 = load i16, ptr %arrayidx, align 2
596  %conv = sext i16 %3 to i32
597  %4 = load ptr, ptr %z.addr, align 8
598  %5 = load i32, ptr %i, align 4
599  %idxprom1 = sext i32 %5 to i64
600  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
601  %6 = load i16, ptr %arrayidx2, align 2
602  %conv3 = sext i16 %6 to i32
603  %mul = mul nsw i32 %conv, %conv3
604  %7 = load ptr, ptr %x.addr, align 8
605  %8 = load i32, ptr %i, align 4
606  %idxprom4 = sext i32 %8 to i64
607  %arrayidx5 = getelementptr inbounds i16, ptr %7, i64 %idxprom4
608  %9 = load i16, ptr %arrayidx5, align 2
609  %conv6 = sext i16 %9 to i32
610  %add = add nsw i32 %conv6, %mul
611  %conv7 = trunc i32 %add to i16
612  store i16 %conv7, ptr %arrayidx5, align 2
613  %10 = load ptr, ptr %y.addr, align 8
614  %11 = load i32, ptr %i, align 4
615  %add8 = add nsw i32 %11, 1
616  %idxprom9 = sext i32 %add8 to i64
617  %arrayidx10 = getelementptr inbounds i16, ptr %10, i64 %idxprom9
618  %12 = load i16, ptr %arrayidx10, align 2
619  %conv11 = sext i16 %12 to i32
620  %13 = load ptr, ptr %z.addr, align 8
621  %14 = load i32, ptr %i, align 4
622  %add12 = add nsw i32 %14, 1
623  %idxprom13 = sext i32 %add12 to i64
624  %arrayidx14 = getelementptr inbounds i16, ptr %13, i64 %idxprom13
625  %15 = load i16, ptr %arrayidx14, align 2
626  %conv15 = sext i16 %15 to i32
627  %mul16 = mul nsw i32 %conv11, %conv15
628  %16 = load ptr, ptr %x.addr, align 8
629  %17 = load i32, ptr %i, align 4
630  %add17 = add nsw i32 %17, 1
631  %idxprom18 = sext i32 %add17 to i64
632  %arrayidx19 = getelementptr inbounds i16, ptr %16, i64 %idxprom18
633  %18 = load i16, ptr %arrayidx19, align 2
634  %conv20 = sext i16 %18 to i32
635  %sub = sub nsw i32 %conv20, %mul16
636  %conv21 = trunc i32 %sub to i16
637  store i16 %conv21, ptr %arrayidx19, align 2
638  %19 = load ptr, ptr %y.addr, align 8
639  %20 = load i32, ptr %i, align 4
640  %add22 = add nsw i32 %20, 2
641  %idxprom23 = sext i32 %add22 to i64
642  %arrayidx24 = getelementptr inbounds i16, ptr %19, i64 %idxprom23
643  %21 = load i16, ptr %arrayidx24, align 2
644  %conv25 = sext i16 %21 to i32
645  %22 = load ptr, ptr %z.addr, align 8
646  %23 = load i32, ptr %i, align 4
647  %add26 = add nsw i32 %23, 2
648  %idxprom27 = sext i32 %add26 to i64
649  %arrayidx28 = getelementptr inbounds i16, ptr %22, i64 %idxprom27
650  %24 = load i16, ptr %arrayidx28, align 2
651  %conv29 = sext i16 %24 to i32
652  %mul30 = mul nsw i32 %conv25, %conv29
653  %25 = load ptr, ptr %x.addr, align 8
654  %26 = load i32, ptr %i, align 4
655  %add31 = add nsw i32 %26, 2
656  %idxprom32 = sext i32 %add31 to i64
657  %arrayidx33 = getelementptr inbounds i16, ptr %25, i64 %idxprom32
658  %27 = load i16, ptr %arrayidx33, align 2
659  %conv34 = sext i16 %27 to i32
660  %add35 = add nsw i32 %conv34, %mul30
661  %conv36 = trunc i32 %add35 to i16
662  store i16 %conv36, ptr %arrayidx33, align 2
663  %28 = load ptr, ptr %y.addr, align 8
664  %29 = load i32, ptr %i, align 4
665  %add37 = add nsw i32 %29, 3
666  %idxprom38 = sext i32 %add37 to i64
667  %arrayidx39 = getelementptr inbounds i16, ptr %28, i64 %idxprom38
668  %30 = load i16, ptr %arrayidx39, align 2
669  %conv40 = sext i16 %30 to i32
670  %31 = load ptr, ptr %z.addr, align 8
671  %32 = load i32, ptr %i, align 4
672  %add41 = add nsw i32 %32, 3
673  %idxprom42 = sext i32 %add41 to i64
674  %arrayidx43 = getelementptr inbounds i16, ptr %31, i64 %idxprom42
675  %33 = load i16, ptr %arrayidx43, align 2
676  %conv44 = sext i16 %33 to i32
677  %mul45 = mul nsw i32 %conv40, %conv44
678  %34 = load ptr, ptr %x.addr, align 8
679  %35 = load i32, ptr %i, align 4
680  %add46 = add nsw i32 %35, 3
681  %idxprom47 = sext i32 %add46 to i64
682  %arrayidx48 = getelementptr inbounds i16, ptr %34, i64 %idxprom47
683  %36 = load i16, ptr %arrayidx48, align 2
684  %conv49 = sext i16 %36 to i32
685  %sub50 = sub nsw i32 %conv49, %mul45
686  %conv51 = trunc i32 %sub50 to i16
687  store i16 %conv51, ptr %arrayidx48, align 2
688  br label %for.inc
689
690for.inc:
691  %37 = load i32, ptr %i, align 4
692  %add52 = add nsw i32 %37, 4
693  store i32 %add52, ptr %i, align 4
694  br label %for.cond
695
696for.end:
697  ret void
698}
699
700; for(int i =0; i < 1024; i+=4) {
701;   x[i] += y[i] * z[i];
702;   x[i+1] += y[i+1] * z[i+1];
703;   x[i+2] -= y[i+2] * z[i+2];
704;   x[i+3] -= y[i+3] * z[i+3];
705; }
706define void @add2sub2mul(ptr noalias noundef %x, ptr noundef %y, ptr noundef %z, i32 noundef %n) {
707; CHECK-LABEL: @add2sub2mul(
708; CHECK-NEXT:  entry:
709; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
710; CHECK:       vector.body:
711; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
712; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 2
713; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds nuw i16, ptr [[Y:%.*]], i64 [[OFFSET_IDX]]
714; CHECK-NEXT:    [[WIDE_VEC:%.*]] = load <32 x i16>, ptr [[TMP0]], align 2
715; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw i16, ptr [[Z:%.*]], i64 [[OFFSET_IDX]]
716; CHECK-NEXT:    [[WIDE_VEC31:%.*]] = load <32 x i16>, ptr [[TMP1]], align 2
717; CHECK-NEXT:    [[TMP2:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
718; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds nuw i16, ptr [[X:%.*]], i64 [[OFFSET_IDX]]
719; CHECK-NEXT:    [[WIDE_VEC36:%.*]] = load <32 x i16>, ptr [[TMP3]], align 2
720; CHECK-NEXT:    [[TMP4:%.*]] = add <32 x i16> [[TMP2]], [[WIDE_VEC36]]
721; CHECK-NEXT:    [[TMP5:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
722; CHECK-NEXT:    [[TMP6:%.*]] = add <32 x i16> [[TMP5]], [[WIDE_VEC36]]
723; CHECK-NEXT:    [[TMP7:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
724; CHECK-NEXT:    [[TMP8:%.*]] = sub <32 x i16> [[WIDE_VEC36]], [[TMP7]]
725; CHECK-NEXT:    [[TMP10:%.*]] = mul <32 x i16> [[WIDE_VEC31]], [[WIDE_VEC]]
726; CHECK-NEXT:    [[TMP11:%.*]] = sub <32 x i16> [[WIDE_VEC36]], [[TMP10]]
727; CHECK-NEXT:    [[TMP12:%.*]] = shufflevector <32 x i16> [[TMP4]], <32 x i16> [[TMP6]], <16 x i32> <i32 0, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 33, i32 37, i32 41, i32 45, i32 49, i32 53, i32 57, i32 61>
728; CHECK-NEXT:    [[TMP13:%.*]] = shufflevector <32 x i16> [[TMP8]], <32 x i16> [[TMP11]], <16 x i32> <i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 35, i32 39, i32 43, i32 47, i32 51, i32 55, i32 59, i32 63>
729; CHECK-NEXT:    [[INTERLEAVED_VEC:%.*]] = shufflevector <16 x i16> [[TMP12]], <16 x i16> [[TMP13]], <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
730; CHECK-NEXT:    store <32 x i16> [[INTERLEAVED_VEC]], ptr [[TMP3]], align 2
731; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
732; CHECK-NEXT:    [[TMP14:%.*]] = icmp eq i64 [[INDEX_NEXT]], 256
733; CHECK-NEXT:    br i1 [[TMP14]], label [[FOR_END:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
734; CHECK:       for.end:
735; CHECK-NEXT:    ret void
736;
737entry:
738  %x.addr = alloca ptr, align 8
739  %y.addr = alloca ptr, align 8
740  %z.addr = alloca ptr, align 8
741  %n.addr = alloca i32, align 4
742  %i = alloca i32, align 4
743  store ptr %x, ptr %x.addr, align 8
744  store ptr %y, ptr %y.addr, align 8
745  store ptr %z, ptr %z.addr, align 8
746  store i32 %n, ptr %n.addr, align 4
747  store i32 0, ptr %i, align 4
748  br label %for.cond
749
750for.cond:
751  %0 = load i32, ptr %i, align 4
752  %cmp = icmp slt i32 %0, 1024
753  br i1 %cmp, label %for.body, label %for.end
754
755for.body:
756  %1 = load ptr, ptr %y.addr, align 8
757  %2 = load i32, ptr %i, align 4
758  %idxprom = sext i32 %2 to i64
759  %arrayidx = getelementptr inbounds i16, ptr %1, i64 %idxprom
760  %3 = load i16, ptr %arrayidx, align 2
761  %conv = sext i16 %3 to i32
762  %4 = load ptr, ptr %z.addr, align 8
763  %5 = load i32, ptr %i, align 4
764  %idxprom1 = sext i32 %5 to i64
765  %arrayidx2 = getelementptr inbounds i16, ptr %4, i64 %idxprom1
766  %6 = load i16, ptr %arrayidx2, align 2
767  %conv3 = sext i16 %6 to i32
768  %mul = mul nsw i32 %conv, %conv3
769  %7 = load ptr, ptr %x.addr, align 8
770  %8 = load i32, ptr %i, align 4
771  %idxprom4 = sext i32 %8 to i64
772  %arrayidx5 = getelementptr inbounds i16, ptr %7, i64 %idxprom4
773  %9 = load i16, ptr %arrayidx5, align 2
774  %conv6 = sext i16 %9 to i32
775  %add = add nsw i32 %conv6, %mul
776  %conv7 = trunc i32 %add to i16
777  store i16 %conv7, ptr %arrayidx5, align 2
778  %10 = load ptr, ptr %y.addr, align 8
779  %11 = load i32, ptr %i, align 4
780  %add8 = add nsw i32 %11, 1
781  %idxprom9 = sext i32 %add8 to i64
782  %arrayidx10 = getelementptr inbounds i16, ptr %10, i64 %idxprom9
783  %12 = load i16, ptr %arrayidx10, align 2
784  %conv11 = sext i16 %12 to i32
785  %13 = load ptr, ptr %z.addr, align 8
786  %14 = load i32, ptr %i, align 4
787  %add12 = add nsw i32 %14, 1
788  %idxprom13 = sext i32 %add12 to i64
789  %arrayidx14 = getelementptr inbounds i16, ptr %13, i64 %idxprom13
790  %15 = load i16, ptr %arrayidx14, align 2
791  %conv15 = sext i16 %15 to i32
792  %mul16 = mul nsw i32 %conv11, %conv15
793  %16 = load ptr, ptr %x.addr, align 8
794  %17 = load i32, ptr %i, align 4
795  %add17 = add nsw i32 %17, 1
796  %idxprom18 = sext i32 %add17 to i64
797  %arrayidx19 = getelementptr inbounds i16, ptr %16, i64 %idxprom18
798  %18 = load i16, ptr %arrayidx19, align 2
799  %conv20 = sext i16 %18 to i32
800  %add21 = add nsw i32 %conv20, %mul16
801  %conv22 = trunc i32 %add21 to i16
802  store i16 %conv22, ptr %arrayidx19, align 2
803  %19 = load ptr, ptr %y.addr, align 8
804  %20 = load i32, ptr %i, align 4
805  %add23 = add nsw i32 %20, 2
806  %idxprom24 = sext i32 %add23 to i64
807  %arrayidx25 = getelementptr inbounds i16, ptr %19, i64 %idxprom24
808  %21 = load i16, ptr %arrayidx25, align 2
809  %conv26 = sext i16 %21 to i32
810  %22 = load ptr, ptr %z.addr, align 8
811  %23 = load i32, ptr %i, align 4
812  %add27 = add nsw i32 %23, 2
813  %idxprom28 = sext i32 %add27 to i64
814  %arrayidx29 = getelementptr inbounds i16, ptr %22, i64 %idxprom28
815  %24 = load i16, ptr %arrayidx29, align 2
816  %conv30 = sext i16 %24 to i32
817  %mul31 = mul nsw i32 %conv26, %conv30
818  %25 = load ptr, ptr %x.addr, align 8
819  %26 = load i32, ptr %i, align 4
820  %add32 = add nsw i32 %26, 2
821  %idxprom33 = sext i32 %add32 to i64
822  %arrayidx34 = getelementptr inbounds i16, ptr %25, i64 %idxprom33
823  %27 = load i16, ptr %arrayidx34, align 2
824  %conv35 = sext i16 %27 to i32
825  %sub = sub nsw i32 %conv35, %mul31
826  %conv36 = trunc i32 %sub to i16
827  store i16 %conv36, ptr %arrayidx34, align 2
828  %28 = load ptr, ptr %y.addr, align 8
829  %29 = load i32, ptr %i, align 4
830  %add37 = add nsw i32 %29, 3
831  %idxprom38 = sext i32 %add37 to i64
832  %arrayidx39 = getelementptr inbounds i16, ptr %28, i64 %idxprom38
833  %30 = load i16, ptr %arrayidx39, align 2
834  %conv40 = sext i16 %30 to i32
835  %31 = load ptr, ptr %z.addr, align 8
836  %32 = load i32, ptr %i, align 4
837  %add41 = add nsw i32 %32, 3
838  %idxprom42 = sext i32 %add41 to i64
839  %arrayidx43 = getelementptr inbounds i16, ptr %31, i64 %idxprom42
840  %33 = load i16, ptr %arrayidx43, align 2
841  %conv44 = sext i16 %33 to i32
842  %mul45 = mul nsw i32 %conv40, %conv44
843  %34 = load ptr, ptr %x.addr, align 8
844  %35 = load i32, ptr %i, align 4
845  %add46 = add nsw i32 %35, 3
846  %idxprom47 = sext i32 %add46 to i64
847  %arrayidx48 = getelementptr inbounds i16, ptr %34, i64 %idxprom47
848  %36 = load i16, ptr %arrayidx48, align 2
849  %conv49 = sext i16 %36 to i32
850  %sub50 = sub nsw i32 %conv49, %mul45
851  %conv51 = trunc i32 %sub50 to i16
852  store i16 %conv51, ptr %arrayidx48, align 2
853  br label %for.inc
854
855for.inc:
856  %37 = load i32, ptr %i, align 4
857  %add52 = add nsw i32 %37, 4
858  store i32 %add52, ptr %i, align 4
859  br label %for.cond
860
861for.end:
862  ret void
863}
864