1; RUN: opt -mtriple=arm-none-none-eabi -mcpu=cortex-m33 < %s -arm-parallel-dsp -verify -S | FileCheck %s
2;
3; Alias check: check that the rewrite isn't triggered when there's a store
4; instruction possibly aliasing any mul load operands; arguments are passed
5; without 'restrict' enabled.
6;
7; CHECK-NOT:  call i32 @llvm.arm.smlad
8;
9define dso_local i32 @no_restrict(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
10entry:
11  %cmp24 = icmp sgt i32 %arg, 0
12  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
13
14for.body.preheader:
15  %.pre = load i16, i16* %arg3, align 2
16  %.pre27 = load i16, i16* %arg2, align 2
17  br label %for.body
18
19for.cond.cleanup:
20  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
21  ret i32 %mac1.0.lcssa
22
23for.body:
24  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
25  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
26  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
27  %0 = load i16, i16* %arrayidx, align 2
28
29; Store inserted here, aliasing with arrayidx, arrayidx1, arrayidx3
30  store i16 42, i16* %arrayidx, align 2
31
32  %add = add nuw nsw i32 %i.025, 1
33  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
34  %1 = load i16, i16* %arrayidx1, align 2
35  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
36  %2 = load i16, i16* %arrayidx3, align 2
37  %conv = sext i16 %2 to i32
38  %conv4 = sext i16 %0 to i32
39  %mul = mul nsw i32 %conv, %conv4
40  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
41  %3 = load i16, i16* %arrayidx6, align 2
42  %conv7 = sext i16 %3 to i32
43  %conv8 = sext i16 %1 to i32
44  %mul9 = mul nsw i32 %conv7, %conv8
45  %add10 = add i32 %mul, %mac1.026
46  %add11 = add i32 %mul9, %add10
47  %exitcond = icmp ne i32 %add, %arg
48  br i1 %exitcond, label %for.body, label %for.cond.cleanup
49}
50
51; Alias check: check that the rewrite isn't triggered when there's a store
52; aliasing one of the mul load operands. Arguments are now annotated with
53; 'noalias'.
54;
55; CHECK-NOT:  call i32 @llvm.arm.smlad
56;
57define dso_local i32 @restrict(i32 %arg, i32* noalias %arg1, i16* noalias readonly %arg2, i16* noalias readonly %arg3) {
58entry:
59  %cmp24 = icmp sgt i32 %arg, 0
60  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
61
62for.body.preheader:
63  %.pre = load i16, i16* %arg3, align 2
64  %.pre27 = load i16, i16* %arg2, align 2
65  br label %for.body
66
67for.cond.cleanup:
68  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
69  ret i32 %mac1.0.lcssa
70
71for.body:
72  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
73  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
74  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
75  %0 = load i16, i16* %arrayidx, align 2
76
77; Store inserted here, aliasing only with loads from 'arrayidx'.
78  store i16 42, i16* %arrayidx, align 2
79
80  %add = add nuw nsw i32 %i.025, 1
81  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
82  %1 = load i16, i16* %arrayidx1, align 2
83  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
84  %2 = load i16, i16* %arrayidx3, align 2
85  %conv = sext i16 %2 to i32
86  %conv4 = sext i16 %0 to i32
87  %mul = mul nsw i32 %conv, %conv4
88  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
89  %3 = load i16, i16* %arrayidx6, align 2
90  %conv7 = sext i16 %3 to i32
91  %conv8 = sext i16 %1 to i32
92  %mul9 = mul nsw i32 %conv7, %conv8
93  %add10 = add i32 %mul, %mac1.026
94
95; Here the Mul is the LHS, and the Add the RHS.
96  %add11 = add i32 %mul9, %add10
97
98  %exitcond = icmp ne i32 %add, %arg
99  br i1 %exitcond, label %for.body, label %for.cond.cleanup
100}
101
102; CHECK-LABEL: store_dominates_all
103; CHECK: store
104; CHECK: load
105; CHECK: load
106; CHECK: load
107; CHECK: load
108; CHECK: smlad
109define dso_local i32 @store_dominates_all(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
110entry:
111  %cmp24 = icmp sgt i32 %arg, 0
112  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
113
114for.body.preheader:
115  %.pre = load i16, i16* %arg3, align 2
116  %.pre27 = load i16, i16* %arg2, align 2
117  br label %for.body
118
119for.cond.cleanup:
120  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
121  ret i32 %mac1.0.lcssa
122
123for.body:
124  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
125  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
126  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
127  store i16 42, i16* %arrayidx, align 2
128  %0 = load i16, i16* %arrayidx, align 2
129  %add = add nuw nsw i32 %i.025, 1
130  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
131  %1 = load i16, i16* %arrayidx1, align 2
132  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
133  %2 = load i16, i16* %arrayidx3, align 2
134  %conv = sext i16 %2 to i32
135  %conv4 = sext i16 %0 to i32
136  %mul = mul nsw i32 %conv, %conv4
137  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
138  %3 = load i16, i16* %arrayidx6, align 2
139  %conv7 = sext i16 %3 to i32
140  %conv8 = sext i16 %1 to i32
141  %mul9 = mul nsw i32 %conv7, %conv8
142  %add10 = add i32 %mul, %mac1.026
143  %add11 = add i32 %mul9, %add10
144  %exitcond = icmp ne i32 %add, %arg
145  br i1 %exitcond, label %for.body, label %for.cond.cleanup
146}
147
148; CHECK-LABEL: loads_dominate
149; CHECK-NOT: store
150; CHECK: load i32
151; CHECK-NOT: store
152; CHECK: load i32
153; CHECK: store
154define dso_local i32 @loads_dominate(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
155entry:
156  %cmp24 = icmp sgt i32 %arg, 0
157  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
158
159for.body.preheader:
160  %.pre = load i16, i16* %arg3, align 2
161  %.pre27 = load i16, i16* %arg2, align 2
162  br label %for.body
163
164for.cond.cleanup:
165  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
166  ret i32 %mac1.0.lcssa
167
168for.body:
169  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
170  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
171  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
172  %0 = load i16, i16* %arrayidx, align 2
173  %add = add nuw nsw i32 %i.025, 1
174  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
175  %1 = load i16, i16* %arrayidx1, align 2
176  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
177  %2 = load i16, i16* %arrayidx3, align 2
178  %conv = sext i16 %2 to i32
179  %conv4 = sext i16 %0 to i32
180  %mul = mul nsw i32 %conv, %conv4
181  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
182  %3 = load i16, i16* %arrayidx6, align 2
183  %conv7 = sext i16 %3 to i32
184  %conv8 = sext i16 %1 to i32
185  %mul9 = mul nsw i32 %conv7, %conv8
186  %add10 = add i32 %mul, %mac1.026
187  %add11 = add i32 %mul9, %add10
188  store i16 42, i16* %arrayidx, align 2
189  %exitcond = icmp ne i32 %add, %arg
190  br i1 %exitcond, label %for.body, label %for.cond.cleanup
191}
192
193; CHECK-LABEL: store_alias_arg3_legal_1
194; CHECK-NOT: store
195; CHECK: phi i32
196; CHECK: [[IV:%[^ ]+]] = phi i32 [ %add
197; CHECK: [[ARG3_GEP:%[^ ]+]] = getelementptr inbounds i16, i16* %arg3, i32 [[IV]]
198; CHECK: [[ARG3:%[^ ]+]] = bitcast i16* [[ARG3_GEP]] to i32*
199; CHECK: load i32, i32* [[ARG3]]
200; CHECK: [[ARG2_GEP:%[^ ]+]] = getelementptr inbounds i16, i16* %arg2, i32 [[IV]]
201; CHECK: [[ARG2:%[^ ]+]] = bitcast i16* [[ARG2_GEP]] to i32*
202; CHECK: load i32, i32* [[ARG2]]
203; CHECK: store
204define dso_local i32 @store_alias_arg3_legal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) {
205entry:
206  %cmp24 = icmp sgt i32 %arg, 0
207  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
208
209for.body.preheader:
210  %.pre = load i16, i16* %arg3, align 2
211  %.pre27 = load i16, i16* %arg2, align 2
212  br label %for.body
213
214for.cond.cleanup:
215  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
216  ret i32 %mac1.0.lcssa
217
218for.body:
219  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
220  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
221  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
222  %0 = load i16, i16* %arrayidx, align 2
223  %add = add nuw nsw i32 %i.025, 1
224  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
225  %1 = load i16, i16* %arrayidx1, align 2
226  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
227  %2 = load i16, i16* %arrayidx3, align 2
228  %conv = sext i16 %2 to i32
229  %conv4 = sext i16 %0 to i32
230  %mul = mul nsw i32 %conv, %conv4
231  store i16 42, i16* %arrayidx, align 2
232  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
233  %3 = load i16, i16* %arrayidx6, align 2
234  %conv7 = sext i16 %3 to i32
235  %conv8 = sext i16 %1 to i32
236  %mul9 = mul nsw i32 %conv7, %conv8
237  %add10 = add i32 %mul, %mac1.026
238  %add11 = add i32 %mul9, %add10
239  %exitcond = icmp ne i32 %add, %arg
240  br i1 %exitcond, label %for.body, label %for.cond.cleanup
241}
242
243; CHECK-LABEL: store_alias_arg3_legal_2
244; CHECK-NOT: store
245; CHECK: [[BITCAST:[^ ]+]] = bitcast i16* %arrayidx to i32*
246; CHECK: load i32, i32* [[BITCAST]]
247; CHECK: store i16 42, i16* %arrayidx
248; CHECK: [[BITCAST3:[^ ]+]] = bitcast i16* %arrayidx3 to i32*
249; CHECK: load i32, i32* [[BITCAST3]]
250; CHECK: smlad
251define dso_local i32 @store_alias_arg3_legal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) {
252entry:
253  %cmp24 = icmp sgt i32 %arg, 0
254  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
255
256for.body.preheader:
257  %.pre = load i16, i16* %arg3, align 2
258  %.pre27 = load i16, i16* %arg2, align 2
259  br label %for.body
260
261for.cond.cleanup:
262  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
263  ret i32 %mac1.0.lcssa
264
265for.body:
266  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
267  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
268  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
269  %0 = load i16, i16* %arrayidx, align 2
270  %add = add nuw nsw i32 %i.025, 1
271  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
272  %1 = load i16, i16* %arrayidx1, align 2
273  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
274  store i16 42, i16* %arrayidx, align 2
275  %2 = load i16, i16* %arrayidx3, align 2
276  %conv = sext i16 %2 to i32
277  %conv4 = sext i16 %0 to i32
278  %mul = mul nsw i32 %conv, %conv4
279  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
280  %3 = load i16, i16* %arrayidx6, align 2
281  %conv7 = sext i16 %3 to i32
282  %conv8 = sext i16 %1 to i32
283  %mul9 = mul nsw i32 %conv7, %conv8
284  %add10 = add i32 %mul, %mac1.026
285  %add11 = add i32 %mul9, %add10
286  %exitcond = icmp ne i32 %add, %arg
287  br i1 %exitcond, label %for.body, label %for.cond.cleanup
288}
289
290; CHECK-LABEL: store_alias_arg3_illegal_1
291; CHECK-NOT: load i32
292define dso_local i32 @store_alias_arg3_illegal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) {
293entry:
294  %cmp24 = icmp sgt i32 %arg, 0
295  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
296
297for.body.preheader:
298  %.pre = load i16, i16* %arg3, align 2
299  %.pre27 = load i16, i16* %arg2, align 2
300  br label %for.body
301
302for.cond.cleanup:
303  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
304  ret i32 %mac1.0.lcssa
305
306for.body:
307  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
308  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
309  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
310  %0 = load i16, i16* %arrayidx, align 2
311  %add = add nuw nsw i32 %i.025, 1
312  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
313  store i16 42, i16* %arrayidx1, align 2
314  %1 = load i16, i16* %arrayidx1, align 2
315  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
316  %2 = load i16, i16* %arrayidx3, align 2
317  %conv = sext i16 %2 to i32
318  %conv4 = sext i16 %0 to i32
319  %mul = mul nsw i32 %conv, %conv4
320  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
321  %3 = load i16, i16* %arrayidx6, align 2
322  %conv7 = sext i16 %3 to i32
323  %conv8 = sext i16 %1 to i32
324  %mul9 = mul nsw i32 %conv7, %conv8
325  %add10 = add i32 %mul, %mac1.026
326  %add11 = add i32 %mul9, %add10
327  %exitcond = icmp ne i32 %add, %arg
328  br i1 %exitcond, label %for.body, label %for.cond.cleanup
329}
330
331; CHECK-LABEL: store_alias_arg3_illegal_2
332; CHECK-NOT: load i32
333define dso_local i32 @store_alias_arg3_illegal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) {
334entry:
335  %cmp24 = icmp sgt i32 %arg, 0
336  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
337
338for.body.preheader:
339  %.pre = load i16, i16* %arg3, align 2
340  %.pre27 = load i16, i16* %arg2, align 2
341  br label %for.body
342
343for.cond.cleanup:
344  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
345  ret i32 %mac1.0.lcssa
346
347for.body:
348  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
349  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
350  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
351  %0 = load i16, i16* %arrayidx, align 2
352  %add = add nuw nsw i32 %i.025, 1
353  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
354  store i16 42, i16* %arrayidx, align 2
355  %1 = load i16, i16* %arrayidx1, align 2
356  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
357  %2 = load i16, i16* %arrayidx3, align 2
358  %conv = sext i16 %2 to i32
359  %conv4 = sext i16 %0 to i32
360  %mul = mul nsw i32 %conv, %conv4
361  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
362  %3 = load i16, i16* %arrayidx6, align 2
363  %conv7 = sext i16 %3 to i32
364  %conv8 = sext i16 %1 to i32
365  %mul9 = mul nsw i32 %conv7, %conv8
366  %add10 = add i32 %mul, %mac1.026
367  %add11 = add i32 %mul9, %add10
368  %exitcond = icmp ne i32 %add, %arg
369  br i1 %exitcond, label %for.body, label %for.cond.cleanup
370}
371
372; CHECK-LABEL: store_alias_arg2_illegal_1
373; CHECK-NOT: load i32
374define dso_local i32 @store_alias_arg2_illegal_1(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
375entry:
376  %cmp24 = icmp sgt i32 %arg, 0
377  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
378
379for.body.preheader:
380  %.pre = load i16, i16* %arg3, align 2
381  %.pre27 = load i16, i16* %arg2, align 2
382  br label %for.body
383
384for.cond.cleanup:
385  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
386  ret i32 %mac1.0.lcssa
387
388for.body:
389  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
390  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
391  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
392  %0 = load i16, i16* %arrayidx, align 2
393  %add = add nuw nsw i32 %i.025, 1
394  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
395  %1 = load i16, i16* %arrayidx1, align 2
396  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
397  %2 = load i16, i16* %arrayidx3, align 2
398  %conv = sext i16 %2 to i32
399  %conv4 = sext i16 %0 to i32
400  %mul = mul nsw i32 %conv, %conv4
401  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
402  store i16 42, i16* %arrayidx6, align 2
403  %3 = load i16, i16* %arrayidx6, align 2
404  %conv7 = sext i16 %3 to i32
405  %conv8 = sext i16 %1 to i32
406  %mul9 = mul nsw i32 %conv7, %conv8
407  %add10 = add i32 %mul, %mac1.026
408  %add11 = add i32 %mul9, %add10
409  %exitcond = icmp ne i32 %add, %arg
410  br i1 %exitcond, label %for.body, label %for.cond.cleanup
411}
412
413; CHECK-LABEL: store_alias_arg2_illegal_2
414; CHECK-NOT: load i32
415define dso_local i32 @store_alias_arg2_illegal_2(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
416entry:
417  %cmp24 = icmp sgt i32 %arg, 0
418  br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
419
420for.body.preheader:
421  %.pre = load i16, i16* %arg3, align 2
422  %.pre27 = load i16, i16* %arg2, align 2
423  br label %for.body
424
425for.cond.cleanup:
426  %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
427  ret i32 %mac1.0.lcssa
428
429for.body:
430  %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ]
431  %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]
432  %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025
433  %0 = load i16, i16* %arrayidx, align 2
434  %add = add nuw nsw i32 %i.025, 1
435  %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add
436  %1 = load i16, i16* %arrayidx1, align 2
437  %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025
438  %2 = load i16, i16* %arrayidx3, align 2
439  %conv = sext i16 %2 to i32
440  %conv4 = sext i16 %0 to i32
441  %mul = mul nsw i32 %conv, %conv4
442  %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add
443  store i16 42, i16* %arrayidx3, align 2
444  %3 = load i16, i16* %arrayidx6, align 2
445  %conv7 = sext i16 %3 to i32
446  %conv8 = sext i16 %1 to i32
447  %mul9 = mul nsw i32 %conv7, %conv8
448  %add10 = add i32 %mul, %mac1.026
449  %add11 = add i32 %mul9, %add10
450  %exitcond = icmp ne i32 %add, %arg
451  br i1 %exitcond, label %for.body, label %for.cond.cleanup
452}
453
454; TODO: I think we should be able to generate one smlad here. The search fails
455; when it finds the alias.
456; CHECK-LABEL: one_pair_alias
457; CHECK-NOT: call i32 @llvm.arm.smlad
458define i32 @one_pair_alias(i16* noalias nocapture readonly %b, i16* noalias nocapture readonly %c) {
459entry:
460  br label %for.body
461
462for.cond.cleanup:                                 ; preds = %for.body
463  ret i32 %add26
464
465for.body:                                         ; preds = %for.body, %entry
466  %i.050 = phi i32 [ 0, %entry ], [ %add27, %for.body ]
467  %a.049 = phi i32 [ 0, %entry ], [ %add26, %for.body ]
468  %add3 = or i32 %i.050, 1
469  %add11 = or i32 %i.050, 2
470  %add19 = or i32 %i.050, 3
471  %arrayidx = getelementptr inbounds i16, i16* %b, i32 %i.050
472  %arrayidx4 = getelementptr inbounds i16, i16* %b, i32 %add3
473  %arrayidx12 = getelementptr inbounds i16, i16* %b, i32 %add11
474  %arrayidx20 = getelementptr inbounds i16, i16* %b, i32 %add19
475  %arrayidx1 = getelementptr inbounds i16, i16* %c, i32 %i.050
476  %arrayidx7 = getelementptr inbounds i16, i16* %c, i32 %add3
477  %arrayidx15 = getelementptr inbounds i16, i16* %c, i32 %add11
478  %arrayidx23 = getelementptr inbounds i16, i16* %c, i32 %add19
479  %tmp = load i16, i16* %arrayidx, align 2
480  %tmp2 = load i16, i16* %arrayidx4, align 2
481  %tmp4 = load i16, i16* %arrayidx12, align 2
482  %tmp6 = load i16, i16* %arrayidx20, align 2
483  %tmp1 = load i16, i16* %arrayidx1, align 2
484  store i16 43, i16 *%arrayidx7
485  %tmp3 = load i16, i16* %arrayidx7, align 2
486  %tmp5 = load i16, i16* %arrayidx15, align 2
487  %tmp7 = load i16, i16* %arrayidx23, align 2
488  %conv = sext i16 %tmp to i32
489  %conv2 = sext i16 %tmp1 to i32
490  %mul = mul nsw i32 %conv2, %conv
491  %add = add nsw i32 %mul, %a.049
492  %conv5 = sext i16 %tmp2 to i32
493  %conv8 = sext i16 %tmp3 to i32
494  %mul9 = mul nsw i32 %conv8, %conv5
495  %add10 = add nsw i32 %add, %mul9
496  %conv13 = sext i16 %tmp4 to i32
497  %conv16 = sext i16 %tmp5 to i32
498  %mul17 = mul nsw i32 %conv16, %conv13
499  %add18 = add nsw i32 %add10, %mul17
500  %conv21 = sext i16 %tmp6 to i32
501  %conv24 = sext i16 %tmp7 to i32
502  %mul25 = mul nsw i32 %conv24, %conv21
503  %add26 = add nsw i32 %add18, %mul25
504  %add27 = add nuw nsw i32 %i.050, 4
505  %cmp = icmp ult i32 %add27, 100
506  br i1 %cmp, label %for.body, label %for.cond.cleanup
507}
508
509