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