1 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefix=EPILOG-NO-IC 2 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s -check-prefix=EPILOG 3 ; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-count=2 -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine 4 ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s -check-prefix=PROLOG 5 ; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-runtime-epilog=false -unroll-count=2 -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine 6 7 ; REQUIRES: asserts 8 9 ; the third and fifth RUNs generate an epilog/prolog remainder block for all the test 10 ; cases below (it does not generate a loop). 11 12 ; test with three exiting and three exit blocks. 13 ; none of the exit blocks have successors 14 define void @test1(i64 %trip, i1 %cond) { 15 ; EPILOG: test1( 16 ; EPILOG-NEXT: entry: 17 ; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 18 ; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 19 ; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 20 ; EPILOG-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]] 21 ; EPILOG: entry.new: 22 ; EPILOG-NEXT: [[UNROLL_ITER:%.*]] = sub i64 [[TRIP]], [[XTRAITER]] 23 ; EPILOG-NEXT: br label [[LOOP_HEADER:%.*]] 24 ; EPILOG: loop_latch.epil: 25 ; EPILOG-NEXT: %epil.iter.sub = add i64 %epil.iter, -1 26 ; EPILOG-NEXT: %epil.iter.cmp = icmp eq i64 %epil.iter.sub, 0 27 ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %exit2.loopexit.epilog-lcssa, label %loop_header.epil 28 ; EPILOG: loop_latch.7: 29 ; EPILOG-NEXT: %niter.nsub.7 = add i64 %niter, -8 30 ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0 31 ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header 32 33 ; PROLOG: test1( 34 ; PROLOG-NEXT: entry: 35 ; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 36 ; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 37 ; PROLOG-NEXT: [[TMP1:%.*]] = icmp eq i64 [[XTRAITER]], 0 38 ; PROLOG-NEXT: br i1 [[TMP1]], label %loop_header.prol.loopexit, label %loop_header.prol.preheader 39 ; PROLOG: loop_header.prol: 40 ; PROLOG-NEXT: %iv.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %iv_next.prol, %loop_latch.prol ] 41 ; PROLOG-NEXT: %prol.iter = phi i64 [ [[XTRAITER]], %loop_header.prol.preheader ], [ %prol.iter.sub, %loop_latch.prol ] 42 ; PROLOG-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting_bb1.prol 43 ; PROLOG: loop_latch.prol: 44 ; PROLOG-NEXT: %iv_next.prol = add i64 %iv.prol, 1 45 ; PROLOG-NEXT: %prol.iter.sub = add i64 %prol.iter, -1 46 ; PROLOG-NEXT: %prol.iter.cmp = icmp eq i64 %prol.iter.sub, 0 47 ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %loop_header.prol.loopexit.unr-lcssa, label %loop_header.prol 48 ; PROLOG: loop_latch.7: 49 ; PROLOG-NEXT: %iv_next.7 = add i64 %iv, 8 50 ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip 51 ; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header 52 entry: 53 br label %loop_header 54 55 loop_header: 56 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] 57 br i1 %cond, label %loop_latch, label %loop_exiting_bb1 58 59 loop_exiting_bb1: 60 br i1 false, label %loop_exiting_bb2, label %exit1 61 62 loop_exiting_bb2: 63 br i1 false, label %loop_latch, label %exit3 64 65 exit3: 66 ret void 67 68 loop_latch: 69 %iv_next = add i64 %iv, 1 70 %cmp = icmp ne i64 %iv_next, %trip 71 br i1 %cmp, label %loop_header, label %exit2.loopexit 72 73 exit1: 74 ret void 75 76 exit2.loopexit: 77 ret void 78 } 79 80 81 ; test with three exiting and two exit blocks. 82 ; The non-latch exit block has 2 unique predecessors. 83 ; There are 2 values passed to the exit blocks that are calculated at every iteration. 84 ; %sum.02 and %add. Both of these are incoming values for phi from every exiting 85 ; unrolled block. 86 define i32 @test2(i32* nocapture %a, i64 %n) { 87 ; EPILOG: test2( 88 ; EPILOG: for.exit2.loopexit: 89 ; EPILOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ], [ %add.1, %for.body.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %for.body.2 ], [ 42, %for.exiting_block.3 ], 90 ; EPILOG-NEXT: br label %for.exit2 91 ; EPILOG: for.exit2.loopexit2: 92 ; EPILOG-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ] 93 ; EPILOG-NEXT: br label %for.exit2 94 ; EPILOG: for.exit2: 95 ; EPILOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ] 96 ; EPILOG-NEXT: ret i32 %retval 97 ; EPILOG: %niter.nsub.7 = add i64 %niter, -8 98 99 ; PROLOG: test2( 100 ; PROLOG: for.exit2.loopexit: 101 ; PROLOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ], [ %add.1, %for.body.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %for.body.2 ], [ 42, %for.exiting_block.3 ], 102 ; PROLOG-NEXT: br label %for.exit2 103 ; PROLOG: for.exit2.loopexit1: 104 ; PROLOG-NEXT: %retval.ph2 = phi i32 [ 42, %for.exiting_block.prol ], [ %sum.02.prol, %header.prol ] 105 ; PROLOG-NEXT: br label %for.exit2 106 ; PROLOG: for.exit2: 107 ; PROLOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph2, %for.exit2.loopexit1 ] 108 ; PROLOG-NEXT: ret i32 %retval 109 ; PROLOG: %indvars.iv.next.7 = add i64 %indvars.iv, 8 110 111 entry: 112 br label %header 113 114 header: 115 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 116 %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] 117 br i1 false, label %for.exit2, label %for.exiting_block 118 119 for.exiting_block: 120 %cmp = icmp eq i64 %n, 42 121 br i1 %cmp, label %for.exit2, label %for.body 122 123 for.body: 124 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 125 %0 = load i32, i32* %arrayidx, align 4 126 %add = add nsw i32 %0, %sum.02 127 %indvars.iv.next = add i64 %indvars.iv, 1 128 %exitcond = icmp eq i64 %indvars.iv.next, %n 129 br i1 %exitcond, label %for.end, label %header 130 131 for.end: ; preds = %for.body 132 %sum.0.lcssa = phi i32 [ %add, %for.body ] 133 ret i32 %sum.0.lcssa 134 135 for.exit2: 136 %retval = phi i32 [ %sum.02, %header ], [ 42, %for.exiting_block ] 137 ret i32 %retval 138 } 139 140 ; test with two exiting and three exit blocks. 141 ; the non-latch exiting block has a switch. 142 define void @test3(i64 %trip, i64 %add) { 143 ; EPILOG: test3( 144 ; EPILOG-NEXT: entry: 145 ; EPILOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 146 ; EPILOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 147 ; EPILOG-NEXT: [[TMP1:%.*]] = icmp ult i64 [[TMP0]], 7 148 ; EPILOG-NEXT: br i1 [[TMP1]], label %exit2.loopexit.unr-lcssa, label [[ENTRY_NEW:%.*]] 149 ; EPILOG: entry.new: 150 ; EPILOG-NEXT: %unroll_iter = sub i64 [[TRIP]], [[XTRAITER]] 151 ; EPILOG-NEXT: br label [[LOOP_HEADER:%.*]] 152 ; EPILOG: loop_header: 153 ; EPILOG-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.7, %loop_latch.7 ] 154 ; EPILOG-NEXT: %niter = phi i64 [ %unroll_iter, %entry.new ], [ %niter.nsub.7, %loop_latch.7 ] 155 ; EPILOG: loop_exiting_bb1.7: 156 ; EPILOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 157 ; EPILOG: loop_latch.7: 158 ; EPILOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add 159 ; EPILOG-NEXT: %niter.nsub.7 = add i64 %niter, -8 160 ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.nsub.7, 0 161 ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %exit2.loopexit.unr-lcssa.loopexit, label %loop_header 162 163 ; PROLOG: test3( 164 ; PROLOG-NEXT: entry: 165 ; PROLOG-NEXT: [[TMP0:%.*]] = add i64 [[TRIP:%.*]], -1 166 ; PROLOG-NEXT: [[XTRAITER:%.*]] = and i64 [[TRIP]], 7 167 ; PROLOG-NEXT: [[TMP1:%.*]] = icmp eq i64 [[XTRAITER]], 0 168 ; PROLOG-NEXT: br i1 [[TMP1]], label %loop_header.prol.loopexit, label %loop_header.prol.preheader 169 ; PROLOG: loop_header: 170 ; PROLOG-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.7, %loop_latch.7 ] 171 ; PROLOG-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.7, %loop_latch.7 ] 172 ; PROLOG: loop_exiting_bb1.7: 173 ; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 174 ; PROLOG: loop_latch.7: 175 ; PROLOG-NEXT: %iv_next.7 = add nsw i64 %iv, 8 176 ; PROLOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add 177 ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip 178 ; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header 179 entry: 180 br label %loop_header 181 182 loop_header: 183 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] 184 %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ] 185 br i1 undef, label %loop_latch, label %loop_exiting_bb1 186 187 loop_exiting_bb1: 188 switch i64 %sum, label %loop_latch [ 189 i64 24, label %exit1 190 i64 42, label %exit3 191 ] 192 193 exit3: 194 ret void 195 196 loop_latch: 197 %iv_next = add nuw nsw i64 %iv, 1 198 %sum.next = add i64 %sum, %add 199 %cmp = icmp ne i64 %iv_next, %trip 200 br i1 %cmp, label %loop_header, label %exit2.loopexit 201 202 exit1: 203 ret void 204 205 exit2.loopexit: 206 ret void 207 } 208 209 ; FIXME: Support multiple exiting blocks to the same latch exit block. 210 define i32 @test4(i32* nocapture %a, i64 %n, i1 %cond) { 211 ; EPILOG: test4( 212 ; EPILOG-NOT: .unr 213 ; EPILOG-NOT: .epil 214 215 ; PROLOG: test4( 216 ; PROLOG-NOT: .unr 217 ; PROLOG-NOT: .prol 218 entry: 219 br label %header 220 221 header: 222 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 223 %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] 224 br i1 %cond, label %for.end, label %for.exiting_block 225 226 for.exiting_block: 227 %cmp = icmp eq i64 %n, 42 228 br i1 %cmp, label %for.exit2, label %for.body 229 230 for.body: ; preds = %for.body, %entry 231 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 232 %0 = load i32, i32* %arrayidx, align 4 233 %add = add nsw i32 %0, %sum.02 234 %indvars.iv.next = add i64 %indvars.iv, 1 235 %exitcond = icmp eq i64 %indvars.iv.next, %n 236 br i1 %exitcond, label %for.end, label %header 237 238 for.end: ; preds = %for.body, %entry 239 %sum.0.lcssa = phi i32 [ 0, %header ], [ %add, %for.body ] 240 ret i32 %sum.0.lcssa 241 242 for.exit2: 243 ret i32 42 244 } 245 246 ; FIXME: Support multiple exiting blocks to the unique exit block. 247 define void @unique_exit(i32 %arg) { 248 ; EPILOG: unique_exit( 249 ; EPILOG-NOT: .unr 250 ; EPILOG-NOT: .epil 251 252 ; PROLOG: unique_exit( 253 ; PROLOG-NOT: .unr 254 ; PROLOG-NOT: .prol 255 entry: 256 %tmp = icmp sgt i32 undef, %arg 257 br i1 %tmp, label %preheader, label %returnblock 258 259 preheader: ; preds = %entry 260 br label %header 261 262 LoopExit: ; preds = %header, %latch 263 %tmp2.ph = phi i32 [ %tmp4, %header ], [ -1, %latch ] 264 br label %returnblock 265 266 returnblock: ; preds = %LoopExit, %entry 267 %tmp2 = phi i32 [ -1, %entry ], [ %tmp2.ph, %LoopExit ] 268 ret void 269 270 header: ; preds = %preheader, %latch 271 %tmp4 = phi i32 [ %inc, %latch ], [ %arg, %preheader ] 272 %inc = add nsw i32 %tmp4, 1 273 br i1 true, label %LoopExit, label %latch 274 275 latch: ; preds = %header 276 %cmp = icmp slt i32 %inc, undef 277 br i1 %cmp, label %header, label %LoopExit 278 } 279 280 ; two exiting and two exit blocks. 281 ; the non-latch exiting block has duplicate edges to the non-latch exit block. 282 define i64 @test5(i64 %trip, i64 %add, i1 %cond) { 283 ; EPILOG: test5( 284 ; EPILOG: exit1.loopexit: 285 ; EPILOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ], 286 ; EPILOG-NEXT: br label %exit1 287 ; EPILOG: exit1.loopexit2: 288 ; EPILOG-NEXT: %ivy.epil = add i64 %iv.epil, %add 289 ; EPILOG-NEXT: br label %exit1 290 ; EPILOG: exit1: 291 ; EPILOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.epil, %exit1.loopexit2 ] 292 ; EPILOG-NEXT: ret i64 %result 293 ; EPILOG: loop_latch.7: 294 ; EPILOG: %niter.nsub.7 = add i64 %niter, -8 295 296 ; PROLOG: test5( 297 ; PROLOG: exit1.loopexit: 298 ; PROLOG-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.2, %loop_exiting.2 ], 299 ; PROLOG-NEXT: br label %exit1 300 ; PROLOG: exit1.loopexit1: 301 ; PROLOG-NEXT: %ivy.prol = add i64 %iv.prol, %add 302 ; PROLOG-NEXT: br label %exit1 303 ; PROLOG: exit1: 304 ; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ] 305 ; PROLOG-NEXT: ret i64 %result 306 ; PROLOG: loop_latch.7: 307 ; PROLOG: %iv_next.7 = add nsw i64 %iv, 8 308 entry: 309 br label %loop_header 310 311 loop_header: 312 %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] 313 %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ] 314 br i1 %cond, label %loop_latch, label %loop_exiting 315 316 loop_exiting: 317 %ivy = add i64 %iv, %add 318 switch i64 %sum, label %loop_latch [ 319 i64 24, label %exit1 320 i64 42, label %exit1 321 ] 322 323 loop_latch: 324 %iv_next = add nuw nsw i64 %iv, 1 325 %sum.next = add i64 %sum, %add 326 %cmp = icmp ne i64 %iv_next, %trip 327 br i1 %cmp, label %loop_header, label %latchexit 328 329 exit1: 330 %result = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ] 331 ret i64 %result 332 333 latchexit: 334 ret i64 %sum.next 335 } 336 337 ; test when exit blocks have successors. 338 define i32 @test6(i32* nocapture %a, i64 %n, i1 %cond, i32 %x) { 339 ; EPILOG: test6( 340 ; EPILOG: for.exit2.loopexit: 341 ; EPILOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %latch ], [ 42, %for.exiting_block.1 ], [ %add.1, %latch.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %latch.2 ], 342 ; EPILOG-NEXT: br label %for.exit2 343 ; EPILOG: for.exit2.loopexit2: 344 ; EPILOG-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ] 345 ; EPILOG-NEXT: br label %for.exit2 346 ; EPILOG: for.exit2: 347 ; EPILOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ] 348 ; EPILOG-NEXT: br i1 %cond, label %exit_true, label %exit_false 349 ; EPILOG: latch.7: 350 ; EPILOG: %niter.nsub.7 = add i64 %niter, -8 351 352 ; PROLOG: test6( 353 ; PROLOG: for.exit2.loopexit: 354 ; PROLOG-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %latch ], [ 42, %for.exiting_block.1 ], [ %add.1, %latch.1 ], [ 42, %for.exiting_block.2 ], [ %add.2, %latch.2 ], 355 ; PROLOG-NEXT: br label %for.exit2 356 ; PROLOG: for.exit2.loopexit1: 357 ; PROLOG-NEXT: %retval.ph2 = phi i32 [ 42, %for.exiting_block.prol ], [ %sum.02.prol, %header.prol ] 358 ; PROLOG-NEXT: br label %for.exit2 359 ; PROLOG: for.exit2: 360 ; PROLOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph2, %for.exit2.loopexit1 ] 361 ; PROLOG-NEXT: br i1 %cond, label %exit_true, label %exit_false 362 ; PROLOG: latch.7: 363 ; PROLOG: %indvars.iv.next.7 = add i64 %indvars.iv, 8 364 entry: 365 br label %header 366 367 header: 368 %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] 369 %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] 370 br i1 false, label %for.exit2, label %for.exiting_block 371 372 for.exiting_block: 373 %cmp = icmp eq i64 %n, 42 374 br i1 %cmp, label %for.exit2, label %latch 375 376 latch: 377 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv 378 %load = load i32, i32* %arrayidx, align 4 379 %add = add nsw i32 %load, %sum.02 380 %indvars.iv.next = add i64 %indvars.iv, 1 381 %exitcond = icmp eq i64 %indvars.iv.next, %n 382 br i1 %exitcond, label %latch_exit, label %header 383 384 latch_exit: 385 %sum.0.lcssa = phi i32 [ %add, %latch ] 386 ret i32 %sum.0.lcssa 387 388 for.exit2: 389 %retval = phi i32 [ %sum.02, %header ], [ 42, %for.exiting_block ] 390 %addx = add i32 %retval, %x 391 br i1 %cond, label %exit_true, label %exit_false 392 393 exit_true: 394 ret i32 %retval 395 396 exit_false: 397 ret i32 %addx 398 } 399 400 ; test when value in exit block does not have VMap. 401 define i32 @test7(i32 %arg, i32 %arg1, i32 %arg2) { 402 ; EPILOG-NO-IC: test7( 403 ; EPILOG-NO-IC: loopexit1.loopexit: 404 ; EPILOG-NO-IC-NEXT: %sext3.ph = phi i32 [ %shft, %header ], [ %shft, %latch ], [ %shft, %latch.1 ], [ %shft, %latch.2 ], [ %shft, %latch.3 ], [ %shft, %latch.4 ], [ %shft, %latch.5 ], [ %shft, %latch.6 ] 405 ; EPILOG-NO-IC-NEXT: br label %loopexit1 406 ; EPILOG-NO-IC: loopexit1.loopexit1: 407 ; EPILOG-NO-IC-NEXT: %sext3.ph2 = phi i32 [ %shft, %header.epil ] 408 ; EPILOG-NO-IC-NEXT: br label %loopexit1 409 ; EPILOG-NO-IC: loopexit1: 410 ; EPILOG-NO-IC-NEXT: %sext3 = phi i32 [ %sext3.ph, %loopexit1.loopexit ], [ %sext3.ph2, %loopexit1.loopexit1 ] 411 bb: 412 %tmp = icmp slt i32 undef, 2 413 %sext = sext i32 undef to i64 414 %shft = ashr exact i32 %arg, 16 415 br i1 %tmp, label %loopexit2, label %preheader 416 417 preheader: ; preds = %bb2 418 br label %header 419 420 header: ; preds = %latch, %preheader 421 %tmp6 = phi i64 [ 1, %preheader ], [ %add, %latch ] 422 br i1 false, label %loopexit1, label %latch 423 424 latch: ; preds = %header 425 %add = add nuw nsw i64 %tmp6, 1 426 %tmp9 = icmp slt i64 %add, %sext 427 br i1 %tmp9, label %header, label %latchexit 428 429 latchexit: ; preds = %latch 430 unreachable 431 432 loopexit2: ; preds = %bb2 433 ret i32 %shft 434 435 loopexit1: ; preds = %header 436 %sext3 = phi i32 [ %shft, %header ] 437 ret i32 %sext3 438 } 439 440 ; Nested loop and inner loop is unrolled 441 ; FIXME: we cannot unroll with epilog remainder currently, because 442 ; the outer loop does not contain the epilog preheader and epilog exit (while 443 ; infact it should). This causes us to choke up on LCSSA form being incorrect in 444 ; outer loop. However, the exit block where LCSSA fails, is infact still within 445 ; the outer loop. For now, we just bail out in presence of outer loop and epilog 446 ; loop is generated. 447 ; The outer loop header is the preheader for the inner loop and the inner header 448 ; branches back to the outer loop. 449 define void @test8() { 450 ; EPILOG: test8( 451 ; EPILOG-NOT: niter 452 453 ; PROLOG: test8( 454 ; PROLOG: outerloop: 455 ; PROLOG-NEXT: phi i64 [ 3, %bb ], [ 0, %outerloop.loopexit ] 456 ; PROLOG: %lcmp.mod = icmp eq i64 457 ; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader 458 ; PROLOG: latch.6: 459 ; PROLOG-NEXT: %tmp4.7 = add nsw i64 %tmp3, 8 460 ; PROLOG-NEXT: br i1 false, label %outerloop.loopexit.loopexit, label %latch.7 461 ; PROLOG: latch.7 462 ; PROLOG-NEXT: %tmp6.7 = icmp ult i64 %tmp4.7, 100 463 ; PROLOG-NEXT: br i1 %tmp6.7, label %innerH, label %exit.unr-lcssa 464 bb: 465 br label %outerloop 466 467 outerloop: ; preds = %innerH, %bb 468 %tmp = phi i64 [ 3, %bb ], [ 0, %innerH ] 469 br label %innerH 470 471 innerH: ; preds = %latch, %outerloop 472 %tmp3 = phi i64 [ %tmp4, %latch ], [ %tmp, %outerloop ] 473 %tmp4 = add nuw nsw i64 %tmp3, 1 474 br i1 false, label %outerloop, label %latch 475 476 latch: ; preds = %innerH 477 %tmp6 = icmp ult i64 %tmp4, 100 478 br i1 %tmp6, label %innerH, label %exit 479 480 exit: ; preds = %latch 481 ret void 482 } 483 484 declare i8 addrspace(1)* @foo(i32) 485 ; inner loop prolog unrolled 486 ; a value from outer loop is used in exit block of inner loop. 487 ; Don't create VMap entries for such values (%trip). 488 define i8 addrspace(1)* @test9(i8* nocapture readonly %arg, i32 %n) { 489 ; PROLOG: test9( 490 ; PROLOG: header.prol: 491 ; PROLOG-NEXT: %phi.prol = phi i64 [ 0, %header.prol.preheader ], [ %iv.next.prol, %latch.prol ] 492 ; PROLOG: latch.prol: 493 ; PROLOG-NOT: trip 494 ; PROLOG: br i1 %prol.iter.cmp, label %header.prol.loopexit.unr-lcssa, label %header.prol 495 bb: 496 br label %outerloopHdr 497 498 outerloopHdr: ; preds = %outerLatch, %bb 499 %trip = add i32 %n, -1 500 %outercnd = icmp slt i32 0, %trip 501 br i1 %outercnd, label %preheader, label %outerLatch 502 503 preheader: ; preds = %outerloopHdr 504 %tmp4 = zext i32 0 to i64 505 br label %header 506 507 header: ; preds = %latch, %preheader 508 %phi = phi i64 [ %tmp4, %preheader ], [ %iv.next, %latch ] 509 %tmp7 = trunc i64 %phi to i32 510 br i1 true, label %latch, label %innerexit 511 512 innerexit: ; preds = %header 513 %tmp9 = call i8 addrspace(1)* @foo(i32 %trip) 514 ret i8 addrspace(1)* %tmp9 515 516 latch: ; preds = %header 517 %tmp11 = add nsw i32 %tmp7, 1 518 %innercnd = icmp slt i32 %tmp11, %trip 519 %iv.next = add nuw nsw i64 %phi, 1 520 br i1 %innercnd, label %header, label %outerLatch 521 522 outerLatch: ; preds = %latch, %outerloopHdr 523 br label %outerloopHdr 524 } 525