580 lines · plain
1; RUN: opt -passes=loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s2; RUN: opt -aa-pipeline=basic-aa -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"5 6; CHECK-LABEL: fore_aft_less7; CHECK: %j = phi8; CHECK: %j.1 = phi9; CHECK: %j.2 = phi10; CHECK: %j.3 = phi11;12; fore_aft_less SHOULD be unroll-and-jammed (count=4) as it's safe.13; Memory accesses:14; - Fore block: A[i] = 1 (write in outer loop before inner)15; - Aft block: A[i-1] = sum (write in outer loop after inner)16; No dependency conflict: The fore block write A[i] and aft block write A[i-1]17; access different array elements, so unrolling the outer loop and jamming the18; inner loop is safe. The backward dependency (i-1) doesn't create conflicts19; between different unrolled iterations.20define void @fore_aft_less(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {21entry:22 %cmp = icmp sgt i32 %N, 023 br i1 %cmp, label %for.outer, label %cleanup24 25for.outer:26 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]27 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i28 store i32 1, ptr %arrayidx, align 429 br label %for.inner30 31for.inner:32 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]33 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]34 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j35 %0 = load i32, ptr %arrayidx5, align 436 %mul = mul nsw i32 %0, %i37 %add = add nsw i32 %mul, %sum38 %add6 = add nuw nsw i32 %j, 139 %exitcond = icmp eq i32 %add6, %N40 br i1 %exitcond, label %for.latch, label %for.inner41 42for.latch:43 %add7 = add nuw nsw i32 %i, 144 %add72 = add nuw nsw i32 %i, -145 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add7246 store i32 %add, ptr %arrayidx8, align 447 %exitcond29 = icmp eq i32 %add7, %N48 br i1 %exitcond29, label %cleanup, label %for.outer49 50cleanup:51 ret void52}53 54 55; CHECK-LABEL: fore_aft_eq56; CHECK: %j = phi57; CHECK: %j.1 = phi58; CHECK: %j.2 = phi59; CHECK: %j.3 = phi60;61; fore_aft_eq SHOULD be unroll-and-jammed (count=4) as it's safe.62; Memory accesses:63; - Fore block: A[i] = 1 (write in outer loop before inner)64; - Aft block: A[i] = sum (write in outer loop after inner)65; Dependency conflict: Both fore and aft blocks write to A[i], creating a66; write-after-write (WAW) dependency. However, this is safe for unroll-and-jam67; because the aft block write always happens after the fore block write in68; the same iteration, preserving the original execution order.69define void @fore_aft_eq(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {70entry:71 %cmp = icmp sgt i32 %N, 072 br i1 %cmp, label %for.outer, label %cleanup73 74for.outer:75 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]76 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i77 store i32 1, ptr %arrayidx, align 478 br label %for.inner79 80for.inner:81 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]82 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]83 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j84 %0 = load i32, ptr %arrayidx5, align 485 %mul = mul nsw i32 %0, %i86 %add = add nsw i32 %mul, %sum87 %add6 = add nuw nsw i32 %j, 188 %exitcond = icmp eq i32 %add6, %N89 br i1 %exitcond, label %for.latch, label %for.inner90 91for.latch:92 %add7 = add nuw nsw i32 %i, 193 %add72 = add nuw nsw i32 %i, 094 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %i95 store i32 %add, ptr %arrayidx8, align 496 %exitcond29 = icmp eq i32 %add7, %N97 br i1 %exitcond29, label %cleanup, label %for.outer98 99cleanup:100 ret void101}102 103 104; CHECK-LABEL: fore_aft_more105; CHECK: %j = phi106; CHECK-NOT: %j.1 = phi107;108; fore_aft_more should NOT be unroll-and-jammed due to a dependency violation.109; Memory accesses:110; - Fore block: A[i] = 1 (write in outer loop before inner)111; - Aft block: A[i+1] = sum (write in outer loop after inner)112; Dependency conflict: The fore block writes A[i] and aft block writes A[i+1].113; When unroll-and-jamming, iteration i's aft block writes A[i+1] which conflicts114; with iteration i+1's fore block write to A[i+1], creating a write-after-write115; race condition that violates the original sequential semantics.116define void @fore_aft_more(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {117entry:118 %cmp = icmp sgt i32 %N, 0119 br i1 %cmp, label %for.outer, label %cleanup120 121for.outer:122 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]123 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i124 store i32 1, ptr %arrayidx, align 4125 br label %for.inner126 127for.inner:128 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]129 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]130 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j131 %0 = load i32, ptr %arrayidx5, align 4132 %mul = mul nsw i32 %0, %i133 %add = add nsw i32 %mul, %sum134 %add6 = add nuw nsw i32 %j, 1135 %exitcond = icmp eq i32 %add6, %N136 br i1 %exitcond, label %for.latch, label %for.inner137 138for.latch:139 %add7 = add nuw nsw i32 %i, 1140 %add72 = add nuw nsw i32 %i, 1141 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72142 store i32 %add, ptr %arrayidx8, align 4143 %exitcond29 = icmp eq i32 %add7, %N144 br i1 %exitcond29, label %cleanup, label %for.outer145 146cleanup:147 ret void148}149 150 151; CHECK-LABEL: fore_sub_less152; CHECK: %j = phi153; CHECK: %j.1 = phi154; CHECK: %j.2 = phi155; CHECK: %j.3 = phi156;157; fore_sub_less SHOULD be unroll-and-jammed (count=4) as it's safe.158; Memory accesses:159; - Fore block: A[i] = 1 (write in outer loop before inner)160; - Sub block: A[i-1] = sum (write inside inner loop)161; No dependency conflict: The fore block writes A[i] and sub block writes A[i-1].162; These access different array elements, so unroll-and-jam is safe. The backward163; dependency pattern doesn't create conflicts between unrolled iterations.164define void @fore_sub_less(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {165entry:166 %cmp = icmp sgt i32 %N, 0167 br i1 %cmp, label %for.outer, label %cleanup168 169for.outer:170 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]171 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i172 store i32 1, ptr %arrayidx, align 4173 br label %for.inner174 175for.inner:176 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]177 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]178 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j179 %0 = load i32, ptr %arrayidx5, align 4180 %mul = mul nsw i32 %0, %i181 %add = add nsw i32 %mul, %sum182 %add72 = add nuw nsw i32 %i, -1183 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72184 store i32 %add, ptr %arrayidx8, align 4185 %add6 = add nuw nsw i32 %j, 1186 %exitcond = icmp eq i32 %add6, %N187 br i1 %exitcond, label %for.latch, label %for.inner188 189for.latch:190 %add7 = add nuw nsw i32 %i, 1191 %exitcond29 = icmp eq i32 %add7, %N192 br i1 %exitcond29, label %cleanup, label %for.outer193 194cleanup:195 ret void196}197 198 199; CHECK-LABEL: fore_sub_eq200; CHECK: %j = phi201; CHECK: %j.1 = phi202; CHECK: %j.2 = phi203; CHECK: %j.3 = phi204;205; fore_sub_eq SHOULD be unroll-and-jammed (count=4) as it's safe.206; Memory accesses:207; - Fore block: A[i] = 1 (write in outer loop before inner)208; - Sub block: A[i] = sum (write inside inner loop)209; Dependency conflict: Both fore and sub blocks write to A[i], creating a210; write-after-write (WAW) dependency. However, this is safe for unroll-and-jam211; because the execution order is preserved: fore block executes first, then212; the entire inner loop (sub block) executes, maintaining the original semantics.213define void @fore_sub_eq(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {214entry:215 %cmp = icmp sgt i32 %N, 0216 br i1 %cmp, label %for.outer, label %cleanup217 218for.outer:219 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]220 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i221 store i32 1, ptr %arrayidx, align 4222 br label %for.inner223 224for.inner:225 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]226 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]227 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j228 %0 = load i32, ptr %arrayidx5, align 4229 %mul = mul nsw i32 %0, %i230 %add = add nsw i32 %mul, %sum231 %add72 = add nuw nsw i32 %i, 0232 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72233 store i32 %add, ptr %arrayidx8, align 4234 %add6 = add nuw nsw i32 %j, 1235 %exitcond = icmp eq i32 %add6, %N236 br i1 %exitcond, label %for.latch, label %for.inner237 238for.latch:239 %add7 = add nuw nsw i32 %i, 1240 %exitcond29 = icmp eq i32 %add7, %N241 br i1 %exitcond29, label %cleanup, label %for.outer242 243cleanup:244 ret void245}246 247 248; CHECK-LABEL: fore_sub_more249; CHECK: %j = phi250; CHECK-NOT: %j.1 = phi251;252; fore_sub_more should NOT be unroll-and-jammed due to a dependency violation.253; Memory accesses:254; - Fore block: A[i] = 1 (write in outer loop before inner)255; - Sub block: A[i+1] = sum (write inside inner loop)256; Dependency conflict: The fore block writes A[i] and sub block writes A[i+1].257; When unroll-and-jamming, iteration i's fore block writes A[i] but iteration i's258; sub block writes A[i+1]. This conflicts with iteration i+1's fore block write259; to A[i+1], creating a write-after-write race condition.260define void @fore_sub_more(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {261entry:262 %cmp = icmp sgt i32 %N, 0263 br i1 %cmp, label %for.outer, label %cleanup264 265for.outer:266 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]267 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i268 store i32 1, ptr %arrayidx, align 4269 br label %for.inner270 271for.inner:272 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]273 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]274 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j275 %0 = load i32, ptr %arrayidx5, align 4276 %mul = mul nsw i32 %0, %i277 %add = add nsw i32 %mul, %sum278 %add72 = add nuw nsw i32 %i, 1279 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72280 store i32 %add, ptr %arrayidx8, align 4281 %add6 = add nuw nsw i32 %j, 1282 %exitcond = icmp eq i32 %add6, %N283 br i1 %exitcond, label %for.latch, label %for.inner284 285for.latch:286 %add7 = add nuw nsw i32 %i, 1287 %exitcond29 = icmp eq i32 %add7, %N288 br i1 %exitcond29, label %cleanup, label %for.outer289 290cleanup:291 ret void292}293 294 295; CHECK-LABEL: sub_aft_less296; CHECK: %j = phi297; CHECK: %j.1 = phi298; CHECK: %j.2 = phi299; CHECK: %j.3 = phi300;301; sub_aft_less SHOULD be unroll-and-jammed (count=4) as it's safe.302; Memory accesses:303; - Sub block: A[i] = 1 (write inside inner loop)304; - Aft block: A[i-1] = sum (write in outer loop after inner)305; No dependency conflict: The sub block writes A[i] and aft block writes A[i-1].306; These access different array elements, so unroll-and-jam is safe. The backward307; dependency pattern doesn't create conflicts between unrolled iterations.308define void @sub_aft_less(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {309entry:310 %cmp = icmp sgt i32 %N, 0311 br i1 %cmp, label %for.outer, label %cleanup312 313for.outer:314 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]315 br label %for.inner316 317for.inner:318 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]319 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]320 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j321 %0 = load i32, ptr %arrayidx5, align 4322 %mul = mul nsw i32 %0, %i323 %add = add nsw i32 %mul, %sum324 %add6 = add nuw nsw i32 %j, 1325 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i326 store i32 1, ptr %arrayidx, align 4327 %exitcond = icmp eq i32 %add6, %N328 br i1 %exitcond, label %for.latch, label %for.inner329 330for.latch:331 %add7 = add nuw nsw i32 %i, 1332 %add72 = add nuw nsw i32 %i, -1333 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72334 store i32 %add, ptr %arrayidx8, align 4335 %exitcond29 = icmp eq i32 %add7, %N336 br i1 %exitcond29, label %cleanup, label %for.outer337 338cleanup:339 ret void340}341 342 343; CHECK-LABEL: sub_aft_eq344; CHECK: %j = phi345; CHECK: %j.1 = phi346; CHECK: %j.2 = phi347; CHECK: %j.3 = phi348;349; sub_aft_eq SHOULD be unroll-and-jammed (count=4) as it's safe.350; Memory accesses:351; - Sub block: A[i] = 1 (write inside inner loop)352; - Aft block: A[i] = sum (write in outer loop after inner)353; Dependency conflict: Both sub and aft blocks write to A[i], creating a354; write-after-write (WAW) dependency. However, this is safe for unroll-and-jam355; because the execution order is preserved: the entire inner loop (sub block)356; executes first, then the aft block executes, maintaining original semantics.357define void @sub_aft_eq(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {358entry:359 %cmp = icmp sgt i32 %N, 0360 br i1 %cmp, label %for.outer, label %cleanup361 362for.outer:363 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]364 br label %for.inner365 366for.inner:367 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]368 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]369 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j370 %0 = load i32, ptr %arrayidx5, align 4371 %mul = mul nsw i32 %0, %i372 %add = add nsw i32 %mul, %sum373 %add6 = add nuw nsw i32 %j, 1374 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i375 store i32 1, ptr %arrayidx, align 4376 %exitcond = icmp eq i32 %add6, %N377 br i1 %exitcond, label %for.latch, label %for.inner378 379for.latch:380 %add7 = add nuw nsw i32 %i, 1381 %add72 = add nuw nsw i32 %i, 0382 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %i383 store i32 %add, ptr %arrayidx8, align 4384 %exitcond29 = icmp eq i32 %add7, %N385 br i1 %exitcond29, label %cleanup, label %for.outer386 387cleanup:388 ret void389}390 391 392; CHECK-LABEL: sub_aft_more393; CHECK: %j = phi394; CHECK-NOT: %j.1 = phi395;396; sub_aft_more should NOT be unroll-and-jammed due to a dependency violation.397; Memory accesses:398; - Sub block: A[i] = 1 (write inside inner loop)399; - Aft block: A[i+1] = sum (write in outer loop after inner)400; Dependency conflict: The sub block writes A[i] and aft block writes A[i+1].401; When unroll-and-jamming, iteration i's aft block writes A[i+1] which conflicts402; with iteration i+1's sub block write to A[i+1], creating a write-after-write403; race condition that violates the original sequential semantics.404define void @sub_aft_more(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {405entry:406 %cmp = icmp sgt i32 %N, 0407 br i1 %cmp, label %for.outer, label %cleanup408 409for.outer:410 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]411 br label %for.inner412 413for.inner:414 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]415 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]416 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j417 %0 = load i32, ptr %arrayidx5, align 4418 %mul = mul nsw i32 %0, %i419 %add = add nsw i32 %mul, %sum420 %add6 = add nuw nsw i32 %j, 1421 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i422 store i32 1, ptr %arrayidx, align 4423 %exitcond = icmp eq i32 %add6, %N424 br i1 %exitcond, label %for.latch, label %for.inner425 426for.latch:427 %add7 = add nuw nsw i32 %i, 1428 %add72 = add nuw nsw i32 %i, 1429 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72430 store i32 %add, ptr %arrayidx8, align 4431 %exitcond29 = icmp eq i32 %add7, %N432 br i1 %exitcond29, label %cleanup, label %for.outer433 434cleanup:435 ret void436}437 438 439; CHECK-LABEL: sub_sub_less440; CHECK: %j = phi441; CHECK-NOT: %j.1 = phi442;443; sub_sub_less should NOT be unroll-and-jammed due to a dependency violation.444; Memory accesses:445; - Sub block: A[i] = 1 (write inside inner loop)446; - Sub block: A[i-1] = sum (write inside inner loop)447; Dependency conflict: Both writes are in the sub block (inner loop), accessing448; A[i] and A[i-1]. When unroll-and-jamming, the inner loop is jammed, meaning449; iterations of the inner loop from different outer iterations execute together.450; This creates a backward dependency that can cause race conditions.451define void @sub_sub_less(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {452entry:453 %cmp = icmp sgt i32 %N, 0454 br i1 %cmp, label %for.outer, label %cleanup455 456for.outer:457 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]458 br label %for.inner459 460for.inner:461 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]462 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]463 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j464 %0 = load i32, ptr %arrayidx5, align 4465 %mul = mul nsw i32 %0, %i466 %add = add nsw i32 %mul, %sum467 %add6 = add nuw nsw i32 %j, 1468 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i469 store i32 1, ptr %arrayidx, align 4470 %add72 = add nuw nsw i32 %i, -1471 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72472 store i32 %add, ptr %arrayidx8, align 4473 %exitcond = icmp eq i32 %add6, %N474 br i1 %exitcond, label %for.latch, label %for.inner475 476for.latch:477 %add7 = add nuw nsw i32 %i, 1478 %exitcond29 = icmp eq i32 %add7, %N479 br i1 %exitcond29, label %cleanup, label %for.outer480 481cleanup:482 ret void483}484 485 486; CHECK-LABEL: sub_sub_eq487; CHECK: %j = phi488; CHECK: %j.1 = phi489; CHECK: %j.2 = phi490; CHECK: %j.3 = phi491;492; sub_sub_eq SHOULD be unroll-and-jammed (count=4) as it's safe.493; Memory accesses:494; - Sub block: A[i] = 1 (write inside inner loop)495; - Sub block: A[i] = sum (write inside inner loop)496; Dependency conflict: Both writes are to A[i] within the sub block, creating a497; write-after-write (WAW) dependency. However, this is safe for unroll-and-jam498; because both writes are in the same basic block and maintain their relative499; order: A[i] = 1 always executes before A[i] = sum in each iteration.500define void @sub_sub_eq(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {501entry:502 %cmp = icmp sgt i32 %N, 0503 br i1 %cmp, label %for.outer, label %cleanup504 505for.outer:506 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]507 br label %for.inner508 509for.inner:510 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]511 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]512 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j513 %0 = load i32, ptr %arrayidx5, align 4514 %mul = mul nsw i32 %0, %i515 %add = add nsw i32 %mul, %sum516 %add6 = add nuw nsw i32 %j, 1517 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i518 store i32 1, ptr %arrayidx, align 4519 %add72 = add nuw nsw i32 %i, 0520 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72521 store i32 %add, ptr %arrayidx8, align 4522 %exitcond = icmp eq i32 %add6, %N523 br i1 %exitcond, label %for.latch, label %for.inner524 525for.latch:526 %add7 = add nuw nsw i32 %i, 1527 %exitcond29 = icmp eq i32 %add7, %N528 br i1 %exitcond29, label %cleanup, label %for.outer529 530cleanup:531 ret void532}533 534 535; CHECK-LABEL: sub_sub_more536; CHECK: %j = phi537; CHECK-NOT: %j.1 = phi538;539; sub_sub_more should NOT be unroll-and-jammed due to a dependency violation.540; Memory accesses:541; - Sub block: A[i] = 1 (write inside inner loop)542; - Sub block: A[i+1] = sum (write inside inner loop)543; Dependency conflict: Both writes are in the sub block, accessing A[i] and A[i+1].544; When unroll-and-jamming, iteration i's sub block writes A[i+1] which conflicts545; with iteration i+1's sub block write to A[i+1]. This creates a forward546; dependency that causes write-after-write race conditions.547define void @sub_sub_more(ptr noalias nocapture %A, i32 %N, ptr noalias nocapture readonly %B) {548entry:549 %cmp = icmp sgt i32 %N, 0550 br i1 %cmp, label %for.outer, label %cleanup551 552for.outer:553 %i = phi i32 [ %add7, %for.latch ], [ 0, %entry ]554 br label %for.inner555 556for.inner:557 %j = phi i32 [ %add6, %for.inner ], [ 0, %for.outer ]558 %sum = phi i32 [ %add, %for.inner ], [ 0, %for.outer ]559 %arrayidx5 = getelementptr inbounds i32, ptr %B, i32 %j560 %0 = load i32, ptr %arrayidx5, align 4561 %mul = mul nsw i32 %0, %i562 %add = add nsw i32 %mul, %sum563 %add6 = add nuw nsw i32 %j, 1564 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i565 store i32 1, ptr %arrayidx, align 4566 %add72 = add nuw nsw i32 %i, 1567 %arrayidx8 = getelementptr inbounds i32, ptr %A, i32 %add72568 store i32 %add, ptr %arrayidx8, align 4569 %exitcond = icmp eq i32 %add6, %N570 br i1 %exitcond, label %for.latch, label %for.inner571 572for.latch:573 %add7 = add nuw nsw i32 %i, 1574 %exitcond29 = icmp eq i32 %add7, %N575 br i1 %exitcond29, label %cleanup, label %for.outer576 577cleanup:578 ret void579}580