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