1 ; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s 2 ; 3 ; Unit tests for LoopInfo::updateUnloop. 4 5 declare i1 @check() nounwind 6 7 ; Ensure that tail->inner is removed and rely on verify-loopinfo to 8 ; check soundness. 9 ; 10 ; CHECK: @skiplevelexit 11 ; CHECK: tail: 12 ; CHECK-NOT: br 13 ; CHECK: ret void 14 define void @skiplevelexit() nounwind { 15 entry: 16 br label %outer 17 18 outer: 19 br label %inner 20 21 inner: 22 %iv = phi i32 [ 0, %outer ], [ %inc, %tail ] 23 %inc = add i32 %iv, 1 24 %wbucond = call zeroext i1 @check() 25 br i1 %wbucond, label %outer.backedge, label %tail 26 27 tail: 28 br i1 false, label %inner, label %exit 29 30 outer.backedge: 31 br label %outer 32 33 exit: 34 ret void 35 } 36 37 ; Remove the middle loop of a triply nested loop tree. 38 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to 39 ; check soundness. 40 ; 41 ; CHECK: @unloopNested 42 ; Outer loop control. 43 ; CHECK: while.body: 44 ; CHECK: br i1 %cmp3, label %if.then, label %if.end 45 ; Inner loop control. 46 ; CHECK: while.end14.i: 47 ; CHECK: br i1 %call15.i, label %if.end.i, label %exit 48 ; Middle loop control should no longer reach %while.cond. 49 ; Now it is the outer loop backedge. 50 ; CHECK: exit: 51 ; CHECK: br label %while.cond.outer 52 define void @unloopNested() { 53 entry: 54 br label %while.cond.outer 55 56 while.cond.outer: 57 br label %while.cond 58 59 while.cond: 60 %cmp = call zeroext i1 @check() 61 br i1 %cmp, label %while.body, label %while.end 62 63 while.body: 64 %cmp3 = call zeroext i1 @check() 65 br i1 %cmp3, label %if.then, label %if.end 66 67 if.then: 68 br label %return 69 70 if.end: 71 %cmp.i48 = call zeroext i1 @check() 72 br i1 %cmp.i48, label %if.then.i, label %if.else20.i 73 74 if.then.i: 75 %cmp8.i = call zeroext i1 @check() 76 br i1 %cmp8.i, label %merge, label %if.else.i 77 78 if.else.i: 79 br label %merge 80 81 if.else20.i: 82 %cmp25.i = call zeroext i1 @check() 83 br i1 %cmp25.i, label %merge, label %if.else28.i 84 85 if.else28.i: 86 br label %merge 87 88 merge: 89 br label %while.cond2.i 90 91 while.cond2.i: 92 %cmp.i = call zeroext i1 @check() 93 br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i 94 95 while.cond2.backedge.i: 96 br label %while.cond2.i 97 98 while.end.i: 99 %cmp1114.i = call zeroext i1 @check() 100 br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i 101 102 while.body12.lr.ph.i: 103 br label %while.end14.i 104 105 while.end14.i: 106 %call15.i = call zeroext i1 @check() 107 br i1 %call15.i, label %if.end.i, label %exit 108 109 if.end.i: 110 br label %while.cond2.backedge.i 111 112 exit: 113 br i1 false, label %while.cond, label %if.else 114 115 if.else: 116 br label %while.cond.outer 117 118 while.end: 119 br label %return 120 121 return: 122 ret void 123 } 124 125 ; Remove the middle loop of a deeply nested loop tree. 126 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to 127 ; check soundness. 128 ; 129 ; CHECK: @unloopDeepNested 130 ; Inner-inner loop control. 131 ; CHECK: while.cond.us.i: 132 ; CHECK: br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i 133 ; CHECK: if.then.us.i: 134 ; CHECK: br label %while.cond.us.i 135 ; Inner loop tail. 136 ; CHECK: if.else.i: 137 ; CHECK: br label %while.cond.outer.i 138 ; Middle loop control (removed). 139 ; CHECK: valid_data.exit: 140 ; CHECK-NOT: br 141 ; CHECK: %cmp = call zeroext i1 @check() 142 ; Outer loop control. 143 ; CHECK: copy_data.exit: 144 ; CHECK: br i1 %cmp38, label %if.then39, label %while.cond.outer 145 ; Outer-outer loop tail. 146 ; CHECK: while.cond.outer.outer.backedge: 147 ; CHECK: br label %while.cond.outer.outer 148 define void @unloopDeepNested() nounwind { 149 for.cond8.preheader.i: 150 %cmp113.i = call zeroext i1 @check() 151 br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i 152 153 for.body13.lr.ph.i: 154 br label %make_data.exit 155 156 make_data.exit: 157 br label %while.cond.outer.outer 158 159 while.cond.outer.outer: 160 br label %while.cond.outer 161 162 while.cond.outer: 163 br label %while.cond 164 165 while.cond: 166 br label %while.cond.outer.i 167 168 while.cond.outer.i: 169 %tmp192.ph.i = call zeroext i1 @check() 170 br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit 171 172 while.cond.outer.split.us.i: 173 br label %while.cond.us.i 174 175 while.cond.us.i: 176 %cmp.us.i = call zeroext i1 @check() 177 br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i 178 179 while.body.us.i: 180 %cmp7.us.i = call zeroext i1 @check() 181 br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i 182 183 if.then.us.i: 184 br label %while.cond.us.i 185 186 if.else.i: 187 br label %while.cond.outer.i 188 189 next_data.exit: 190 %tmp192.ph.i.lcssa28 = call zeroext i1 @check() 191 br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body 192 193 while.body.loopexit: 194 br label %while.body 195 196 while.body: 197 br label %while.cond.i 198 199 while.cond.i: 200 %cmp.i = call zeroext i1 @check() 201 br i1 %cmp.i, label %valid_data.exit, label %while.body.i 202 203 while.body.i: 204 %cmp7.i = call zeroext i1 @check() 205 br i1 %cmp7.i, label %valid_data.exit, label %if.end.i 206 207 if.end.i: 208 br label %while.cond.i 209 210 valid_data.exit: 211 br i1 true, label %if.then, label %while.cond 212 213 if.then: 214 %cmp = call zeroext i1 @check() 215 br i1 %cmp, label %if.then12, label %if.end 216 217 if.then12: 218 br label %if.end 219 220 if.end: 221 %tobool3.i = call zeroext i1 @check() 222 br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i 223 224 while.body.lr.ph.i: 225 br label %copy_data.exit 226 227 copy_data.exit: 228 %cmp38 = call zeroext i1 @check() 229 br i1 %cmp38, label %if.then39, label %while.cond.outer 230 231 if.then39: 232 %cmp5.i = call zeroext i1 @check() 233 br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread 234 235 for.cond8.preheader.i8.thread: 236 br label %while.cond.outer.outer.backedge 237 238 while.cond.outer.outer.backedge: 239 br label %while.cond.outer.outer 240 241 while.end: 242 ret void 243 } 244 245 ; Remove a nested loop with irreducible control flow. 246 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to 247 ; check soundness. 248 ; 249 ; CHECK: @unloopIrreducible 250 ; Irreducible loop. 251 ; CHECK: for.inc117: 252 ; CHECK: br label %for.cond103t 253 ; Nested loop (removed). 254 ; CHECK: for.inc159: 255 ; CHECK: br label %for.inc163 256 define void @unloopIrreducible() nounwind { 257 258 entry: 259 br label %for.body 260 261 for.body: 262 %cmp2113 = call zeroext i1 @check() 263 br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163 264 265 for.body22.lr.ph: 266 br label %for.body22 267 268 for.body22: 269 br label %for.body33 270 271 for.body33: 272 br label %for.end 273 274 for.end: 275 %cmp424 = call zeroext i1 @check() 276 br i1 %cmp424, label %for.body43.lr.ph, label %for.end93 277 278 for.body43.lr.ph: 279 br label %for.end93 280 281 for.end93: 282 %cmp96 = call zeroext i1 @check() 283 br i1 %cmp96, label %if.then97, label %for.cond103 284 285 if.then97: 286 br label %for.cond103t 287 288 for.cond103t: 289 br label %for.cond103 290 291 for.cond103: 292 %cmp105 = call zeroext i1 @check() 293 br i1 %cmp105, label %for.body106, label %for.end120 294 295 for.body106: 296 %cmp108 = call zeroext i1 @check() 297 br i1 %cmp108, label %if.then109, label %for.inc117 298 299 if.then109: 300 br label %for.inc117 301 302 for.inc117: 303 br label %for.cond103t 304 305 for.end120: 306 br label %for.inc159 307 308 for.inc159: 309 br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge 310 311 for.cond15.for.inc163_crit_edge: 312 br label %for.inc163 313 314 for.inc163: 315 %cmp12 = call zeroext i1 @check() 316 br i1 %cmp12, label %for.body, label %for.end166 317 318 for.end166: 319 ret void 320 321 } 322 323 ; Remove a loop whose exit branches into a sibling loop. 324 ; Ensure that only the loop is removed and rely on verify-loopinfo to 325 ; check soundness. 326 ; 327 ; CHECK: @unloopCriticalEdge 328 ; CHECK: while.cond.outer.i.loopexit.split: 329 ; CHECK: br label %while.body 330 ; CHECK: while.body: 331 ; CHECK: br label %for.end78 332 define void @unloopCriticalEdge() nounwind { 333 entry: 334 br label %for.cond31 335 336 for.cond31: 337 br i1 undef, label %for.body35, label %for.end94 338 339 for.body35: 340 br label %while.cond.i.preheader 341 342 while.cond.i.preheader: 343 br i1 undef, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split 344 345 while.cond.i.preheader.split: 346 br label %while.cond.i 347 348 while.cond.i: 349 br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit 350 351 while.cond.outer.i.loopexit: 352 br label %while.cond.outer.i.loopexit.split 353 354 while.cond.outer.i.loopexit.split: 355 br i1 false, label %while.cond.i.preheader, label %Func2.exit 356 357 Func2.exit: 358 br label %while.body 359 360 while.body: 361 br i1 false, label %while.body, label %while.end 362 363 while.end: 364 br label %for.end78 365 366 for.end78: 367 br i1 undef, label %Proc2.exit, label %for.cond.i.preheader 368 369 for.cond.i.preheader: 370 br label %for.cond.i 371 372 for.cond.i: 373 br label %for.cond.i 374 375 Proc2.exit: 376 br label %for.cond31 377 378 for.end94: 379 ret void 380 } 381 382 ; Test UnloopUpdater::removeBlocksFromAncestors. 383 ; 384 ; Check that the loop backedge is removed from the middle loop 1699, 385 ; but not the inner loop 1676. 386 ; CHECK: while.body1694: 387 ; CHECK: br label %while.cond1676 388 ; CHECK: while.end1699: 389 ; CHECK: br label %sw.default1711 390 define void @removeSubloopBlocks() nounwind { 391 entry: 392 br label %tryagain.outer 393 394 tryagain.outer: ; preds = %sw.bb304, %entry 395 br label %tryagain 396 397 tryagain: ; preds = %while.end1699, %tryagain.outer 398 br i1 undef, label %sw.bb1669, label %sw.bb304 399 400 sw.bb304: ; preds = %tryagain 401 br i1 undef, label %return, label %tryagain.outer 402 403 sw.bb1669: ; preds = %tryagain 404 br i1 undef, label %sw.default1711, label %while.cond1676 405 406 while.cond1676: ; preds = %while.body1694, %sw.bb1669 407 br i1 undef, label %while.end1699, label %while.body1694 408 409 while.body1694: ; preds = %while.cond1676 410 br label %while.cond1676 411 412 while.end1699: ; preds = %while.cond1676 413 br i1 false, label %tryagain, label %sw.default1711 414 415 sw.default1711: ; preds = %while.end1699, %sw.bb1669, %tryagain 416 br label %defchar 417 418 defchar: ; preds = %sw.default1711, %sw.bb376 419 br i1 undef, label %if.end2413, label %if.then2368 420 421 if.then2368: ; preds = %defchar 422 unreachable 423 424 if.end2413: ; preds = %defchar 425 unreachable 426 427 return: ; preds = %sw.bb304 428 ret void 429 } 430