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