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
4 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
6 define hidden void @compile_time_full(ptr nocapture %a, ptr nocapture readonly %b) {
7 ; CHECK-LABEL: @compile_time_full(
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
52 for.cond.cleanup: ; preds = %for.body
55 for.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
66 define hidden void @compile_time_partial(ptr nocapture %a, ptr nocapture readonly %b) {
67 ; CHECK-LABEL: @compile_time_partial(
69 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
70 ; CHECK: for.cond.cleanup:
71 ; CHECK-NEXT: ret void
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]]
104 for.cond.cleanup: ; preds = %for.body
107 for.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
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
119 define hidden void @runtime(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
120 ; CHECK-LABEL: @runtime(
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
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]]
170 %cmp8.not = icmp eq i32 %N, 0
171 br i1 %cmp8.not, label %for.cond.cleanup, label %for.body
173 for.cond.cleanup: ; preds = %for.body, %entry
176 for.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
190 define hidden void @dont_unroll_call(ptr nocapture %a, ptr nocapture readonly %b, ptr nocapture readonly %c, i32 %N) {
191 ; CHECK-LABEL: @dont_unroll_call(
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
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]]
212 %cmp12.not = icmp eq i32 %N, 0
213 br i1 %cmp12.not, label %for.cond.cleanup, label %for.body
215 for.cond.cleanup: ; preds = %for.body, %entry
218 for.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
233 define hidden void @dont_unroll_optsize(ptr nocapture %a, ptr nocapture readonly %b) #0 {
234 ; CHECK-LABEL: @dont_unroll_optsize(
236 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
237 ; CHECK: for.cond.cleanup:
238 ; CHECK-NEXT: ret void
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]]
252 for.cond.cleanup: ; preds = %for.body
255 for.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
266 define hidden void @dont_unroll_minsize(ptr nocapture %a, ptr nocapture readonly %b) #1 {
267 ; CHECK-LABEL: @dont_unroll_minsize(
269 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
270 ; CHECK: for.cond.cleanup:
271 ; CHECK-NEXT: ret void
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]]
285 for.cond.cleanup: ; preds = %for.body
288 for.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
299 attributes #0 = { optsize }
300 attributes #1 = { minsize }
302 @.str = private unnamed_addr constant [12 x i8] c"a[%d] = %d\0A\00", align 1
303 declare i32 @printf(ptr nocapture readonly, ...)