xref: /llvm-project/llvm/test/Transforms/LoopUnroll/WebAssembly/basic-unrolling.ll (revision 462cb3cd6cecd0511ecaf0e3ebcaba455ece587d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -mtriple=wasm32-unknown-unknown -passes=loop-unroll,simplifycfg,instcombine -S %s -o - | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
5
6define hidden void @compile_time_full(ptr nocapture %a, ptr nocapture readonly %b) {
7; CHECK-LABEL: @compile_time_full(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[B:%.*]], align 1
10; CHECK-NEXT:    store i8 [[I]], ptr [[A:%.*]], align 1
11; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 1
12; CHECK-NEXT:    [[I_1:%.*]] = load i8, ptr [[ARRAYIDX_1]], align 1
13; CHECK-NEXT:    [[ARRAYIDX1_1:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 1
14; CHECK-NEXT:    store i8 [[I_1]], ptr [[ARRAYIDX1_1]], align 1
15; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 2
16; CHECK-NEXT:    [[I_2:%.*]] = load i8, ptr [[ARRAYIDX_2]], align 1
17; CHECK-NEXT:    [[ARRAYIDX1_2:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 2
18; CHECK-NEXT:    store i8 [[I_2]], ptr [[ARRAYIDX1_2]], align 1
19; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 3
20; CHECK-NEXT:    [[I_3:%.*]] = load i8, ptr [[ARRAYIDX_3]], align 1
21; CHECK-NEXT:    [[ARRAYIDX1_3:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 3
22; CHECK-NEXT:    store i8 [[I_3]], ptr [[ARRAYIDX1_3]], align 1
23; CHECK-NEXT:    [[ARRAYIDX_4:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 4
24; CHECK-NEXT:    [[I_4:%.*]] = load i8, ptr [[ARRAYIDX_4]], align 1
25; CHECK-NEXT:    [[ARRAYIDX1_4:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 4
26; CHECK-NEXT:    store i8 [[I_4]], ptr [[ARRAYIDX1_4]], align 1
27; CHECK-NEXT:    [[ARRAYIDX_5:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 5
28; CHECK-NEXT:    [[I_5:%.*]] = load i8, ptr [[ARRAYIDX_5]], align 1
29; CHECK-NEXT:    [[ARRAYIDX1_5:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 5
30; CHECK-NEXT:    store i8 [[I_5]], ptr [[ARRAYIDX1_5]], align 1
31; CHECK-NEXT:    [[ARRAYIDX_6:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 6
32; CHECK-NEXT:    [[I_6:%.*]] = load i8, ptr [[ARRAYIDX_6]], align 1
33; CHECK-NEXT:    [[ARRAYIDX1_6:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 6
34; CHECK-NEXT:    store i8 [[I_6]], ptr [[ARRAYIDX1_6]], align 1
35; CHECK-NEXT:    [[ARRAYIDX_7:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 7
36; CHECK-NEXT:    [[I_7:%.*]] = load i8, ptr [[ARRAYIDX_7]], align 1
37; CHECK-NEXT:    [[ARRAYIDX1_7:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 7
38; CHECK-NEXT:    store i8 [[I_7]], ptr [[ARRAYIDX1_7]], align 1
39; CHECK-NEXT:    [[ARRAYIDX_8:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 8
40; CHECK-NEXT:    [[I_8:%.*]] = load i8, ptr [[ARRAYIDX_8]], align 1
41; CHECK-NEXT:    [[ARRAYIDX1_8:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 8
42; CHECK-NEXT:    store i8 [[I_8]], ptr [[ARRAYIDX1_8]], align 1
43; CHECK-NEXT:    [[ARRAYIDX_9:%.*]] = getelementptr inbounds nuw i8, ptr [[B]], i32 9
44; CHECK-NEXT:    [[I_9:%.*]] = load i8, ptr [[ARRAYIDX_9]], align 1
45; CHECK-NEXT:    [[ARRAYIDX1_9:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 9
46; CHECK-NEXT:    store i8 [[I_9]], ptr [[ARRAYIDX1_9]], align 1
47; CHECK-NEXT:    ret void
48;
49entry:
50  br label %for.body
51
52for.cond.cleanup:                                 ; preds = %for.body
53  ret void
54
55for.body:                                         ; preds = %for.body, %entry
56  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
57  %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06
58  %i = load i8, ptr %arrayidx, align 1
59  %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06
60  store i8 %i, ptr %arrayidx1, align 1
61  %inc = add nuw nsw i32 %i.06, 1
62  %exitcond.not = icmp eq i32 %inc, 10
63  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
64}
65
66define hidden void @compile_time_partial(ptr nocapture %a, ptr nocapture readonly %b) {
67; CHECK-LABEL: @compile_time_partial(
68; CHECK-NEXT:  entry:
69; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
70; CHECK:       for.cond.cleanup:
71; CHECK-NEXT:    ret void
72; CHECK:       for.body:
73; CHECK-NEXT:    [[I_07:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_3:%.*]], [[FOR_BODY]] ]
74; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i16, ptr [[B:%.*]], i32 [[I_07]]
75; CHECK-NEXT:    [[I:%.*]] = load i16, ptr [[ARRAYIDX]], align 2
76; CHECK-NEXT:    [[ADD:%.*]] = add i16 [[I]], 1
77; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i16, ptr [[A:%.*]], i32 [[I_07]]
78; CHECK-NEXT:    store i16 [[ADD]], ptr [[ARRAYIDX2]], align 2
79; CHECK-NEXT:    [[INC:%.*]] = or disjoint i32 [[I_07]], 1
80; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC]]
81; CHECK-NEXT:    [[I_1:%.*]] = load i16, ptr [[ARRAYIDX_1]], align 2
82; CHECK-NEXT:    [[ADD_1:%.*]] = add i16 [[I_1]], 1
83; CHECK-NEXT:    [[ARRAYIDX2_1:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC]]
84; CHECK-NEXT:    store i16 [[ADD_1]], ptr [[ARRAYIDX2_1]], align 2
85; CHECK-NEXT:    [[INC_1:%.*]] = or disjoint i32 [[I_07]], 2
86; CHECK-NEXT:    [[ARRAYIDX_2:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC_1]]
87; CHECK-NEXT:    [[I_2:%.*]] = load i16, ptr [[ARRAYIDX_2]], align 2
88; CHECK-NEXT:    [[ADD_2:%.*]] = add i16 [[I_2]], 1
89; CHECK-NEXT:    [[ARRAYIDX2_2:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC_1]]
90; CHECK-NEXT:    store i16 [[ADD_2]], ptr [[ARRAYIDX2_2]], align 2
91; CHECK-NEXT:    [[INC_2:%.*]] = or disjoint i32 [[I_07]], 3
92; CHECK-NEXT:    [[ARRAYIDX_3:%.*]] = getelementptr inbounds nuw i16, ptr [[B]], i32 [[INC_2]]
93; CHECK-NEXT:    [[I_3:%.*]] = load i16, ptr [[ARRAYIDX_3]], align 2
94; CHECK-NEXT:    [[ADD_3:%.*]] = add i16 [[I_3]], 1
95; CHECK-NEXT:    [[ARRAYIDX2_3:%.*]] = getelementptr inbounds nuw i16, ptr [[A]], i32 [[INC_2]]
96; CHECK-NEXT:    store i16 [[ADD_3]], ptr [[ARRAYIDX2_3]], align 2
97; CHECK-NEXT:    [[INC_3]] = add nuw nsw i32 [[I_07]], 4
98; CHECK-NEXT:    [[EXITCOND_NOT_3:%.*]] = icmp eq i32 [[INC_3]], 1000
99; CHECK-NEXT:    br i1 [[EXITCOND_NOT_3]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
100;
101entry:
102  br label %for.body
103
104for.cond.cleanup:                                 ; preds = %for.body
105  ret void
106
107for.body:                                         ; preds = %for.body, %entry
108  %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
109  %arrayidx = getelementptr inbounds i16, ptr %b, i32 %i.07
110  %i = load i16, ptr %arrayidx, align 2
111  %add = add i16 %i, 1
112  %arrayidx2 = getelementptr inbounds i16, ptr %a, i32 %i.07
113  store i16 %add, ptr %arrayidx2, align 2
114  %inc = add nuw nsw i32 %i.07, 1
115  %exitcond.not = icmp eq i32 %inc, 1000
116  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
117}
118
119define hidden void @runtime(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
120; CHECK-LABEL: @runtime(
121; CHECK-NEXT:  entry:
122; CHECK-NEXT:    [[CMP8_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
123; CHECK-NEXT:    br i1 [[CMP8_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
124; CHECK:       for.body.preheader:
125; CHECK-NEXT:    [[XTRAITER:%.*]] = and i32 [[N]], 1
126; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[N]], 1
127; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA:%.*]], label [[FOR_BODY_PREHEADER_NEW:%.*]]
128; CHECK:       for.body.preheader.new:
129; CHECK-NEXT:    [[UNROLL_ITER:%.*]] = and i32 [[N]], -2
130; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
131; CHECK:       for.cond.cleanup.loopexit.unr-lcssa:
132; CHECK-NEXT:    [[I_09_UNR:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER]] ], [ [[INC_1:%.*]], [[FOR_BODY]] ]
133; CHECK-NEXT:    [[LCMP_MOD_NOT:%.*]] = icmp eq i32 [[XTRAITER]], 0
134; CHECK-NEXT:    br i1 [[LCMP_MOD_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY_EPIL:%.*]]
135; CHECK:       for.body.epil:
136; CHECK-NEXT:    [[ARRAYIDX_EPIL:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[I_09_UNR]]
137; CHECK-NEXT:    [[I_EPIL:%.*]] = load i32, ptr [[ARRAYIDX_EPIL]], align 4
138; CHECK-NEXT:    [[ARRAYIDX1_EPIL:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i32 [[I_09_UNR]]
139; CHECK-NEXT:    [[I1_EPIL:%.*]] = load i32, ptr [[ARRAYIDX1_EPIL]], align 4
140; CHECK-NEXT:    [[MUL_EPIL:%.*]] = mul nsw i32 [[I1_EPIL]], [[I_EPIL]]
141; CHECK-NEXT:    [[ARRAYIDX2_EPIL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_09_UNR]]
142; CHECK-NEXT:    store i32 [[MUL_EPIL]], ptr [[ARRAYIDX2_EPIL]], align 4
143; CHECK-NEXT:    br label [[FOR_COND_CLEANUP]]
144; CHECK:       for.cond.cleanup:
145; CHECK-NEXT:    ret void
146; CHECK:       for.body:
147; CHECK-NEXT:    [[I_09:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[INC_1]], [[FOR_BODY]] ]
148; CHECK-NEXT:    [[NITER:%.*]] = phi i32 [ 0, [[FOR_BODY_PREHEADER_NEW]] ], [ [[NITER_NEXT_1:%.*]], [[FOR_BODY]] ]
149; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[I_09]]
150; CHECK-NEXT:    [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
151; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[I_09]]
152; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
153; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]]
154; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[I_09]]
155; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
156; CHECK-NEXT:    [[INC:%.*]] = or disjoint i32 [[I_09]], 1
157; CHECK-NEXT:    [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INC]]
158; CHECK-NEXT:    [[I_1:%.*]] = load i32, ptr [[ARRAYIDX_1]], align 4
159; CHECK-NEXT:    [[ARRAYIDX1_1:%.*]] = getelementptr inbounds i32, ptr [[C]], i32 [[INC]]
160; CHECK-NEXT:    [[I1_1:%.*]] = load i32, ptr [[ARRAYIDX1_1]], align 4
161; CHECK-NEXT:    [[MUL_1:%.*]] = mul nsw i32 [[I1_1]], [[I_1]]
162; CHECK-NEXT:    [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INC]]
163; CHECK-NEXT:    store i32 [[MUL_1]], ptr [[ARRAYIDX2_1]], align 4
164; CHECK-NEXT:    [[INC_1]] = add nuw i32 [[I_09]], 2
165; CHECK-NEXT:    [[NITER_NEXT_1]] = add i32 [[NITER]], 2
166; CHECK-NEXT:    [[NITER_NCMP_1:%.*]] = icmp eq i32 [[NITER_NEXT_1]], [[UNROLL_ITER]]
167; CHECK-NEXT:    br i1 [[NITER_NCMP_1]], label [[FOR_COND_CLEANUP_LOOPEXIT_UNR_LCSSA]], label [[FOR_BODY]]
168;
169entry:
170  %cmp8.not = icmp eq i32 %N, 0
171  br i1 %cmp8.not, label %for.cond.cleanup, label %for.body
172
173for.cond.cleanup:                                 ; preds = %for.body, %entry
174  ret void
175
176for.body:                                         ; preds = %for.body, %entry
177  %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
178  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.09
179  %i = load i32, ptr %arrayidx, align 4
180  %arrayidx1 = getelementptr inbounds i32, ptr %c, i32 %i.09
181  %i1 = load i32, ptr %arrayidx1, align 4
182  %mul = mul nsw i32 %i1, %i
183  %arrayidx2 = getelementptr inbounds i32, ptr %a, i32 %i.09
184  store i32 %mul, ptr %arrayidx2, align 4
185  %inc = add nuw i32 %i.09, 1
186  %exitcond.not = icmp eq i32 %inc, %N
187  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
188}
189
190define hidden void @dont_unroll_call(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
191; CHECK-LABEL: @dont_unroll_call(
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    [[CMP12_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
194; CHECK-NEXT:    br i1 [[CMP12_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
195; CHECK:       for.cond.cleanup:
196; CHECK-NEXT:    ret void
197; CHECK:       for.body:
198; CHECK-NEXT:    [[I_013:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
199; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[I_013]]
200; CHECK-NEXT:    [[I:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
201; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[C:%.*]], i32 [[I_013]]
202; CHECK-NEXT:    [[I1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
203; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[I1]], [[I]]
204; CHECK-NEXT:    [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[I_013]]
205; CHECK-NEXT:    store i32 [[MUL]], ptr [[ARRAYIDX2]], align 4
206; CHECK-NEXT:    [[TMP0:%.*]] = call i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, i32 [[I_013]], i32 [[MUL]])
207; CHECK-NEXT:    [[INC]] = add nuw i32 [[I_013]], 1
208; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[N]]
209; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]]
210;
211entry:
212  %cmp12.not = icmp eq i32 %N, 0
213  br i1 %cmp12.not, label %for.cond.cleanup, label %for.body
214
215for.cond.cleanup:                                 ; preds = %for.body, %entry
216  ret void
217
218for.body:                                         ; preds = %for.body, %entry
219  %i.013 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
220  %arrayidx = getelementptr inbounds i32, ptr %b, i32 %i.013
221  %i = load i32, ptr %arrayidx, align 4
222  %arrayidx1 = getelementptr inbounds i32, ptr %c, i32 %i.013
223  %i1 = load i32, ptr %arrayidx1, align 4
224  %mul = mul nsw i32 %i1, %i
225  %arrayidx2 = getelementptr inbounds i32, ptr %a, i32 %i.013
226  store i32 %mul, ptr %arrayidx2, align 4
227  call i32 (ptr, ...) @printf(ptr nonnull dereferenceable(1) @.str, i32 %i.013, i32 %mul)
228  %inc = add nuw i32 %i.013, 1
229  %exitcond.not = icmp eq i32 %inc, %N
230  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
231}
232
233define hidden void @dont_unroll_optsize(ptr nocapture %a, ptr nocapture readonly %b) #0 {
234; CHECK-LABEL: @dont_unroll_optsize(
235; CHECK-NEXT:  entry:
236; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
237; CHECK:       for.cond.cleanup:
238; CHECK-NEXT:    ret void
239; CHECK:       for.body:
240; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
241; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[B:%.*]], i32 [[I_06]]
242; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
243; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[I_06]]
244; CHECK-NEXT:    store i8 [[I]], ptr [[ARRAYIDX1]], align 1
245; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
246; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 10
247; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
248;
249entry:
250  br label %for.body
251
252for.cond.cleanup:                                 ; preds = %for.body
253  ret void
254
255for.body:                                         ; preds = %for.body, %entry
256  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
257  %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06
258  %i = load i8, ptr %arrayidx, align 1
259  %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06
260  store i8 %i, ptr %arrayidx1, align 1
261  %inc = add nuw nsw i32 %i.06, 1
262  %exitcond.not = icmp eq i32 %inc, 10
263  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
264}
265
266define hidden void @dont_unroll_minsize(ptr nocapture %a, ptr nocapture readonly %b) #1 {
267; CHECK-LABEL: @dont_unroll_minsize(
268; CHECK-NEXT:  entry:
269; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
270; CHECK:       for.cond.cleanup:
271; CHECK-NEXT:    ret void
272; CHECK:       for.body:
273; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
274; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[B:%.*]], i32 [[I_06]]
275; CHECK-NEXT:    [[I:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
276; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[I_06]]
277; CHECK-NEXT:    store i8 [[I]], ptr [[ARRAYIDX1]], align 1
278; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_06]], 1
279; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], 10
280; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
281;
282entry:
283  br label %for.body
284
285for.cond.cleanup:                                 ; preds = %for.body
286  ret void
287
288for.body:                                         ; preds = %for.body, %entry
289  %i.06 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
290  %arrayidx = getelementptr inbounds i8, ptr %b, i32 %i.06
291  %i = load i8, ptr %arrayidx, align 1
292  %arrayidx1 = getelementptr inbounds i8, ptr %a, i32 %i.06
293  store i8 %i, ptr %arrayidx1, align 1
294  %inc = add nuw nsw i32 %i.06, 1
295  %exitcond.not = icmp eq i32 %inc, 10
296  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
297}
298
299attributes #0 = { optsize }
300attributes #1 = { minsize }
301
302@.str = private unnamed_addr constant [12 x i8] c"a[%d] = %d\0A\00", align 1
303declare i32 @printf(ptr nocapture readonly, ...)
304