1; RUN: opt -passes=loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 -pass-remarks=loop-unroll-and-jam < %s -S 2>&1 | FileCheck %s 2; RUN: opt -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 -pass-remarks=loop-unroll-and-jam < %s -S 2>&1 | FileCheck %s 3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5 6;; Common check for all tests. None should be unroll and jammed 7; CHECK-NOT: remark: {{.*}} unroll and jammed 8 9 10; CHECK-LABEL: disabled1 11; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i+1] = sum; } 12; A[i] to A[i+1] dependency should block unrollandjam 13define void @disabled1(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 14; CHECK: %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ] 15; CHECK: %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 16entry: 17 %cmp = icmp ne i32 %J, 0 18 %cmp127 = icmp ne i32 %I, 0 19 %or.cond = and i1 %cmp127, %cmp 20 br i1 %or.cond, label %for.preheader, label %return 21 22for.preheader: 23 br label %for.outer 24 25for.outer: 26 %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ] 27 %b.028 = phi i32 [ %inc8, %for.latch ], [ 1, %for.preheader ] 28 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.029 29 %0 = load i32, ptr %arrayidx, align 4 30 br label %for.inner 31 32for.inner: 33 %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 34 %sum1.025 = phi i32 [ %0, %for.outer ], [ %add, %for.inner ] 35 %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %j.026 36 %1 = load i32, ptr %arrayidx6, align 4 37 %add = add i32 %1, %sum1.025 38 %inc = add nuw i32 %j.026, 1 39 %exitcond = icmp eq i32 %inc, %J 40 br i1 %exitcond, label %for.latch, label %for.inner 41 42for.latch: 43 %arrayidx7 = getelementptr inbounds i32, ptr %A, i32 %b.028 44 store i32 %add, ptr %arrayidx7, align 4 45 %inc8 = add nuw nsw i32 %b.028, 1 46 %add10 = add nuw nsw i32 %i.029, 1 47 %exitcond30 = icmp eq i32 %add10, %I 48 br i1 %exitcond30, label %return, label %for.outer 49 50return: 51 ret void 52} 53 54 55; CHECK-LABEL: disabled2 56; Tests an incompatible block layout (for.outer jumps past for.inner) 57; FIXME: Make this work 58define void @disabled2(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 59; CHECK: %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ] 60; CHECK: %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ] 61entry: 62 %cmp = icmp ne i32 %J, 0 63 %cmp131 = icmp ne i32 %I, 0 64 %or.cond = and i1 %cmp131, %cmp 65 br i1 %or.cond, label %for.preheader, label %for.end14 66 67for.preheader: 68 br label %for.outer 69 70for.outer: 71 %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ] 72 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %i.032 73 %0 = load i32, ptr %arrayidx, align 4 74 %tobool = icmp eq i32 %0, 0 75 br i1 %tobool, label %for.latch, label %for.inner 76 77for.inner: 78 %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.outer ] 79 %sum1.029 = phi i32 [ %sum1.1, %for.inner ], [ 0, %for.outer ] 80 %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %j.030 81 %1 = load i32, ptr %arrayidx6, align 4 82 %tobool7 = icmp eq i32 %1, 0 83 %sub = add i32 %sum1.029, 10 84 %add = sub i32 %sub, %1 85 %sum1.1 = select i1 %tobool7, i32 %sum1.029, i32 %add 86 %inc = add nuw i32 %j.030, 1 87 %exitcond = icmp eq i32 %inc, %J 88 br i1 %exitcond, label %for.latch, label %for.inner 89 90for.latch: 91 %sum1.1.lcssa = phi i32 [ 0, %for.outer ], [ %sum1.1, %for.inner ] 92 %arrayidx11 = getelementptr inbounds i32, ptr %A, i32 %i.032 93 store i32 %sum1.1.lcssa, ptr %arrayidx11, align 4 94 %add13 = add nuw i32 %i.032, 1 95 %exitcond33 = icmp eq i32 %add13, %I 96 br i1 %exitcond33, label %for.end14, label %for.outer 97 98for.end14: 99 ret void 100} 101 102 103; CHECK-LABEL: disabled3 104; Tests loop carry dependencies in an array S 105define void @disabled3(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 106; CHECK: %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ] 107; CHECK: %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 108entry: 109 %S = alloca [4 x i32], align 4 110 %cmp = icmp eq i32 %J, 0 111 br i1 %cmp, label %return, label %if.end 112 113if.end: 114 %cmp128 = icmp eq i32 %I, 0 115 br i1 %cmp128, label %for.cond.cleanup, label %for.preheader 116 117for.preheader: 118 br label %for.outer 119 120for.cond.cleanup: 121 br label %return 122 123for.outer: 124 %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ] 125 br label %for.inner 126 127for.inner: 128 %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 129 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j.027 130 %l2 = load i32, ptr %arrayidx, align 4 131 %add = add i32 %j.027, %i.029 132 %rem = urem i32 %add, %J 133 %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %rem 134 %l3 = load i32, ptr %arrayidx6, align 4 135 %mul = mul i32 %l3, %l2 136 %rem7 = urem i32 %j.027, 3 137 %arrayidx8 = getelementptr inbounds [4 x i32], ptr %S, i32 0, i32 %rem7 138 store i32 %mul, ptr %arrayidx8, align 4 139 %inc = add nuw i32 %j.027, 1 140 %exitcond = icmp eq i32 %inc, %J 141 br i1 %exitcond, label %for.latch, label %for.inner 142 143for.latch: 144 %l1 = load i32, ptr %S, align 4 145 %arrayidx10 = getelementptr inbounds i32, ptr %A, i32 %i.029 146 store i32 %l1, ptr %arrayidx10, align 4 147 %add12 = add nuw i32 %i.029, 1 148 %exitcond31 = icmp eq i32 %add12, %I 149 br i1 %exitcond31, label %for.cond.cleanup, label %for.outer 150 151return: 152 ret void 153} 154 155 156; CHECK-LABEL: disabled4 157; Inner looop induction variable is not consistent 158; ie for(i = 0..n) for (j = 0..i) sum+=B[j] 159define void @disabled4(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 160; CHECK: %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ] 161; CHECK: %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 162entry: 163 %cmp = icmp ne i32 %J, 0 164 %cmp122 = icmp ugt i32 %I, 1 165 %or.cond = and i1 %cmp122, %cmp 166 br i1 %or.cond, label %for.preheader, label %for.end9 167 168for.preheader: 169 br label %for.outer 170 171for.outer: 172 %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ] 173 br label %for.inner 174 175for.inner: 176 %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 177 %sum1.020 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 178 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j.021 179 %0 = load i32, ptr %arrayidx, align 4 180 %add = add i32 %0, %sum1.020 181 %inc = add nuw i32 %j.021, 1 182 %exitcond = icmp eq i32 %inc, %indvars.iv 183 br i1 %exitcond, label %for.latch, label %for.inner 184 185for.latch: 186 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %indvars.iv 187 store i32 %add, ptr %arrayidx6, align 4 188 %indvars.iv.next = add nuw i32 %indvars.iv, 1 189 %exitcond24 = icmp eq i32 %indvars.iv.next, %I 190 br i1 %exitcond24, label %for.end9, label %for.outer 191 192for.end9: 193 ret void 194} 195 196 197; CHECK-LABEL: disabled5 198; Test odd uses of phi nodes where the outer IV cannot be moved into Fore as it hits a PHI 199@f = hidden global i32 0, align 4 200define i32 @disabled5() #0 { 201; CHECK: %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ] 202; CHECK: %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ] 203entry: 204 %f.promoted10 = load i32, ptr @f, align 4 205 br label %for.outer 206 207for.outer: 208 %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ] 209 %d.018 = phi i16 [ 0, %entry ], [ %odd.lcssa, %for.latch ] 210 %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ] 211 br label %for.inner 212 213for.inner: 214 %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ] 215 %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 216 %inc = add nuw nsw i32 %inc.sink8, 1 217 %exitcond = icmp ne i32 %inc, 7 218 br i1 %exitcond, label %for.inner, label %for.latch 219 220for.latch: 221 %.lcssa = phi i32 [ %1, %for.inner ] 222 %odd.lcssa = phi i16 [ 1, %for.inner ] 223 %inc5 = add nuw nsw i32 %inc5.sink9, 1 224 %exitcond11 = icmp ne i32 %inc5, 7 225 br i1 %exitcond11, label %for.outer, label %for.end 226 227for.end: 228 %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ] 229 %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ] 230 ret i32 0 231} 232 233 234; CHECK-LABEL: disabled6 235; There is a dependency in here, between @d and %0 (=@f) 236@d6 = hidden global i16 5, align 2 237@f6 = hidden global ptr @d6, align 4 238define i32 @disabled6() #0 { 239; CHECK: %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ] 240; CHECK: %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ] 241entry: 242 store i16 1, ptr @d6, align 2 243 %0 = load ptr, ptr @f6, align 4 244 br label %for.body.i 245 246for.body.i: 247 %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ] 248 %1 = load i16, ptr %0, align 2 249 br label %for.body6.i 250 251for.cond.cleanup.i: 252 %inc8.i = add nuw nsw i16 %inc8.sink14.i, 1 253 store i16 %inc8.i, ptr @d6, align 2 254 %cmp.i = icmp ult i16 %inc8.i, 6 255 br i1 %cmp.i, label %for.body.i, label %test.exit 256 257for.body6.i: 258 %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ] 259 %inc.i = add nuw nsw i32 %c.013.i, 1 260 %exitcond.i = icmp eq i32 %inc.i, 7 261 br i1 %exitcond.i, label %for.cond.cleanup.i, label %for.body6.i 262 263test.exit: 264 %conv2.i = sext i16 %1 to i32 265 ret i32 0 266} 267 268 269; CHECK-LABEL: disabled7 270; Has negative output dependency 271define void @disabled7(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 272; CHECK: %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ] 273; CHECK: %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ] 274entry: 275 %cmp = icmp ne i32 %J, 0 276 %cmp127 = icmp ne i32 %I, 0 277 %or.cond = and i1 %cmp127, %cmp 278 br i1 %or.cond, label %for.body.preheader, label %for.end12 279 280for.body.preheader: 281 br label %for.body 282 283for.body: 284 %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ] 285 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.028 286 store i32 0, ptr %arrayidx, align 4 287 %sub = add i32 %i.028, -1 288 %arrayidx2 = getelementptr inbounds i32, ptr %A, i32 %sub 289 store i32 2, ptr %arrayidx2, align 4 290 br label %for.body6 291 292for.cond3.for.cond.cleanup5_crit_edge: 293 store i32 %add, ptr %arrayidx, align 4 294 %add11 = add nuw i32 %i.028, 1 295 %exitcond29 = icmp eq i32 %add11, %I 296 br i1 %exitcond29, label %for.end12, label %for.body 297 298for.body6: 299 %0 = phi i32 [ 0, %for.body ], [ %add, %for.body6 ] 300 %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ] 301 %arrayidx7 = getelementptr inbounds i32, ptr %B, i32 %j.026 302 %1 = load i32, ptr %arrayidx7, align 4 303 %add = add i32 %1, %0 304 %add9 = add nuw i32 %j.026, 1 305 %exitcond = icmp eq i32 %add9, %J 306 br i1 %exitcond, label %for.cond3.for.cond.cleanup5_crit_edge, label %for.body6 307 308for.end12: 309 ret void 310} 311 312 313; CHECK-LABEL: disabled8 314; Same as above with an extra outer loop nest 315define void @disabled8(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 316; CHECK: %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ] 317; CHECK: %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ] 318entry: 319 %cmp = icmp eq i32 %J, 0 320 %cmp335 = icmp eq i32 %I, 0 321 %or.cond = or i1 %cmp, %cmp335 322 br i1 %or.cond, label %for.end18, label %for.body.preheader 323 324for.body.preheader: 325 br label %for.body 326 327for.body: 328 %x.037 = phi i32 [ %inc, %for.cond.cleanup4 ], [ 0, %for.body.preheader ] 329 br label %for.outer 330 331for.cond.cleanup4: 332 %inc = add nuw nsw i32 %x.037, 1 333 %exitcond40 = icmp eq i32 %inc, 5 334 br i1 %exitcond40, label %for.end18, label %for.body 335 336for.outer: 337 %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ] 338 %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.036 339 store i32 0, ptr %arrayidx, align 4 340 %sub = add i32 %i.036, -1 341 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %sub 342 store i32 2, ptr %arrayidx6, align 4 343 br label %for.inner 344 345for.latch: 346 store i32 %add, ptr %arrayidx, align 4 347 %add15 = add nuw i32 %i.036, 1 348 %exitcond38 = icmp eq i32 %add15, %I 349 br i1 %exitcond38, label %for.cond.cleanup4, label %for.outer 350 351for.inner: 352 %0 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 353 %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ] 354 %arrayidx11 = getelementptr inbounds i32, ptr %B, i32 %j.034 355 %1 = load i32, ptr %arrayidx11, align 4 356 %add = add i32 %1, %0 357 %add13 = add nuw i32 %j.034, 1 358 %exitcond = icmp eq i32 %add13, %J 359 br i1 %exitcond, label %for.latch, label %for.inner 360 361for.end18: 362 ret void 363} 364 365 366; CHECK-LABEL: disabled9 367; Can't prove alias between A and B 368define void @disabled9(i32 %I, i32 %J, ptr nocapture %A, ptr nocapture readonly %B) #0 { 369; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 370; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 371entry: 372 %cmp = icmp ne i32 %J, 0 373 %cmp122 = icmp ne i32 %I, 0 374 %or.cond = and i1 %cmp, %cmp122 375 br i1 %or.cond, label %for.outer.preheader, label %for.end 376 377for.outer.preheader: 378 br label %for.outer 379 380for.outer: 381 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 382 br label %for.inner 383 384for.inner: 385 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 386 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 387 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 388 %0 = load i32, ptr %arrayidx, align 4 389 %add = add i32 %0, %sum1 390 %inc = add nuw i32 %j, 1 391 %exitcond = icmp eq i32 %inc, %J 392 br i1 %exitcond, label %for.latch, label %for.inner 393 394for.latch: 395 %add.lcssa = phi i32 [ %add, %for.inner ] 396 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 397 store i32 %add.lcssa, ptr %arrayidx6, align 4 398 %add8 = add nuw i32 %i, 1 399 %exitcond25 = icmp eq i32 %add8, %I 400 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 401 402for.end.loopexit: 403 br label %for.end 404 405for.end: 406 ret void 407} 408 409 410; CHECK-LABEL: disable10 411; Simple call 412declare void @f10(i32, i32) #0 413define void @disable10(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 414; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 415; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 416entry: 417 %cmp = icmp ne i32 %J, 0 418 %cmp122 = icmp ne i32 %I, 0 419 %or.cond = and i1 %cmp, %cmp122 420 br i1 %or.cond, label %for.outer.preheader, label %for.end 421 422for.outer.preheader: 423 br label %for.outer 424 425for.outer: 426 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 427 br label %for.inner 428 429for.inner: 430 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 431 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 432 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 433 %0 = load i32, ptr %arrayidx, align 4 434 %add = add i32 %0, %sum1 435 %inc = add nuw i32 %j, 1 436 %exitcond = icmp eq i32 %inc, %J 437 tail call void @f10(i32 %i, i32 %j) nounwind 438 br i1 %exitcond, label %for.latch, label %for.inner 439 440for.latch: 441 %add.lcssa = phi i32 [ %add, %for.inner ] 442 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 443 store i32 %add.lcssa, ptr %arrayidx6, align 4 444 %add8 = add nuw i32 %i, 1 445 %exitcond25 = icmp eq i32 %add8, %I 446 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 447 448for.end.loopexit: 449 br label %for.end 450 451for.end: 452 ret void 453} 454 455 456; CHECK-LABEL: disable11 457; volatile 458define void @disable11(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 459; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 460; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 461entry: 462 %cmp = icmp ne i32 %J, 0 463 %cmp122 = icmp ne i32 %I, 0 464 %or.cond = and i1 %cmp, %cmp122 465 br i1 %or.cond, label %for.outer.preheader, label %for.end 466 467for.outer.preheader: 468 br label %for.outer 469 470for.outer: 471 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 472 br label %for.inner 473 474for.inner: 475 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 476 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 477 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 478 %0 = load volatile i32, ptr %arrayidx, align 4 479 %add = add i32 %0, %sum1 480 %inc = add nuw i32 %j, 1 481 %exitcond = icmp eq i32 %inc, %J 482 br i1 %exitcond, label %for.latch, label %for.inner 483 484for.latch: 485 %add.lcssa = phi i32 [ %add, %for.inner ] 486 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 487 store i32 %add.lcssa, ptr %arrayidx6, align 4 488 %add8 = add nuw i32 %i, 1 489 %exitcond25 = icmp eq i32 %add8, %I 490 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 491 492for.end.loopexit: 493 br label %for.end 494 495for.end: 496 ret void 497} 498 499 500; CHECK-LABEL: disable12 501; Multiple aft blocks 502define void @disable12(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 503; CHECK: %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ] 504; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 505entry: 506 %cmp = icmp ne i32 %J, 0 507 %cmp122 = icmp ne i32 %I, 0 508 %or.cond = and i1 %cmp, %cmp122 509 br i1 %or.cond, label %for.outer.preheader, label %for.end 510 511for.outer.preheader: 512 br label %for.outer 513 514for.outer: 515 %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ] 516 br label %for.inner 517 518for.inner: 519 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 520 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 521 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 522 %0 = load i32, ptr %arrayidx, align 4 523 %add = add i32 %0, %sum1 524 %inc = add nuw i32 %j, 1 525 %exitcond = icmp eq i32 %inc, %J 526 br i1 %exitcond, label %for.latch, label %for.inner 527 528for.latch: 529 %add.lcssa = phi i32 [ %add, %for.inner ] 530 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 531 store i32 %add.lcssa, ptr %arrayidx6, align 4 532 %cmpl = icmp eq i32 %add.lcssa, 10 533 br i1 %cmpl, label %for.latch2, label %for.latch3 534 535for.latch2: 536 br label %for.latch3 537 538for.latch3: 539 %add8 = add nuw i32 %i, 1 540 %exitcond25 = icmp eq i32 %add8, %I 541 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 542 543for.end.loopexit: 544 br label %for.end 545 546for.end: 547 ret void 548} 549 550 551; CHECK-LABEL: disable13 552; Two subloops 553define void @disable13(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 554; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 555; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 556; CHECK: %j2 = phi i32 [ %inc2, %for.inner2 ], [ 0, %for.inner2.preheader ] 557entry: 558 %cmp = icmp ne i32 %J, 0 559 %cmp122 = icmp ne i32 %I, 0 560 %or.cond = and i1 %cmp, %cmp122 561 br i1 %or.cond, label %for.outer.preheader, label %for.end 562 563for.outer.preheader: 564 br label %for.outer 565 566for.outer: 567 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 568 br label %for.inner 569 570for.inner: 571 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 572 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 573 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 574 %0 = load i32, ptr %arrayidx, align 4 575 %add = add i32 %0, %sum1 576 %inc = add nuw i32 %j, 1 577 %exitcond = icmp eq i32 %inc, %J 578 br i1 %exitcond, label %for.inner2, label %for.inner 579 580for.inner2: 581 %j2 = phi i32 [ 0, %for.inner ], [ %inc2, %for.inner2 ] 582 %sum12 = phi i32 [ 0, %for.inner ], [ %add2, %for.inner2 ] 583 %arrayidx2 = getelementptr inbounds i32, ptr %B, i32 %j2 584 %l0 = load i32, ptr %arrayidx2, align 4 585 %add2 = add i32 %l0, %sum12 586 %inc2 = add nuw i32 %j2, 1 587 %exitcond2 = icmp eq i32 %inc2, %J 588 br i1 %exitcond2, label %for.latch, label %for.inner2 589 590for.latch: 591 %add.lcssa = phi i32 [ %add, %for.inner2 ] 592 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 593 store i32 %add.lcssa, ptr %arrayidx6, align 4 594 %add8 = add nuw i32 %i, 1 595 %exitcond25 = icmp eq i32 %add8, %I 596 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 597 598for.end.loopexit: 599 br label %for.end 600 601for.end: 602 ret void 603} 604 605 606; CHECK-LABEL: disable14 607; Multiple exits blocks 608define void @disable14(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 609; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 610; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ] 611entry: 612 %cmp = icmp ne i32 %J, 0 613 %cmp122 = icmp ne i32 %I, 0 614 %or.cond = and i1 %cmp, %cmp122 615 br i1 %or.cond, label %for.outer.preheader, label %for.end 616 617for.outer.preheader: 618 br label %for.outer 619 620for.outer: 621 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 622 %add8 = add nuw i32 %i, 1 623 %exitcond23 = icmp eq i32 %add8, %I 624 br i1 %exitcond23, label %for.end.loopexit, label %for.inner 625 626for.inner: 627 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 628 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 629 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 630 %0 = load i32, ptr %arrayidx, align 4 631 %add = add i32 %0, %sum1 632 %inc = add nuw i32 %j, 1 633 %exitcond = icmp eq i32 %inc, %J 634 br i1 %exitcond, label %for.latch, label %for.inner 635 636for.latch: 637 %add.lcssa = phi i32 [ %add, %for.inner ] 638 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 639 store i32 %add.lcssa, ptr %arrayidx6, align 4 640 %exitcond25 = icmp eq i32 %add8, %I 641 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 642 643for.end.loopexit: 644 br label %for.end 645 646for.end: 647 ret void 648} 649 650 651; CHECK-LABEL: disable15 652; Latch != exit 653define void @disable15(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 654; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 655; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ] 656entry: 657 %cmp = icmp ne i32 %J, 0 658 %cmp122 = icmp ne i32 %I, 0 659 %or.cond = and i1 %cmp, %cmp122 660 br i1 %or.cond, label %for.outer.preheader, label %for.end 661 662for.outer.preheader: 663 br label %for.outer 664 665for.outer: 666 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 667 %add8 = add nuw i32 %i, 1 668 %exitcond25 = icmp eq i32 %add8, %I 669 br i1 %exitcond25, label %for.end.loopexit, label %for.inner 670 671for.inner: 672 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 673 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 674 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 675 %0 = load i32, ptr %arrayidx, align 4 676 %add = add i32 %0, %sum1 677 %inc = add nuw i32 %j, 1 678 %exitcond = icmp eq i32 %inc, %J 679 br i1 %exitcond, label %for.latch, label %for.inner 680 681for.latch: 682 %add.lcssa = phi i32 [ %add, %for.inner ] 683 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 684 store i32 %add.lcssa, ptr %arrayidx6, align 4 685 br label %for.outer 686 687for.end.loopexit: 688 br label %for.end 689 690for.end: 691 ret void 692} 693 694 695; CHECK-LABEL: disable16 696; Cannot move other before inner loop 697define void @disable16(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 { 698; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 699; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 700entry: 701 %cmp = icmp ne i32 %J, 0 702 %cmp122 = icmp ne i32 %I, 0 703 %or.cond = and i1 %cmp, %cmp122 704 br i1 %or.cond, label %for.outer.preheader, label %for.end 705 706for.outer.preheader: 707 br label %for.outer 708 709for.outer: 710 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ] 711 %otherphi = phi i32 [ %other, %for.latch ], [ 0, %for.outer.preheader ] 712 br label %for.inner 713 714for.inner: 715 %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ] 716 %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ] 717 %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j 718 %0 = load i32, ptr %arrayidx, align 4 719 %add = add i32 %0, %sum1 720 %inc = add nuw i32 %j, 1 721 %exitcond = icmp eq i32 %inc, %J 722 br i1 %exitcond, label %for.latch, label %for.inner 723 724for.latch: 725 %add.lcssa = phi i32 [ %add, %for.inner ] 726 %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i 727 store i32 %add.lcssa, ptr %arrayidx6, align 4 728 %add8 = add nuw i32 %i, 1 729 %exitcond25 = icmp eq i32 %add8, %I 730 %loadarr = getelementptr inbounds i32, ptr %A, i32 %i 731 %load = load i32, ptr %arrayidx6, align 4 732 %other = add i32 %otherphi, %load 733 br i1 %exitcond25, label %for.end.loopexit, label %for.outer 734 735for.end.loopexit: 736 br label %for.end 737 738for.end: 739 ret void 740} 741