[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / ARM / ParallelDSP / aliasing.ll
blob4edf5bfbbef0fe1eb818c4939abd9741b43c1073
1 ; RUN: opt -mtriple=arm-arm-eabi -mcpu=cortex-m33 < %s -arm-parallel-dsp -verify -S | FileCheck %s
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.
7 ; CHECK-NOT:  call i32 @llvm.arm.smlad
9 define dso_local i32 @no_restrict(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
10 entry:
11   %cmp24 = icmp sgt i32 %arg, 0
12   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
14 for.body.preheader:
15   %.pre = load i16, i16* %arg3, align 2
16   %.pre27 = load i16, i16* %arg2, align 2
17   br label %for.body
19 for.cond.cleanup:
20   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
21   ret i32 %mac1.0.lcssa
23 for.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
29 ; Store inserted here, aliasing with arrayidx, arrayidx1, arrayidx3
30   store i16 42, i16* %arrayidx, align 2
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
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'.
55 ; CHECK-NOT:  call i32 @llvm.arm.smlad
57 define dso_local i32 @restrict(i32 %arg, i32* noalias %arg1, i16* noalias readonly %arg2, i16* noalias readonly %arg3) {
58 entry:
59   %cmp24 = icmp sgt i32 %arg, 0
60   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
62 for.body.preheader:
63   %.pre = load i16, i16* %arg3, align 2
64   %.pre27 = load i16, i16* %arg2, align 2
65   br label %for.body
67 for.cond.cleanup:
68   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
69   ret i32 %mac1.0.lcssa
71 for.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
77 ; Store inserted here, aliasing only with loads from 'arrayidx'.
78   store i16 42, i16* %arrayidx, align 2
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
95 ; Here the Mul is the LHS, and the Add the RHS.
96   %add11 = add i32 %mul9, %add10
98   %exitcond = icmp ne i32 %add, %arg
99   br i1 %exitcond, label %for.body, label %for.cond.cleanup
102 ; CHECK-LABEL: store_dominates_all
103 ; CHECK: store
104 ; CHECK: load
105 ; CHECK: load
106 ; CHECK: load
107 ; CHECK: load
108 ; CHECK: smlad
109 define dso_local i32 @store_dominates_all(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
110 entry:
111   %cmp24 = icmp sgt i32 %arg, 0
112   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
114 for.body.preheader:
115   %.pre = load i16, i16* %arg3, align 2
116   %.pre27 = load i16, i16* %arg2, align 2
117   br label %for.body
119 for.cond.cleanup:
120   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
121   ret i32 %mac1.0.lcssa
123 for.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
148 ; CHECK-LABEL: loads_dominate
149 ; CHECK-NOT: store 
150 ; CHECK: load i32
151 ; CHECK-NOT: store
152 ; CHECK: load i32
153 ; CHECK: store
154 define dso_local i32 @loads_dominate(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
155 entry:
156   %cmp24 = icmp sgt i32 %arg, 0
157   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
159 for.body.preheader:
160   %.pre = load i16, i16* %arg3, align 2
161   %.pre27 = load i16, i16* %arg2, align 2
162   br label %for.body
164 for.cond.cleanup:
165   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
166   ret i32 %mac1.0.lcssa
168 for.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
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
204 define dso_local i32 @store_alias_arg3_legal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) {
205 entry:
206   %cmp24 = icmp sgt i32 %arg, 0
207   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
209 for.body.preheader:
210   %.pre = load i16, i16* %arg3, align 2
211   %.pre27 = load i16, i16* %arg2, align 2
212   br label %for.body
214 for.cond.cleanup:
215   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
216   ret i32 %mac1.0.lcssa
218 for.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
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
251 define dso_local i32 @store_alias_arg3_legal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) {
252 entry:
253   %cmp24 = icmp sgt i32 %arg, 0
254   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
256 for.body.preheader:
257   %.pre = load i16, i16* %arg3, align 2
258   %.pre27 = load i16, i16* %arg2, align 2
259   br label %for.body
261 for.cond.cleanup:
262   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
263   ret i32 %mac1.0.lcssa
265 for.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
290 ; CHECK-LABEL: store_alias_arg3_illegal_1
291 ; CHECK-NOT: load i32
292 define dso_local i32 @store_alias_arg3_illegal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) {
293 entry:
294   %cmp24 = icmp sgt i32 %arg, 0
295   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
297 for.body.preheader:
298   %.pre = load i16, i16* %arg3, align 2
299   %.pre27 = load i16, i16* %arg2, align 2
300   br label %for.body
302 for.cond.cleanup:
303   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
304   ret i32 %mac1.0.lcssa
306 for.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
331 ; CHECK-LABEL: store_alias_arg3_illegal_2
332 ; CHECK-NOT: load i32
333 define dso_local i32 @store_alias_arg3_illegal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) {
334 entry:
335   %cmp24 = icmp sgt i32 %arg, 0
336   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
338 for.body.preheader:
339   %.pre = load i16, i16* %arg3, align 2
340   %.pre27 = load i16, i16* %arg2, align 2
341   br label %for.body
343 for.cond.cleanup:
344   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
345   ret i32 %mac1.0.lcssa
347 for.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
372 ; CHECK-LABEL: store_alias_arg2_illegal_1
373 ; CHECK-NOT: load i32
374 define dso_local i32 @store_alias_arg2_illegal_1(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
375 entry:
376   %cmp24 = icmp sgt i32 %arg, 0
377   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
379 for.body.preheader:
380   %.pre = load i16, i16* %arg3, align 2
381   %.pre27 = load i16, i16* %arg2, align 2
382   br label %for.body
384 for.cond.cleanup:
385   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
386   ret i32 %mac1.0.lcssa
388 for.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
413 ; CHECK-LABEL: store_alias_arg2_illegal_2
414 ; CHECK-NOT: load i32
415 define dso_local i32 @store_alias_arg2_illegal_2(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) {
416 entry:
417   %cmp24 = icmp sgt i32 %arg, 0
418   br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup
420 for.body.preheader:
421   %.pre = load i16, i16* %arg3, align 2
422   %.pre27 = load i16, i16* %arg2, align 2
423   br label %for.body
425 for.cond.cleanup:
426   %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ]
427   ret i32 %mac1.0.lcssa
429 for.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
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
458 define i32 @one_pair_alias(i16* noalias nocapture readonly %b, i16* noalias nocapture readonly %c) {
459 entry:
460   br label %for.body
462 for.cond.cleanup:                                 ; preds = %for.body
463   ret i32 %add26
465 for.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