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