xref: /aosp_15_r20/external/llvm/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; RUN: opt -passes='require<scalar-evolution>,require<aa>,loop(print-access-info)' -disable-output  < %s 2>&1 | FileCheck %s
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
5*9880d681SAndroid Build Coastguard Workertarget triple = "aarch64--linux-gnueabi"
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker; 3 reads and 3 writes should need 12 memchecks
8*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testf':
9*9880d681SAndroid Build Coastguard Worker; CHECK: Memory dependences are safe with run-time checks
10*9880d681SAndroid Build Coastguard Worker
11*9880d681SAndroid Build Coastguard Worker; Memory dependencies have labels starting from 0, so in
12*9880d681SAndroid Build Coastguard Worker; order to verify that we have n checks, we look for
13*9880d681SAndroid Build Coastguard Worker; (n-1): and not n:.
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks:
16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: Check 0:
17*9880d681SAndroid Build Coastguard Worker; CHECK: Check 11:
18*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: Check 12:
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Workerdefine void @testf(i16* %a,
21*9880d681SAndroid Build Coastguard Worker               i16* %b,
22*9880d681SAndroid Build Coastguard Worker               i16* %c,
23*9880d681SAndroid Build Coastguard Worker               i16* %d,
24*9880d681SAndroid Build Coastguard Worker               i16* %e,
25*9880d681SAndroid Build Coastguard Worker               i16* %f) {
26*9880d681SAndroid Build Coastguard Workerentry:
27*9880d681SAndroid Build Coastguard Worker  br label %for.body
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
30*9880d681SAndroid Build Coastguard Worker  %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker  %add = add nuw nsw i64 %ind, 1
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker  %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind
35*9880d681SAndroid Build Coastguard Worker  %loadA = load i16, i16* %arrayidxA, align 2
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
38*9880d681SAndroid Build Coastguard Worker  %loadB = load i16, i16* %arrayidxB, align 2
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker  %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %ind
41*9880d681SAndroid Build Coastguard Worker  %loadC = load i16, i16* %arrayidxC, align 2
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker  %mul = mul i16 %loadB, %loadA
44*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i16 %mul, %loadC
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker  %arrayidxD = getelementptr inbounds i16, i16* %d, i64 %ind
47*9880d681SAndroid Build Coastguard Worker  store i16 %mul1, i16* %arrayidxD, align 2
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker  %arrayidxE = getelementptr inbounds i16, i16* %e, i64 %ind
50*9880d681SAndroid Build Coastguard Worker  store i16 %mul, i16* %arrayidxE, align 2
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker  %arrayidxF = getelementptr inbounds i16, i16* %f, i64 %ind
53*9880d681SAndroid Build Coastguard Worker  store i16 %mul1, i16* %arrayidxF, align 2
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i64 %add, 20
56*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
59*9880d681SAndroid Build Coastguard Worker  ret void
60*9880d681SAndroid Build Coastguard Worker}
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker; The following (testg and testh) check that we can group
63*9880d681SAndroid Build Coastguard Worker; memory checks of accesses which differ by a constant value.
64*9880d681SAndroid Build Coastguard Worker; Both tests are based on the following C code:
65*9880d681SAndroid Build Coastguard Worker;
66*9880d681SAndroid Build Coastguard Worker; void testh(short *a, short *b, short *c) {
67*9880d681SAndroid Build Coastguard Worker;   unsigned long ind = 0;
68*9880d681SAndroid Build Coastguard Worker;   for (unsigned long ind = 0; ind < 20; ++ind) {
69*9880d681SAndroid Build Coastguard Worker;     c[2 * ind] = a[ind] * a[ind + 1];
70*9880d681SAndroid Build Coastguard Worker;     c[2 * ind + 1] = a[ind] * a[ind + 1] * b[ind];
71*9880d681SAndroid Build Coastguard Worker;   }
72*9880d681SAndroid Build Coastguard Worker; }
73*9880d681SAndroid Build Coastguard Worker;
74*9880d681SAndroid Build Coastguard Worker; It is sufficient to check the intervals
75*9880d681SAndroid Build Coastguard Worker; [a, a + 21], [b, b + 20] against [c, c + 41].
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker; 3 reads and 2 writes - two of the reads can be merged,
78*9880d681SAndroid Build Coastguard Worker; and the writes can be merged as well. This gives us a
79*9880d681SAndroid Build Coastguard Worker; total of 2 memory checks.
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testg':
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks:
84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 0:
85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ([[ZERO:.+]]):
86*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
87*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[ONE:.+]]):
89*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxA1 = getelementptr inbounds i16, i16* %a, i64 %add
90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind
91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 1:
92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ({{.*}}[[ZERO]]):
93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[TWO:.+]]):
96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Grouped accesses:
98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:    Group {{.*}}[[ZERO]]:
99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %c High: (78 + %c))
100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {(2 + %c)<nsw>,+,4}
101*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%c,+,4}
102*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[ONE]]:
103*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %a High: (40 + %a))
104*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {(2 + %a)<nsw>,+,2}
105*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%a,+,2}
106*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[TWO]]:
107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %b High: (38 + %b))
108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%b,+,2}
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Workerdefine void @testg(i16* %a,
111*9880d681SAndroid Build Coastguard Worker               i16* %b,
112*9880d681SAndroid Build Coastguard Worker               i16* %c) {
113*9880d681SAndroid Build Coastguard Workerentry:
114*9880d681SAndroid Build Coastguard Worker  br label %for.body
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
117*9880d681SAndroid Build Coastguard Worker  %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
118*9880d681SAndroid Build Coastguard Worker  %store_ind = phi i64 [ 0, %entry ], [ %store_ind_next, %for.body ]
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker  %add = add nuw nsw i64 %ind, 1
121*9880d681SAndroid Build Coastguard Worker  %store_ind_inc = add nuw nsw i64 %store_ind, 1
122*9880d681SAndroid Build Coastguard Worker  %store_ind_next = add nuw nsw i64 %store_ind_inc, 1
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker  %arrayidxA = getelementptr inbounds i16, i16* %a, i64 %ind
125*9880d681SAndroid Build Coastguard Worker  %loadA = load i16, i16* %arrayidxA, align 2
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker  %arrayidxA1 = getelementptr inbounds i16, i16* %a, i64 %add
128*9880d681SAndroid Build Coastguard Worker  %loadA1 = load i16, i16* %arrayidxA1, align 2
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker  %arrayidxB = getelementptr inbounds i16, i16* %b, i64 %ind
131*9880d681SAndroid Build Coastguard Worker  %loadB = load i16, i16* %arrayidxB, align 2
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker  %mul = mul i16 %loadA, %loadA1
134*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i16 %mul, %loadB
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker  %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
137*9880d681SAndroid Build Coastguard Worker  store i16 %mul1, i16* %arrayidxC, align 2
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker  %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
140*9880d681SAndroid Build Coastguard Worker  store i16 %mul, i16* %arrayidxC1, align 2
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i64 %add, 20
143*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
144*9880d681SAndroid Build Coastguard Worker
145*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
146*9880d681SAndroid Build Coastguard Worker  ret void
147*9880d681SAndroid Build Coastguard Worker}
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker; 3 reads and 2 writes - the writes can be merged into a single
150*9880d681SAndroid Build Coastguard Worker; group, but the GEPs used for the reads are not marked as inbounds.
151*9880d681SAndroid Build Coastguard Worker; We can still merge them because we are using a unit stride for
152*9880d681SAndroid Build Coastguard Worker; accesses, so we cannot overflow the GEPs.
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testh':
155*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks:
156*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 0:
157*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ([[ZERO:.+]]):
158*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[ONE:.+]]):
161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxA1 = getelementptr i16, i16* %a, i64 %add
162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxA = getelementptr i16, i16* %a, i64 %ind
163*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 1:
164*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ({{.*}}[[ZERO]]):
165*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
166*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
167*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[TWO:.+]]):
168*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         %arrayidxB = getelementptr i16, i16* %b, i64 %ind
169*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Grouped accesses:
170*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[ZERO]]:
171*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %c High: (78 + %c))
172*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {(2 + %c)<nsw>,+,4}
173*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%c,+,4}
174*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[ONE]]:
175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %a High: (40 + %a))
176*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {(2 + %a),+,2}
177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%a,+,2}
178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[TWO]]:
179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %b High: (38 + %b))
180*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%b,+,2}
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerdefine void @testh(i16* %a,
183*9880d681SAndroid Build Coastguard Worker               i16* %b,
184*9880d681SAndroid Build Coastguard Worker               i16* %c) {
185*9880d681SAndroid Build Coastguard Workerentry:
186*9880d681SAndroid Build Coastguard Worker  br label %for.body
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
189*9880d681SAndroid Build Coastguard Worker  %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
190*9880d681SAndroid Build Coastguard Worker  %store_ind = phi i64 [ 0, %entry ], [ %store_ind_next, %for.body ]
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker  %add = add nuw nsw i64 %ind, 1
193*9880d681SAndroid Build Coastguard Worker  %store_ind_inc = add nuw nsw i64 %store_ind, 1
194*9880d681SAndroid Build Coastguard Worker  %store_ind_next = add nuw nsw i64 %store_ind_inc, 1
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker  %arrayidxA = getelementptr i16, i16* %a, i64 %ind
197*9880d681SAndroid Build Coastguard Worker  %loadA = load i16, i16* %arrayidxA, align 2
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker  %arrayidxA1 = getelementptr i16, i16* %a, i64 %add
200*9880d681SAndroid Build Coastguard Worker  %loadA1 = load i16, i16* %arrayidxA1, align 2
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker  %arrayidxB = getelementptr i16, i16* %b, i64 %ind
203*9880d681SAndroid Build Coastguard Worker  %loadB = load i16, i16* %arrayidxB, align 2
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker  %mul = mul i16 %loadA, %loadA1
206*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i16 %mul, %loadB
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker  %arrayidxC = getelementptr inbounds i16, i16* %c, i64 %store_ind
209*9880d681SAndroid Build Coastguard Worker  store i16 %mul1, i16* %arrayidxC, align 2
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker  %arrayidxC1 = getelementptr inbounds i16, i16* %c, i64 %store_ind_inc
212*9880d681SAndroid Build Coastguard Worker  store i16 %mul, i16* %arrayidxC1, align 2
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i64 %add, 20
215*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
218*9880d681SAndroid Build Coastguard Worker  ret void
219*9880d681SAndroid Build Coastguard Worker}
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker; Don't merge pointers if we need to perform a check against a pointer
222*9880d681SAndroid Build Coastguard Worker; to the same underlying object (doing so would emit a check that could be
223*9880d681SAndroid Build Coastguard Worker; falsely invalidated) For example, in the following loop:
224*9880d681SAndroid Build Coastguard Worker;
225*9880d681SAndroid Build Coastguard Worker; for (i = 0; i < 5000; ++i)
226*9880d681SAndroid Build Coastguard Worker;   a[i + offset] = a[i] + a[i + 10000]
227*9880d681SAndroid Build Coastguard Worker;
228*9880d681SAndroid Build Coastguard Worker; we should not merge the intervals associated with the reads (0,5000) and
229*9880d681SAndroid Build Coastguard Worker; (10000, 15000) into (0, 15000) as this will pottentially fail the check
230*9880d681SAndroid Build Coastguard Worker; against the interval associated with the write.
231*9880d681SAndroid Build Coastguard Worker;
232*9880d681SAndroid Build Coastguard Worker; We cannot have this check unless ShouldRetryWithRuntimeCheck is set,
233*9880d681SAndroid Build Coastguard Worker; and therefore the grouping algorithm would create a separate group for
234*9880d681SAndroid Build Coastguard Worker; each pointer.
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker; CHECK: function 'testi':
237*9880d681SAndroid Build Coastguard Worker; CHECK: Run-time memory checks:
238*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 0:
239*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ([[ZERO:.+]]):
240*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind
241*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[ONE:.+]]):
242*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxA1 = getelementptr i16, i16* %a, i64 %ind
243*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Check 1:
244*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Comparing group ({{.*}}[[ZERO]]):
245*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind
246*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Against group ([[TWO:.+]]):
247*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
248*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:   Grouped accesses:
249*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[ZERO]]:
250*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: ((2 * %offset) + %a)<nsw> High: (9998 + (2 * %offset) + %a))
251*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body>
252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[ONE]]:
253*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: %a High: (9998 + %a))
254*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {%a,+,2}<%for.body>
255*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:     Group {{.*}}[[TWO]]:
256*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:       (Low: (20000 + %a) High: (29998 + %a))
257*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT:         Member: {(20000 + %a),+,2}<%for.body>
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Workerdefine void @testi(i16* %a,
260*9880d681SAndroid Build Coastguard Worker                   i64 %offset) {
261*9880d681SAndroid Build Coastguard Workerentry:
262*9880d681SAndroid Build Coastguard Worker  br label %for.body
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
265*9880d681SAndroid Build Coastguard Worker  %ind = phi i64 [ 0, %entry ], [ %add, %for.body ]
266*9880d681SAndroid Build Coastguard Worker  %store_ind = phi i64 [ %offset, %entry ], [ %store_ind_inc, %for.body ]
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker  %add = add nuw nsw i64 %ind, 1
269*9880d681SAndroid Build Coastguard Worker  %store_ind_inc = add nuw nsw i64 %store_ind, 1
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker  %arrayidxA1 = getelementptr i16, i16* %a, i64 %ind
272*9880d681SAndroid Build Coastguard Worker  %ind2 = add nuw nsw i64 %ind, 10000
273*9880d681SAndroid Build Coastguard Worker  %arrayidxA2 = getelementptr i16, i16* %a, i64 %ind2
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Worker  %loadA1 = load i16, i16* %arrayidxA1, align 2
276*9880d681SAndroid Build Coastguard Worker  %loadA2 = load i16, i16* %arrayidxA2, align 2
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker  %addres = add i16 %loadA1, %loadA2
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker  %storeidx = getelementptr inbounds i16, i16* %a, i64 %store_ind
281*9880d681SAndroid Build Coastguard Worker  store i16 %addres, i16* %storeidx, align 2
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i64 %add, 5000
284*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
287*9880d681SAndroid Build Coastguard Worker  ret void
288*9880d681SAndroid Build Coastguard Worker}
289