| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p |
| ; RUN: opt < %s -passes=loop-unroll -unroll-runtime=true -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefixes=CHECK,EPILOG |
| ; RUN: opt < %s -passes=loop-unroll -unroll-runtime -unroll-count=2 -unroll-runtime-epilog=true -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefixes=CHECK,EPILOG-BLOCK |
| ; RUN: opt < %s -passes=loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefixes=CHECK,PROLOG |
| ; RUN: opt < %s -passes=loop-unroll -unroll-runtime -unroll-runtime-epilog=false -unroll-count=2 -unroll-runtime-multi-exit=true -verify-loop-lcssa -verify-dom-info -verify-loop-info -S | FileCheck %s -check-prefixes=CHECK,PROLOG-BLOCK |
| |
| ; REQUIRES: asserts |
| |
| ; test with three exiting and three exit blocks. |
| ; none of the exit blocks have successors |
| define void @test1(i64 %trip, i1 %cond) { |
| ; EPILOG-LABEL: @test1( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %exit2.loopexit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %loop_header |
| ; EPILOG: loop_header: |
| ; EPILOG-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting_bb1 |
| ; EPILOG: loop_exiting_bb1: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch, label %exit3.loopexit |
| ; EPILOG: exit3.loopexit: |
| ; EPILOG-NEXT: br label %exit3 |
| ; EPILOG: exit3.loopexit2: |
| ; EPILOG-NEXT: br label %exit3 |
| ; EPILOG: exit3: |
| ; EPILOG-NEXT: ret void |
| ; EPILOG: loop_latch: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; EPILOG: loop_exiting_bb1.1: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.1, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.1: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.1, label %exit3.loopexit |
| ; EPILOG: loop_latch.1: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.2, label %loop_exiting_bb1.2 |
| ; EPILOG: loop_exiting_bb1.2: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.2, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.2: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.2, label %exit3.loopexit |
| ; EPILOG: loop_latch.2: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.3, label %loop_exiting_bb1.3 |
| ; EPILOG: loop_exiting_bb1.3: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.3, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.3: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.3, label %exit3.loopexit |
| ; EPILOG: loop_latch.3: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.4, label %loop_exiting_bb1.4 |
| ; EPILOG: loop_exiting_bb1.4: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.4, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.4: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.4, label %exit3.loopexit |
| ; EPILOG: loop_latch.4: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.5, label %loop_exiting_bb1.5 |
| ; EPILOG: loop_exiting_bb1.5: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.5, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.5: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.5, label %exit3.loopexit |
| ; EPILOG: loop_latch.5: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.6, label %loop_exiting_bb1.6 |
| ; EPILOG: loop_exiting_bb1.6: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.6, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.6: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.6, label %exit3.loopexit |
| ; EPILOG: loop_latch.6: |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.7, label %loop_exiting_bb1.7 |
| ; EPILOG: loop_exiting_bb1.7: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.7, label %exit1.loopexit |
| ; EPILOG: loop_exiting_bb2.7: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.7, label %exit3.loopexit |
| ; EPILOG: loop_latch.7: |
| ; EPILOG-NEXT: %iv_next.7 = add i64 %iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp ne i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %loop_header, label %exit2.loopexit.unr-lcssa.loopexit |
| ; EPILOG: exit1.loopexit: |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1.loopexit1: |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1: |
| ; EPILOG-NEXT: ret void |
| ; EPILOG: exit2.loopexit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br label %exit2.loopexit.unr-lcssa |
| ; EPILOG: exit2.loopexit.unr-lcssa: |
| ; EPILOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %exit2.loopexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %exit2.loopexit |
| ; EPILOG: loop_header.epil.preheader: |
| ; EPILOG-NEXT: br label %loop_header.epil |
| ; EPILOG: loop_header.epil: |
| ; EPILOG-NEXT: %iv.epil = phi i64 [ %iv.unr, %loop_header.epil.preheader ], [ %iv_next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %loop_header.epil.preheader ], [ %epil.iter.next, %loop_latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.epil, label %loop_exiting_bb1.epil |
| ; EPILOG: loop_exiting_bb1.epil: |
| ; EPILOG-NEXT: br i1 false, label %loop_exiting_bb2.epil, label %exit1.loopexit1 |
| ; EPILOG: loop_exiting_bb2.epil: |
| ; EPILOG-NEXT: br i1 false, label %loop_latch.epil, label %exit3.loopexit2 |
| ; EPILOG: loop_latch.epil: |
| ; EPILOG-NEXT: %iv_next.epil = add i64 %iv.epil, 1 |
| ; EPILOG-NEXT: %cmp.epil = icmp ne i64 %iv_next.epil, %trip |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %loop_header.epil, label %exit2.loopexit.epilog-lcssa, !llvm.loop !0 |
| ; EPILOG: exit2.loopexit.epilog-lcssa: |
| ; EPILOG-NEXT: br label %exit2.loopexit |
| ; EPILOG: exit2.loopexit: |
| ; EPILOG-NEXT: ret void |
| ; |
| ; EPILOG-BLOCK-LABEL: @test1( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %exit2.loopexit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %loop_header |
| ; EPILOG-BLOCK: loop_header: |
| ; EPILOG-BLOCK-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting_bb1 |
| ; EPILOG-BLOCK: loop_exiting_bb1: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2, label %exit1.loopexit |
| ; EPILOG-BLOCK: loop_exiting_bb2: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_latch, label %exit3.loopexit |
| ; EPILOG-BLOCK: exit3.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %exit3 |
| ; EPILOG-BLOCK: exit3: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; EPILOG-BLOCK: loop_latch: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; EPILOG-BLOCK: loop_exiting_bb1.1: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2.1, label %exit1.loopexit |
| ; EPILOG-BLOCK: loop_exiting_bb2.1: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_latch.1, label %exit3.loopexit |
| ; EPILOG-BLOCK: loop_latch.1: |
| ; EPILOG-BLOCK-NEXT: %iv_next.1 = add i64 %iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp ne i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %loop_header, label %exit2.loopexit.unr-lcssa.loopexit, !llvm.loop !0 |
| ; EPILOG-BLOCK: exit1.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %exit1 |
| ; EPILOG-BLOCK: exit1: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; EPILOG-BLOCK: exit2.loopexit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %exit2.loopexit.unr-lcssa |
| ; EPILOG-BLOCK: exit2.loopexit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %exit2.loopexit |
| ; EPILOG-BLOCK: loop_header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %loop_header.epil |
| ; EPILOG-BLOCK: loop_header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.epil, label %loop_exiting_bb1.epil |
| ; EPILOG-BLOCK: loop_exiting_bb1.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2.epil, label %exit1 |
| ; EPILOG-BLOCK: loop_exiting_bb2.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %loop_latch.epil, label %exit3 |
| ; EPILOG-BLOCK: loop_latch.epil: |
| ; EPILOG-BLOCK-NEXT: br label %exit2.loopexit |
| ; EPILOG-BLOCK: exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; |
| ; PROLOG-LABEL: @test1( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.preheader: |
| ; PROLOG-NEXT: br label %loop_header.prol |
| ; PROLOG: loop_header.prol: |
| ; PROLOG-NEXT: %iv.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %loop_header.prol.preheader ], [ %prol.iter.next, %loop_latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting_bb1.prol |
| ; PROLOG: loop_exiting_bb1.prol: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.prol, label %exit1.loopexit1 |
| ; PROLOG: loop_exiting_bb2.prol: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.prol, label %exit3.loopexit2 |
| ; PROLOG: loop_latch.prol: |
| ; PROLOG-NEXT: %iv_next.prol = add i64 %iv.prol, 1 |
| ; PROLOG-NEXT: %cmp.prol = icmp ne i64 %iv_next.prol, %trip |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %loop_header.prol, label %loop_header.prol.loopexit.unr-lcssa, !llvm.loop !0 |
| ; PROLOG: loop_header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.loopexit: |
| ; PROLOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %2, label %exit2.loopexit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %loop_header |
| ; PROLOG: loop_header: |
| ; PROLOG-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting_bb1 |
| ; PROLOG: loop_exiting_bb1: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch, label %exit3.loopexit |
| ; PROLOG: exit3.loopexit: |
| ; PROLOG-NEXT: br label %exit3 |
| ; PROLOG: exit3.loopexit2: |
| ; PROLOG-NEXT: br label %exit3 |
| ; PROLOG: exit3: |
| ; PROLOG-NEXT: ret void |
| ; PROLOG: loop_latch: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; PROLOG: loop_exiting_bb1.1: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.1, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.1: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.1, label %exit3.loopexit |
| ; PROLOG: loop_latch.1: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.2, label %loop_exiting_bb1.2 |
| ; PROLOG: loop_exiting_bb1.2: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.2, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.2: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.2, label %exit3.loopexit |
| ; PROLOG: loop_latch.2: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.3, label %loop_exiting_bb1.3 |
| ; PROLOG: loop_exiting_bb1.3: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.3, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.3: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.3, label %exit3.loopexit |
| ; PROLOG: loop_latch.3: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.4, label %loop_exiting_bb1.4 |
| ; PROLOG: loop_exiting_bb1.4: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.4, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.4: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.4, label %exit3.loopexit |
| ; PROLOG: loop_latch.4: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.5, label %loop_exiting_bb1.5 |
| ; PROLOG: loop_exiting_bb1.5: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.5, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.5: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.5, label %exit3.loopexit |
| ; PROLOG: loop_latch.5: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.6, label %loop_exiting_bb1.6 |
| ; PROLOG: loop_exiting_bb1.6: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.6, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.6: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.6, label %exit3.loopexit |
| ; PROLOG: loop_latch.6: |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.7, label %loop_exiting_bb1.7 |
| ; PROLOG: loop_exiting_bb1.7: |
| ; PROLOG-NEXT: br i1 false, label %loop_exiting_bb2.7, label %exit1.loopexit |
| ; PROLOG: loop_exiting_bb2.7: |
| ; PROLOG-NEXT: br i1 false, label %loop_latch.7, label %exit3.loopexit |
| ; PROLOG: loop_latch.7: |
| ; PROLOG-NEXT: %iv_next.7 = add i64 %iv, 8 |
| ; PROLOG-NEXT: %cmp.7 = icmp ne i64 %iv_next.7, %trip |
| ; PROLOG-NEXT: br i1 %cmp.7, label %loop_header, label %exit2.loopexit.unr-lcssa |
| ; PROLOG: exit1.loopexit: |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1.loopexit1: |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1: |
| ; PROLOG-NEXT: ret void |
| ; PROLOG: exit2.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: br label %exit2.loopexit |
| ; PROLOG: exit2.loopexit: |
| ; PROLOG-NEXT: ret void |
| ; |
| ; PROLOG-BLOCK-LABEL: @test1( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol |
| ; PROLOG-BLOCK: loop_header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting_bb1.prol |
| ; PROLOG-BLOCK: loop_exiting_bb1.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2.prol, label %exit1 |
| ; PROLOG-BLOCK: loop_exiting_bb2.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_latch.prol, label %exit3 |
| ; PROLOG-BLOCK: loop_latch.prol: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ 1, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %2, label %exit2.loopexit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header |
| ; PROLOG-BLOCK: loop_header: |
| ; PROLOG-BLOCK-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting_bb1 |
| ; PROLOG-BLOCK: loop_exiting_bb1: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2, label %exit1.loopexit |
| ; PROLOG-BLOCK: loop_exiting_bb2: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_latch, label %exit3.loopexit |
| ; PROLOG-BLOCK: exit3.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %exit3 |
| ; PROLOG-BLOCK: exit3: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; PROLOG-BLOCK: loop_latch: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; PROLOG-BLOCK: loop_exiting_bb1.1: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_exiting_bb2.1, label %exit1.loopexit |
| ; PROLOG-BLOCK: loop_exiting_bb2.1: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %loop_latch.1, label %exit3.loopexit |
| ; PROLOG-BLOCK: loop_latch.1: |
| ; PROLOG-BLOCK-NEXT: %iv_next.1 = add i64 %iv, 2 |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp ne i64 %iv_next.1, %trip |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %loop_header, label %exit2.loopexit.unr-lcssa, !llvm.loop !0 |
| ; PROLOG-BLOCK: exit1.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %exit1 |
| ; PROLOG-BLOCK: exit1: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; PROLOG-BLOCK: exit2.loopexit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: br label %exit2.loopexit |
| ; PROLOG-BLOCK: exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; |
| |
| entry: |
| br label %loop_header |
| |
| loop_header: |
| %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] |
| br i1 %cond, label %loop_latch, label %loop_exiting_bb1 |
| |
| loop_exiting_bb1: |
| br i1 false, label %loop_exiting_bb2, label %exit1 |
| |
| loop_exiting_bb2: |
| br i1 false, label %loop_latch, label %exit3 |
| |
| exit3: |
| ret void |
| |
| loop_latch: |
| %iv_next = add i64 %iv, 1 |
| %cmp = icmp ne i64 %iv_next, %trip |
| br i1 %cmp, label %loop_header, label %exit2.loopexit |
| |
| exit1: |
| ret void |
| |
| exit2.loopexit: |
| ret void |
| } |
| |
| |
| ; test with three exiting and two exit blocks. |
| ; The non-latch exit block has 2 unique predecessors. |
| ; There are 2 values passed to the exit blocks that are calculated at every iteration. |
| ; %sum.02 and %add. Both of these are incoming values for phi from every exiting |
| ; unrolled block. |
| define i32 @test2(ptr nocapture %a, i64 %n) { |
| ; EPILOG-LABEL: @test2( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %n |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %for.end.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.7, %for.body.7 ] |
| ; EPILOG-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.7, %for.body.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %for.body.7 ] |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG: for.exiting_block: |
| ; EPILOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %for.body |
| ; EPILOG: for.body: |
| ; EPILOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG: for.exiting_block.1: |
| ; EPILOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %for.body.1 |
| ; EPILOG: for.body.1: |
| ; EPILOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-NEXT: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; EPILOG: for.exiting_block.2: |
| ; EPILOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.2, label %for.exit2.loopexit, label %for.body.2 |
| ; EPILOG: for.body.2: |
| ; EPILOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; EPILOG-NEXT: %5 = load i32, ptr %arrayidx.2, align 4 |
| ; EPILOG-NEXT: %add.2 = add nsw i32 %5, %add.1 |
| ; EPILOG-NEXT: %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; EPILOG: for.exiting_block.3: |
| ; EPILOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.3, label %for.exit2.loopexit, label %for.body.3 |
| ; EPILOG: for.body.3: |
| ; EPILOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; EPILOG-NEXT: %6 = load i32, ptr %arrayidx.3, align 4 |
| ; EPILOG-NEXT: %add.3 = add nsw i32 %6, %add.2 |
| ; EPILOG-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; EPILOG: for.exiting_block.4: |
| ; EPILOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.4, label %for.exit2.loopexit, label %for.body.4 |
| ; EPILOG: for.body.4: |
| ; EPILOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; EPILOG-NEXT: %7 = load i32, ptr %arrayidx.4, align 4 |
| ; EPILOG-NEXT: %add.4 = add nsw i32 %7, %add.3 |
| ; EPILOG-NEXT: %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; EPILOG: for.exiting_block.5: |
| ; EPILOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.5, label %for.exit2.loopexit, label %for.body.5 |
| ; EPILOG: for.body.5: |
| ; EPILOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; EPILOG-NEXT: %8 = load i32, ptr %arrayidx.5, align 4 |
| ; EPILOG-NEXT: %add.5 = add nsw i32 %8, %add.4 |
| ; EPILOG-NEXT: %indvars.iv.next.5 = add nuw nsw i64 %indvars.iv, 6 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; EPILOG: for.exiting_block.6: |
| ; EPILOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.6, label %for.exit2.loopexit, label %for.body.6 |
| ; EPILOG: for.body.6: |
| ; EPILOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; EPILOG-NEXT: %9 = load i32, ptr %arrayidx.6, align 4 |
| ; EPILOG-NEXT: %add.6 = add nsw i32 %9, %add.5 |
| ; EPILOG-NEXT: %indvars.iv.next.6 = add nuw nsw i64 %indvars.iv, 7 |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; EPILOG: for.exiting_block.7: |
| ; EPILOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.7, label %for.exit2.loopexit, label %for.body.7 |
| ; EPILOG: for.body.7: |
| ; EPILOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; EPILOG-NEXT: %10 = load i32, ptr %arrayidx.7, align 4 |
| ; EPILOG-NEXT: %add.7 = add nsw i32 %10, %add.6 |
| ; EPILOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %for.end.unr-lcssa.loopexit, label %header |
| ; EPILOG: for.end.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %sum.0.lcssa.ph.ph = phi i32 [ %add.7, %for.body.7 ] |
| ; EPILOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.7, %for.body.7 ] |
| ; EPILOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.7, %for.body.7 ] |
| ; EPILOG-NEXT: br label %for.end.unr-lcssa |
| ; EPILOG: for.end.unr-lcssa: |
| ; EPILOG-NEXT: %sum.0.lcssa.ph = phi i32 [ undef, %entry ], [ %sum.0.lcssa.ph.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %for.end |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %for.body.epil ], [ %indvars.iv.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %sum.02.epil = phi i32 [ %add.epil, %for.body.epil ], [ %sum.02.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %header.epil.preheader ], [ %epil.iter.next, %for.body.epil ] |
| ; EPILOG-NEXT: br i1 false, label %for.exit2.loopexit2, label %for.exiting_block.epil |
| ; EPILOG: for.exiting_block.epil: |
| ; EPILOG-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.epil, label %for.exit2.loopexit2, label %for.body.epil |
| ; EPILOG: for.body.epil: |
| ; EPILOG-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.epil |
| ; EPILOG-NEXT: %11 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-NEXT: %add.epil = add nsw i32 %11, %sum.02.epil |
| ; EPILOG-NEXT: %indvars.iv.next.epil = add i64 %indvars.iv.epil, 1 |
| ; EPILOG-NEXT: %exitcond.epil = icmp eq i64 %indvars.iv.next.epil, %n |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %for.end.epilog-lcssa, !llvm.loop !2 |
| ; EPILOG: for.end.epilog-lcssa: |
| ; EPILOG-NEXT: %sum.0.lcssa.ph1 = phi i32 [ %add.epil, %for.body.epil ] |
| ; EPILOG-NEXT: br label %for.end |
| ; EPILOG: for.end: |
| ; EPILOG-NEXT: %sum.0.lcssa = phi i32 [ %sum.0.lcssa.ph, %for.end.unr-lcssa ], [ %sum.0.lcssa.ph1, %for.end.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i32 %sum.0.lcssa |
| ; EPILOG: for.exit2.loopexit: |
| ; 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 ], [ %add.3, %for.body.3 ], [ 42, %for.exiting_block.4 ], [ %add.4, %for.body.4 ], [ 42, %for.exiting_block.5 ], [ %add.5, %for.body.5 ], [ 42, %for.exiting_block.6 ], [ %add.6, %for.body.6 ], [ 42, %for.exiting_block.7 ] |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2.loopexit2: |
| ; EPILOG-NEXT: %retval.ph3 = phi i32 [ 42, %for.exiting_block.epil ], [ %sum.02.epil, %header.epil ] |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2: |
| ; EPILOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph3, %for.exit2.loopexit2 ] |
| ; EPILOG-NEXT: ret i32 %retval |
| ; |
| ; EPILOG-BLOCK-LABEL: @test2( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %for.end.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG-BLOCK: for.exiting_block: |
| ; EPILOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %for.body |
| ; EPILOG-BLOCK: for.body: |
| ; EPILOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-BLOCK-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-BLOCK-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG-BLOCK: for.exiting_block.1: |
| ; EPILOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %for.body.1 |
| ; EPILOG-BLOCK: for.body.1: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %for.end.unr-lcssa.loopexit, label %header, !llvm.loop !2 |
| ; EPILOG-BLOCK: for.end.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %sum.0.lcssa.ph.ph = phi i32 [ %add.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr.ph = phi i32 [ %add.1, %for.body.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %for.end.unr-lcssa |
| ; EPILOG-BLOCK: for.end.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %sum.0.lcssa.ph = phi i32 [ undef, %entry ], [ %sum.0.lcssa.ph.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %for.end.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %for.end |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 false, label %for.exit2, label %for.exiting_block.epil |
| ; EPILOG-BLOCK: for.exiting_block.epil: |
| ; EPILOG-BLOCK-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.epil, label %for.exit2, label %for.body.epil |
| ; EPILOG-BLOCK: for.body.epil: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.unr |
| ; EPILOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.epil = add nsw i32 %5, %sum.02.unr |
| ; EPILOG-BLOCK-NEXT: br label %for.end |
| ; EPILOG-BLOCK: for.end: |
| ; EPILOG-BLOCK-NEXT: %sum.0.lcssa = phi i32 [ %sum.0.lcssa.ph, %for.end.unr-lcssa ], [ %add.epil, %for.body.epil ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %sum.0.lcssa |
| ; EPILOG-BLOCK: for.exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %for.exit2 |
| ; EPILOG-BLOCK: for.exit2: |
| ; EPILOG-BLOCK-NEXT: %retval = phi i32 [ %sum.02.unr, %header.epil ], [ 42, %for.exiting_block.epil ], [ %retval.ph, %for.exit2.loopexit ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %retval |
| ; |
| ; PROLOG-LABEL: @test2( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %n |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %for.body.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %sum.02.prol = phi i32 [ %add.prol, %for.body.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %header.prol.preheader ], [ %prol.iter.next, %for.body.prol ] |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit1, label %for.exiting_block.prol |
| ; PROLOG: for.exiting_block.prol: |
| ; PROLOG-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.prol, label %for.exit2.loopexit1, label %for.body.prol |
| ; PROLOG: for.body.prol: |
| ; PROLOG-NEXT: %arrayidx.prol = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.prol |
| ; PROLOG-NEXT: %2 = load i32, ptr %arrayidx.prol, align 4 |
| ; PROLOG-NEXT: %add.prol = add nsw i32 %2, %sum.02.prol |
| ; PROLOG-NEXT: %indvars.iv.next.prol = add i64 %indvars.iv.prol, 1 |
| ; PROLOG-NEXT: %exitcond.prol = icmp eq i64 %indvars.iv.next.prol, %n |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !2 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %sum.0.lcssa.unr.ph = phi i32 [ %add.prol, %for.body.prol ] |
| ; PROLOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %for.body.prol ] |
| ; PROLOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.prol, %for.body.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %sum.0.lcssa.unr = phi i32 [ undef, %entry ], [ %sum.0.lcssa.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %3 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %3, label %for.end, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.7, %for.body.7 ] |
| ; PROLOG-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.7, %for.body.7 ] |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG: for.exiting_block: |
| ; PROLOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %for.body |
| ; PROLOG: for.body: |
| ; PROLOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG: for.exiting_block.1: |
| ; PROLOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %for.body.1 |
| ; PROLOG: for.body.1: |
| ; PROLOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; PROLOG: for.exiting_block.2: |
| ; PROLOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.2, label %for.exit2.loopexit, label %for.body.2 |
| ; PROLOG: for.body.2: |
| ; PROLOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; PROLOG-NEXT: %6 = load i32, ptr %arrayidx.2, align 4 |
| ; PROLOG-NEXT: %add.2 = add nsw i32 %6, %add.1 |
| ; PROLOG-NEXT: %indvars.iv.next.2 = add i64 %indvars.iv, 3 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; PROLOG: for.exiting_block.3: |
| ; PROLOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.3, label %for.exit2.loopexit, label %for.body.3 |
| ; PROLOG: for.body.3: |
| ; PROLOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; PROLOG-NEXT: %7 = load i32, ptr %arrayidx.3, align 4 |
| ; PROLOG-NEXT: %add.3 = add nsw i32 %7, %add.2 |
| ; PROLOG-NEXT: %indvars.iv.next.3 = add i64 %indvars.iv, 4 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; PROLOG: for.exiting_block.4: |
| ; PROLOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.4, label %for.exit2.loopexit, label %for.body.4 |
| ; PROLOG: for.body.4: |
| ; PROLOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; PROLOG-NEXT: %8 = load i32, ptr %arrayidx.4, align 4 |
| ; PROLOG-NEXT: %add.4 = add nsw i32 %8, %add.3 |
| ; PROLOG-NEXT: %indvars.iv.next.4 = add i64 %indvars.iv, 5 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; PROLOG: for.exiting_block.5: |
| ; PROLOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.5, label %for.exit2.loopexit, label %for.body.5 |
| ; PROLOG: for.body.5: |
| ; PROLOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; PROLOG-NEXT: %9 = load i32, ptr %arrayidx.5, align 4 |
| ; PROLOG-NEXT: %add.5 = add nsw i32 %9, %add.4 |
| ; PROLOG-NEXT: %indvars.iv.next.5 = add i64 %indvars.iv, 6 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; PROLOG: for.exiting_block.6: |
| ; PROLOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.6, label %for.exit2.loopexit, label %for.body.6 |
| ; PROLOG: for.body.6: |
| ; PROLOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; PROLOG-NEXT: %10 = load i32, ptr %arrayidx.6, align 4 |
| ; PROLOG-NEXT: %add.6 = add nsw i32 %10, %add.5 |
| ; PROLOG-NEXT: %indvars.iv.next.6 = add i64 %indvars.iv, 7 |
| ; PROLOG-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; PROLOG: for.exiting_block.7: |
| ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.7, label %for.exit2.loopexit, label %for.body.7 |
| ; PROLOG: for.body.7: |
| ; PROLOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; PROLOG-NEXT: %11 = load i32, ptr %arrayidx.7, align 4 |
| ; PROLOG-NEXT: %add.7 = add nsw i32 %11, %add.6 |
| ; PROLOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; PROLOG-NEXT: %exitcond.7 = icmp eq i64 %indvars.iv.next.7, %n |
| ; PROLOG-NEXT: br i1 %exitcond.7, label %for.end.unr-lcssa, label %header |
| ; PROLOG: for.end.unr-lcssa: |
| ; PROLOG-NEXT: %sum.0.lcssa.ph = phi i32 [ %add.7, %for.body.7 ] |
| ; PROLOG-NEXT: br label %for.end |
| ; PROLOG: for.end: |
| ; PROLOG-NEXT: %sum.0.lcssa = phi i32 [ %sum.0.lcssa.unr, %header.prol.loopexit ], [ %sum.0.lcssa.ph, %for.end.unr-lcssa ] |
| ; PROLOG-NEXT: ret i32 %sum.0.lcssa |
| ; PROLOG: for.exit2.loopexit: |
| ; 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 ], [ %add.3, %for.body.3 ], [ 42, %for.exiting_block.4 ], [ %add.4, %for.body.4 ], [ 42, %for.exiting_block.5 ], [ %add.5, %for.body.5 ], [ 42, %for.exiting_block.6 ], [ %add.6, %for.body.6 ], [ 42, %for.exiting_block.7 ] |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2.loopexit1: |
| ; PROLOG-NEXT: %retval.ph2 = phi i32 [ 42, %for.exiting_block.prol ], [ %sum.02.prol, %header.prol ] |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2: |
| ; PROLOG-NEXT: %retval = phi i32 [ %retval.ph, %for.exit2.loopexit ], [ %retval.ph2, %for.exit2.loopexit1 ] |
| ; PROLOG-NEXT: ret i32 %retval |
| ; |
| ; PROLOG-BLOCK-LABEL: @test2( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %for.exit2, label %for.exiting_block.prol |
| ; PROLOG-BLOCK: for.exiting_block.prol: |
| ; PROLOG-BLOCK-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.prol, label %for.exit2, label %for.body.prol |
| ; PROLOG-BLOCK: for.body.prol: |
| ; PROLOG-BLOCK-NEXT: %2 = load i32, ptr %a, align 4 |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %sum.0.lcssa.unr = phi i32 [ undef, %entry ], [ %2, %for.body.prol ] |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ 1, %for.body.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %2, %for.body.prol ] |
| ; PROLOG-BLOCK-NEXT: %3 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %3, label %for.end, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.1, %for.body.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.1, %for.body.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG-BLOCK: for.exiting_block: |
| ; PROLOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %for.body |
| ; PROLOG-BLOCK: for.body: |
| ; PROLOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-BLOCK-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 false, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG-BLOCK: for.exiting_block.1: |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %for.body.1 |
| ; PROLOG-BLOCK: for.body.1: |
| ; PROLOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-BLOCK-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-BLOCK-NEXT: %exitcond.1 = icmp eq i64 %indvars.iv.next.1, %n |
| ; PROLOG-BLOCK-NEXT: br i1 %exitcond.1, label %for.end.unr-lcssa, label %header, !llvm.loop !2 |
| ; PROLOG-BLOCK: for.end.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %sum.0.lcssa.ph = phi i32 [ %add.1, %for.body.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %for.end |
| ; PROLOG-BLOCK: for.end: |
| ; PROLOG-BLOCK-NEXT: %sum.0.lcssa = phi i32 [ %sum.0.lcssa.unr, %header.prol.loopexit ], [ %sum.0.lcssa.ph, %for.end.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %sum.0.lcssa |
| ; PROLOG-BLOCK: for.exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: %retval.ph = phi i32 [ 42, %for.exiting_block ], [ %sum.02, %header ], [ %add, %for.body ], [ 42, %for.exiting_block.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %for.exit2 |
| ; PROLOG-BLOCK: for.exit2: |
| ; PROLOG-BLOCK-NEXT: %retval = phi i32 [ 0, %header.prol ], [ 42, %for.exiting_block.prol ], [ %retval.ph, %for.exit2.loopexit ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %retval |
| ; |
| |
| |
| entry: |
| br label %header |
| |
| header: |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] |
| %sum.02 = phi i32 [ %add, %for.body ], [ 0, %entry ] |
| br i1 false, label %for.exit2, label %for.exiting_block |
| |
| for.exiting_block: |
| %cmp = icmp eq i64 %n, 42 |
| br i1 %cmp, label %for.exit2, label %for.body |
| |
| for.body: |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| %0 = load i32, ptr %arrayidx, align 4 |
| %add = add nsw i32 %0, %sum.02 |
| %indvars.iv.next = add i64 %indvars.iv, 1 |
| %exitcond = icmp eq i64 %indvars.iv.next, %n |
| br i1 %exitcond, label %for.end, label %header |
| |
| for.end: ; preds = %for.body |
| %sum.0.lcssa = phi i32 [ %add, %for.body ] |
| ret i32 %sum.0.lcssa |
| |
| for.exit2: |
| %retval = phi i32 [ %sum.02, %header ], [ 42, %for.exiting_block ] |
| ret i32 %retval |
| } |
| |
| ; test with two exiting and three exit blocks. |
| ; the non-latch exiting block has a switch. |
| define void @test3(i64 %trip, i64 %add) { |
| ; EPILOG-LABEL: @test3( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %exit2.loopexit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %loop_header |
| ; EPILOG: loop_header: |
| ; EPILOG-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch, label %loop_exiting_bb1 |
| ; EPILOG: loop_exiting_bb1: |
| ; EPILOG-NEXT: switch i64 %sum, label %loop_latch [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: exit3.loopexit: |
| ; EPILOG-NEXT: br label %exit3 |
| ; EPILOG: exit3.loopexit2: |
| ; EPILOG-NEXT: br label %exit3 |
| ; EPILOG: exit3: |
| ; EPILOG-NEXT: ret void |
| ; EPILOG: loop_latch: |
| ; EPILOG-NEXT: %sum.next = add i64 %sum, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; EPILOG: loop_exiting_bb1.1: |
| ; EPILOG-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.1: |
| ; EPILOG-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.2, label %loop_exiting_bb1.2 |
| ; EPILOG: loop_exiting_bb1.2: |
| ; EPILOG-NEXT: switch i64 %sum.next.1, label %loop_latch.2 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.2: |
| ; EPILOG-NEXT: %sum.next.2 = add i64 %sum.next.1, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.3, label %loop_exiting_bb1.3 |
| ; EPILOG: loop_exiting_bb1.3: |
| ; EPILOG-NEXT: switch i64 %sum.next.2, label %loop_latch.3 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.3: |
| ; EPILOG-NEXT: %sum.next.3 = add i64 %sum.next.2, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.4, label %loop_exiting_bb1.4 |
| ; EPILOG: loop_exiting_bb1.4: |
| ; EPILOG-NEXT: switch i64 %sum.next.3, label %loop_latch.4 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.4: |
| ; EPILOG-NEXT: %sum.next.4 = add i64 %sum.next.3, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.5, label %loop_exiting_bb1.5 |
| ; EPILOG: loop_exiting_bb1.5: |
| ; EPILOG-NEXT: switch i64 %sum.next.4, label %loop_latch.5 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.5: |
| ; EPILOG-NEXT: %sum.next.5 = add i64 %sum.next.4, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.6, label %loop_exiting_bb1.6 |
| ; EPILOG: loop_exiting_bb1.6: |
| ; EPILOG-NEXT: switch i64 %sum.next.5, label %loop_latch.6 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.6: |
| ; EPILOG-NEXT: %sum.next.6 = add i64 %sum.next.5, %add |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.7, label %loop_exiting_bb1.7 |
| ; EPILOG: loop_exiting_bb1.7: |
| ; EPILOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.7: |
| ; EPILOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 |
| ; EPILOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp ne i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %loop_header, label %exit2.loopexit.unr-lcssa.loopexit |
| ; EPILOG: exit1.loopexit: |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1.loopexit1: |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1: |
| ; EPILOG-NEXT: ret void |
| ; EPILOG: exit2.loopexit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %sum.unr.ph = phi i64 [ %sum.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br label %exit2.loopexit.unr-lcssa |
| ; EPILOG: exit2.loopexit.unr-lcssa: |
| ; EPILOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %exit2.loopexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %exit2.loopexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %exit2.loopexit |
| ; EPILOG: loop_header.epil.preheader: |
| ; EPILOG-NEXT: br label %loop_header.epil |
| ; EPILOG: loop_header.epil: |
| ; EPILOG-NEXT: %iv.epil = phi i64 [ %iv.unr, %loop_header.epil.preheader ], [ %iv_next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: %sum.epil = phi i64 [ %sum.unr, %loop_header.epil.preheader ], [ %sum.next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %loop_header.epil.preheader ], [ %epil.iter.next, %loop_latch.epil ] |
| ; EPILOG-NEXT: br i1 undef, label %loop_latch.epil, label %loop_exiting_bb1.epil |
| ; EPILOG: loop_exiting_bb1.epil: |
| ; EPILOG-NEXT: switch i64 %sum.epil, label %loop_latch.epil [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit1 |
| ; EPILOG-NEXT: i64 42, label %exit3.loopexit2 |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.epil: |
| ; EPILOG-NEXT: %iv_next.epil = add nuw nsw i64 %iv.epil, 1 |
| ; EPILOG-NEXT: %sum.next.epil = add i64 %sum.epil, %add |
| ; EPILOG-NEXT: %cmp.epil = icmp ne i64 %iv_next.epil, %trip |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %loop_header.epil, label %exit2.loopexit.epilog-lcssa, !llvm.loop !3 |
| ; EPILOG: exit2.loopexit.epilog-lcssa: |
| ; EPILOG-NEXT: br label %exit2.loopexit |
| ; EPILOG: exit2.loopexit: |
| ; EPILOG-NEXT: ret void |
| ; |
| ; EPILOG-BLOCK-LABEL: @test3( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %exit2.loopexit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %loop_header |
| ; EPILOG-BLOCK: loop_header: |
| ; EPILOG-BLOCK-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 undef, label %loop_latch, label %loop_exiting_bb1 |
| ; EPILOG-BLOCK: loop_exiting_bb1: |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum, label %loop_latch [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: exit3.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %exit3 |
| ; EPILOG-BLOCK: exit3: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; EPILOG-BLOCK: loop_latch: |
| ; EPILOG-BLOCK-NEXT: %sum.next = add i64 %sum, %add |
| ; EPILOG-BLOCK-NEXT: br i1 undef, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; EPILOG-BLOCK: loop_exiting_bb1.1: |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit3.loopexit |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: loop_latch.1: |
| ; EPILOG-BLOCK-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; EPILOG-BLOCK-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp ne i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %loop_header, label %exit2.loopexit.unr-lcssa.loopexit, !llvm.loop !3 |
| ; EPILOG-BLOCK: exit1.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %exit1 |
| ; EPILOG-BLOCK: exit1: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; EPILOG-BLOCK: exit2.loopexit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %sum.unr.ph = phi i64 [ %sum.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %exit2.loopexit.unr-lcssa |
| ; EPILOG-BLOCK: exit2.loopexit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %exit2.loopexit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %exit2.loopexit |
| ; EPILOG-BLOCK: loop_header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %loop_header.epil |
| ; EPILOG-BLOCK: loop_header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 undef, label %loop_latch.epil, label %loop_exiting_bb1.epil |
| ; EPILOG-BLOCK: loop_exiting_bb1.epil: |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum.unr, label %loop_latch.epil [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1 |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit3 |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: loop_latch.epil: |
| ; EPILOG-BLOCK-NEXT: br label %exit2.loopexit |
| ; EPILOG-BLOCK: exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; |
| ; PROLOG-LABEL: @test3( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.preheader: |
| ; PROLOG-NEXT: br label %loop_header.prol |
| ; PROLOG: loop_header.prol: |
| ; PROLOG-NEXT: %iv.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %sum.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %sum.next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %loop_header.prol.preheader ], [ %prol.iter.next, %loop_latch.prol ] |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.prol, label %loop_exiting_bb1.prol |
| ; PROLOG: loop_exiting_bb1.prol: |
| ; PROLOG-NEXT: switch i64 %sum.prol, label %loop_latch.prol [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit1 |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit2 |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.prol: |
| ; PROLOG-NEXT: %iv_next.prol = add nuw nsw i64 %iv.prol, 1 |
| ; PROLOG-NEXT: %sum.next.prol = add i64 %sum.prol, %add |
| ; PROLOG-NEXT: %cmp.prol = icmp ne i64 %iv_next.prol, %trip |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %loop_header.prol, label %loop_header.prol.loopexit.unr-lcssa, !llvm.loop !3 |
| ; PROLOG: loop_header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %sum.unr.ph = phi i64 [ %sum.next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.loopexit: |
| ; PROLOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %2, label %exit2.loopexit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %loop_header |
| ; PROLOG: loop_header: |
| ; PROLOG-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch, label %loop_exiting_bb1 |
| ; PROLOG: loop_exiting_bb1: |
| ; PROLOG-NEXT: switch i64 %sum, label %loop_latch [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: exit3.loopexit: |
| ; PROLOG-NEXT: br label %exit3 |
| ; PROLOG: exit3.loopexit2: |
| ; PROLOG-NEXT: br label %exit3 |
| ; PROLOG: exit3: |
| ; PROLOG-NEXT: ret void |
| ; PROLOG: loop_latch: |
| ; PROLOG-NEXT: %sum.next = add i64 %sum, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; PROLOG: loop_exiting_bb1.1: |
| ; PROLOG-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.1: |
| ; PROLOG-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.2, label %loop_exiting_bb1.2 |
| ; PROLOG: loop_exiting_bb1.2: |
| ; PROLOG-NEXT: switch i64 %sum.next.1, label %loop_latch.2 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.2: |
| ; PROLOG-NEXT: %sum.next.2 = add i64 %sum.next.1, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.3, label %loop_exiting_bb1.3 |
| ; PROLOG: loop_exiting_bb1.3: |
| ; PROLOG-NEXT: switch i64 %sum.next.2, label %loop_latch.3 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.3: |
| ; PROLOG-NEXT: %sum.next.3 = add i64 %sum.next.2, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.4, label %loop_exiting_bb1.4 |
| ; PROLOG: loop_exiting_bb1.4: |
| ; PROLOG-NEXT: switch i64 %sum.next.3, label %loop_latch.4 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.4: |
| ; PROLOG-NEXT: %sum.next.4 = add i64 %sum.next.3, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.5, label %loop_exiting_bb1.5 |
| ; PROLOG: loop_exiting_bb1.5: |
| ; PROLOG-NEXT: switch i64 %sum.next.4, label %loop_latch.5 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.5: |
| ; PROLOG-NEXT: %sum.next.5 = add i64 %sum.next.4, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.6, label %loop_exiting_bb1.6 |
| ; PROLOG: loop_exiting_bb1.6: |
| ; PROLOG-NEXT: switch i64 %sum.next.5, label %loop_latch.6 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.6: |
| ; PROLOG-NEXT: %sum.next.6 = add i64 %sum.next.5, %add |
| ; PROLOG-NEXT: br i1 undef, label %loop_latch.7, label %loop_exiting_bb1.7 |
| ; PROLOG: loop_exiting_bb1.7: |
| ; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.7: |
| ; PROLOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 |
| ; PROLOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add |
| ; PROLOG-NEXT: %cmp.7 = icmp ne i64 %iv_next.7, %trip |
| ; PROLOG-NEXT: br i1 %cmp.7, label %loop_header, label %exit2.loopexit.unr-lcssa |
| ; PROLOG: exit1.loopexit: |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1.loopexit1: |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1: |
| ; PROLOG-NEXT: ret void |
| ; PROLOG: exit2.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: br label %exit2.loopexit |
| ; PROLOG: exit2.loopexit: |
| ; PROLOG-NEXT: ret void |
| ; |
| ; PROLOG-BLOCK-LABEL: @test3( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol |
| ; PROLOG-BLOCK: loop_header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 undef, label %loop_latch.prol, label %loop_exiting_bb1.prol |
| ; PROLOG-BLOCK: loop_exiting_bb1.prol: |
| ; PROLOG-BLOCK-NEXT: switch i64 0, label %loop_latch.prol [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1 |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit3 |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: loop_latch.prol: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ 1, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %add, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %2, label %exit2.loopexit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header |
| ; PROLOG-BLOCK: loop_header: |
| ; PROLOG-BLOCK-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 undef, label %loop_latch, label %loop_exiting_bb1 |
| ; PROLOG-BLOCK: loop_exiting_bb1: |
| ; PROLOG-BLOCK-NEXT: switch i64 %sum, label %loop_latch [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: exit3.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %exit3 |
| ; PROLOG-BLOCK: exit3: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; PROLOG-BLOCK: loop_latch: |
| ; PROLOG-BLOCK-NEXT: %sum.next = add i64 %sum, %add |
| ; PROLOG-BLOCK-NEXT: br i1 undef, label %loop_latch.1, label %loop_exiting_bb1.1 |
| ; PROLOG-BLOCK: loop_exiting_bb1.1: |
| ; PROLOG-BLOCK-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit3.loopexit |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: loop_latch.1: |
| ; PROLOG-BLOCK-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; PROLOG-BLOCK-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp ne i64 %iv_next.1, %trip |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %loop_header, label %exit2.loopexit.unr-lcssa, !llvm.loop !3 |
| ; PROLOG-BLOCK: exit1.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %exit1 |
| ; PROLOG-BLOCK: exit1: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; PROLOG-BLOCK: exit2.loopexit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: br label %exit2.loopexit |
| ; PROLOG-BLOCK: exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; |
| |
| entry: |
| br label %loop_header |
| |
| loop_header: |
| %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] |
| %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ] |
| br i1 undef, label %loop_latch, label %loop_exiting_bb1 |
| |
| loop_exiting_bb1: |
| switch i64 %sum, label %loop_latch [ |
| i64 24, label %exit1 |
| i64 42, label %exit3 |
| ] |
| |
| exit3: |
| ret void |
| |
| loop_latch: |
| %iv_next = add nuw nsw i64 %iv, 1 |
| %sum.next = add i64 %sum, %add |
| %cmp = icmp ne i64 %iv_next, %trip |
| br i1 %cmp, label %loop_header, label %exit2.loopexit |
| |
| exit1: |
| ret void |
| |
| exit2.loopexit: |
| ret void |
| } |
| |
| ; FIXME: Support multiple exiting blocks to the same latch exit block. |
| ; Three exiting blocks where header and latch exit to same LatchExit. |
| define i32 @hdr_latch_same_exit(ptr nocapture %a, i64 %n, i1 %cond) { |
| ; EPILOG-LABEL: @hdr_latch_same_exit( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %n |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block |
| ; EPILOG: for.exiting_block: |
| ; EPILOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %latch |
| ; EPILOG: latch: |
| ; EPILOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.1 |
| ; EPILOG: for.exiting_block.1: |
| ; EPILOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %latch.1 |
| ; EPILOG: latch.1: |
| ; EPILOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-NEXT: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.2 |
| ; EPILOG: for.exiting_block.2: |
| ; EPILOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.2, label %for.exit2.loopexit, label %latch.2 |
| ; EPILOG: latch.2: |
| ; EPILOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; EPILOG-NEXT: %5 = load i32, ptr %arrayidx.2, align 4 |
| ; EPILOG-NEXT: %add.2 = add nsw i32 %5, %add.1 |
| ; EPILOG-NEXT: %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.3 |
| ; EPILOG: for.exiting_block.3: |
| ; EPILOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.3, label %for.exit2.loopexit, label %latch.3 |
| ; EPILOG: latch.3: |
| ; EPILOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; EPILOG-NEXT: %6 = load i32, ptr %arrayidx.3, align 4 |
| ; EPILOG-NEXT: %add.3 = add nsw i32 %6, %add.2 |
| ; EPILOG-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.4 |
| ; EPILOG: for.exiting_block.4: |
| ; EPILOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.4, label %for.exit2.loopexit, label %latch.4 |
| ; EPILOG: latch.4: |
| ; EPILOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; EPILOG-NEXT: %7 = load i32, ptr %arrayidx.4, align 4 |
| ; EPILOG-NEXT: %add.4 = add nsw i32 %7, %add.3 |
| ; EPILOG-NEXT: %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.5 |
| ; EPILOG: for.exiting_block.5: |
| ; EPILOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.5, label %for.exit2.loopexit, label %latch.5 |
| ; EPILOG: latch.5: |
| ; EPILOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; EPILOG-NEXT: %8 = load i32, ptr %arrayidx.5, align 4 |
| ; EPILOG-NEXT: %add.5 = add nsw i32 %8, %add.4 |
| ; EPILOG-NEXT: %indvars.iv.next.5 = add nuw nsw i64 %indvars.iv, 6 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.6 |
| ; EPILOG: for.exiting_block.6: |
| ; EPILOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.6, label %for.exit2.loopexit, label %latch.6 |
| ; EPILOG: latch.6: |
| ; EPILOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; EPILOG-NEXT: %9 = load i32, ptr %arrayidx.6, align 4 |
| ; EPILOG-NEXT: %add.6 = add nsw i32 %9, %add.5 |
| ; EPILOG-NEXT: %indvars.iv.next.6 = add nuw nsw i64 %indvars.iv, 7 |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.7 |
| ; EPILOG: for.exiting_block.7: |
| ; EPILOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.7, label %for.exit2.loopexit, label %latch.7 |
| ; EPILOG: latch.7: |
| ; EPILOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; EPILOG-NEXT: %10 = load i32, ptr %arrayidx.7, align 4 |
| ; EPILOG-NEXT: %add.7 = add nsw i32 %10, %add.6 |
| ; EPILOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; EPILOG: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG: latchExit.unr-lcssa: |
| ; EPILOG-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %latch.epil ], [ %indvars.iv.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %sum.02.epil = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %header.epil.preheader ], [ %epil.iter.next, %latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit2, label %for.exiting_block.epil |
| ; EPILOG: for.exiting_block.epil: |
| ; EPILOG-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.epil, label %for.exit2.loopexit4, label %latch.epil |
| ; EPILOG: latch.epil: |
| ; EPILOG-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.epil |
| ; EPILOG-NEXT: %11 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-NEXT: %add.epil = add nsw i32 %11, %sum.02.epil |
| ; EPILOG-NEXT: %indvars.iv.next.epil = add i64 %indvars.iv.epil, 1 |
| ; EPILOG-NEXT: %exitcond.epil = icmp eq i64 %indvars.iv.next.epil, %n |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %latchExit.epilog-lcssa.loopexit2, !llvm.loop !4 |
| ; EPILOG: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph1.ph = phi i32 [ 0, %header ], [ 0, %latch ], [ 0, %latch.1 ], [ 0, %latch.2 ], [ 0, %latch.3 ], [ 0, %latch.4 ], [ 0, %latch.5 ], [ 0, %latch.6 ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa.loopexit2: |
| ; EPILOG-NEXT: %result.ph1.ph3 = phi i32 [ 0, %header.epil ], [ %add.epil, %latch.epil ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa: |
| ; EPILOG-NEXT: %result.ph1 = phi i32 [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ], [ %result.ph1.ph3, %latchExit.epilog-lcssa.loopexit2 ] |
| ; EPILOG-NEXT: br label %latchExit |
| ; EPILOG: latchExit: |
| ; EPILOG-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i32 %result |
| ; EPILOG: for.exit2.loopexit: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2.loopexit4: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2: |
| ; EPILOG-NEXT: ret i32 42 |
| ; |
| ; EPILOG-BLOCK-LABEL: @hdr_latch_same_exit( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block |
| ; EPILOG-BLOCK: for.exiting_block: |
| ; EPILOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %latch |
| ; EPILOG-BLOCK: latch: |
| ; EPILOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-BLOCK-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-BLOCK-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %latchExit.epilog-lcssa.loopexit, label %for.exiting_block.1 |
| ; EPILOG-BLOCK: for.exiting_block.1: |
| ; EPILOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %latch.1 |
| ; EPILOG-BLOCK: latch.1: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !4 |
| ; EPILOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG-BLOCK: latchExit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %latchExit.epilog-lcssa, label %for.exiting_block.epil |
| ; EPILOG-BLOCK: for.exiting_block.epil: |
| ; EPILOG-BLOCK-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.epil, label %for.exit2, label %latch.epil |
| ; EPILOG-BLOCK: latch.epil: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.unr |
| ; EPILOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.epil = add nsw i32 %5, %sum.02.unr |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph1.ph = phi i32 [ 0, %header ], [ 0, %latch ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph1 = phi i32 [ %add.epil, %latch.epil ], [ 0, %header.epil ], [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit |
| ; EPILOG-BLOCK: latchExit: |
| ; EPILOG-BLOCK-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %result |
| ; EPILOG-BLOCK: for.exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %for.exit2 |
| ; EPILOG-BLOCK: for.exit2: |
| ; EPILOG-BLOCK-NEXT: ret i32 42 |
| ; |
| ; PROLOG-LABEL: @hdr_latch_same_exit( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %n |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %sum.02.prol = phi i32 [ %add.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %header.prol.preheader ], [ %prol.iter.next, %latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit1, label %for.exiting_block.prol |
| ; PROLOG: for.exiting_block.prol: |
| ; PROLOG-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.prol, label %for.exit2.loopexit3, label %latch.prol |
| ; PROLOG: latch.prol: |
| ; PROLOG-NEXT: %arrayidx.prol = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.prol |
| ; PROLOG-NEXT: %2 = load i32, ptr %arrayidx.prol, align 4 |
| ; PROLOG-NEXT: %add.prol = add nsw i32 %2, %sum.02.prol |
| ; PROLOG-NEXT: %indvars.iv.next.prol = add i64 %indvars.iv.prol, 1 |
| ; PROLOG-NEXT: %exitcond.prol = icmp eq i64 %indvars.iv.next.prol, %n |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !4 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %result.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ] |
| ; PROLOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %result.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %3 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; PROLOG-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block |
| ; PROLOG: for.exiting_block: |
| ; PROLOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %latch |
| ; PROLOG: latch: |
| ; PROLOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.1 |
| ; PROLOG: for.exiting_block.1: |
| ; PROLOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %latch.1 |
| ; PROLOG: latch.1: |
| ; PROLOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.2 |
| ; PROLOG: for.exiting_block.2: |
| ; PROLOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.2, label %for.exit2.loopexit, label %latch.2 |
| ; PROLOG: latch.2: |
| ; PROLOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; PROLOG-NEXT: %6 = load i32, ptr %arrayidx.2, align 4 |
| ; PROLOG-NEXT: %add.2 = add nsw i32 %6, %add.1 |
| ; PROLOG-NEXT: %indvars.iv.next.2 = add i64 %indvars.iv, 3 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.3 |
| ; PROLOG: for.exiting_block.3: |
| ; PROLOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.3, label %for.exit2.loopexit, label %latch.3 |
| ; PROLOG: latch.3: |
| ; PROLOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; PROLOG-NEXT: %7 = load i32, ptr %arrayidx.3, align 4 |
| ; PROLOG-NEXT: %add.3 = add nsw i32 %7, %add.2 |
| ; PROLOG-NEXT: %indvars.iv.next.3 = add i64 %indvars.iv, 4 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.4 |
| ; PROLOG: for.exiting_block.4: |
| ; PROLOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.4, label %for.exit2.loopexit, label %latch.4 |
| ; PROLOG: latch.4: |
| ; PROLOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; PROLOG-NEXT: %8 = load i32, ptr %arrayidx.4, align 4 |
| ; PROLOG-NEXT: %add.4 = add nsw i32 %8, %add.3 |
| ; PROLOG-NEXT: %indvars.iv.next.4 = add i64 %indvars.iv, 5 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.5 |
| ; PROLOG: for.exiting_block.5: |
| ; PROLOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.5, label %for.exit2.loopexit, label %latch.5 |
| ; PROLOG: latch.5: |
| ; PROLOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; PROLOG-NEXT: %9 = load i32, ptr %arrayidx.5, align 4 |
| ; PROLOG-NEXT: %add.5 = add nsw i32 %9, %add.4 |
| ; PROLOG-NEXT: %indvars.iv.next.5 = add i64 %indvars.iv, 6 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.6 |
| ; PROLOG: for.exiting_block.6: |
| ; PROLOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.6, label %for.exit2.loopexit, label %latch.6 |
| ; PROLOG: latch.6: |
| ; PROLOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; PROLOG-NEXT: %10 = load i32, ptr %arrayidx.6, align 4 |
| ; PROLOG-NEXT: %add.6 = add nsw i32 %10, %add.5 |
| ; PROLOG-NEXT: %indvars.iv.next.6 = add i64 %indvars.iv, 7 |
| ; PROLOG-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.7 |
| ; PROLOG: for.exiting_block.7: |
| ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.7, label %for.exit2.loopexit, label %latch.7 |
| ; PROLOG: latch.7: |
| ; PROLOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; PROLOG-NEXT: %11 = load i32, ptr %arrayidx.7, align 4 |
| ; PROLOG-NEXT: %add.7 = add nsw i32 %11, %add.6 |
| ; PROLOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; PROLOG-NEXT: %exitcond.7 = icmp eq i64 %indvars.iv.next.7, %n |
| ; PROLOG-NEXT: br i1 %exitcond.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; PROLOG: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-NEXT: %result.ph.ph = phi i32 [ 0, %header ], [ 0, %latch ], [ 0, %latch.1 ], [ 0, %latch.2 ], [ 0, %latch.3 ], [ 0, %latch.4 ], [ 0, %latch.5 ], [ 0, %latch.6 ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa.loopexit1: |
| ; PROLOG-NEXT: %result.ph.ph2 = phi i32 [ 0, %header.prol ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa: |
| ; PROLOG-NEXT: %result.ph = phi i32 [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ], [ %result.ph.ph2, %latchExit.unr-lcssa.loopexit1 ] |
| ; PROLOG-NEXT: br label %latchExit |
| ; PROLOG: latchExit: |
| ; PROLOG-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-NEXT: ret i32 %result |
| ; PROLOG: for.exit2.loopexit: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2.loopexit3: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2: |
| ; PROLOG-NEXT: ret i32 42 |
| ; |
| ; PROLOG-BLOCK-LABEL: @hdr_latch_same_exit( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %latchExit.unr-lcssa, label %for.exiting_block.prol |
| ; PROLOG-BLOCK: for.exiting_block.prol: |
| ; PROLOG-BLOCK-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.prol, label %for.exit2, label %latch.prol |
| ; PROLOG-BLOCK: latch.prol: |
| ; PROLOG-BLOCK-NEXT: %2 = load i32, ptr %a, align 4 |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ 1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %3 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block |
| ; PROLOG-BLOCK: for.exiting_block: |
| ; PROLOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp, label %for.exit2.loopexit, label %latch |
| ; PROLOG-BLOCK: latch: |
| ; PROLOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-BLOCK-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %latchExit.unr-lcssa.loopexit, label %for.exiting_block.1 |
| ; PROLOG-BLOCK: for.exiting_block.1: |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %for.exit2.loopexit, label %latch.1 |
| ; PROLOG-BLOCK: latch.1: |
| ; PROLOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-BLOCK-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-BLOCK-NEXT: %exitcond.1 = icmp eq i64 %indvars.iv.next.1, %n |
| ; PROLOG-BLOCK-NEXT: br i1 %exitcond.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !4 |
| ; PROLOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ 0, %header ], [ 0, %latch ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latchExit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %result.ph = phi i32 [ 0, %header.prol ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit |
| ; PROLOG-BLOCK: latchExit: |
| ; PROLOG-BLOCK-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %result |
| ; PROLOG-BLOCK: for.exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %for.exit2 |
| ; PROLOG-BLOCK: for.exit2: |
| ; PROLOG-BLOCK-NEXT: ret i32 42 |
| ; |
| |
| entry: |
| br label %header |
| |
| header: |
| %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] |
| %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] |
| br i1 %cond, label %latchExit, label %for.exiting_block |
| |
| for.exiting_block: |
| %cmp = icmp eq i64 %n, 42 |
| br i1 %cmp, label %for.exit2, label %latch |
| |
| latch: ; preds = %latch, %entry |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| %0 = load i32, ptr %arrayidx, align 4 |
| %add = add nsw i32 %0, %sum.02 |
| %indvars.iv.next = add i64 %indvars.iv, 1 |
| %exitcond = icmp eq i64 %indvars.iv.next, %n |
| br i1 %exitcond, label %latchExit, label %header |
| |
| latchExit: ; preds = %latch, %entry |
| %result = phi i32 [ 0, %header ], [ %add, %latch ] |
| ret i32 %result |
| |
| for.exit2: |
| ret i32 42 |
| } |
| |
| ; Two exiting blocks to latch where the exiting blocks are Latch and a |
| ; non-header |
| ; FIXME: We should unroll this loop. |
| define i32 @otherblock_latch_same_exit(ptr nocapture %a, i64 %n, i1 %cond) { |
| ; EPILOG-LABEL: @otherblock_latch_same_exit( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %n |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG: for.exiting_block: |
| ; EPILOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG: latch: |
| ; EPILOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG: for.exiting_block.1: |
| ; EPILOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG: latch.1: |
| ; EPILOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-NEXT: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; EPILOG: for.exiting_block.2: |
| ; EPILOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.2, label %latchExit.epilog-lcssa.loopexit, label %latch.2 |
| ; EPILOG: latch.2: |
| ; EPILOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; EPILOG-NEXT: %5 = load i32, ptr %arrayidx.2, align 4 |
| ; EPILOG-NEXT: %add.2 = add nsw i32 %5, %add.1 |
| ; EPILOG-NEXT: %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; EPILOG: for.exiting_block.3: |
| ; EPILOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.3, label %latchExit.epilog-lcssa.loopexit, label %latch.3 |
| ; EPILOG: latch.3: |
| ; EPILOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; EPILOG-NEXT: %6 = load i32, ptr %arrayidx.3, align 4 |
| ; EPILOG-NEXT: %add.3 = add nsw i32 %6, %add.2 |
| ; EPILOG-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; EPILOG: for.exiting_block.4: |
| ; EPILOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.4, label %latchExit.epilog-lcssa.loopexit, label %latch.4 |
| ; EPILOG: latch.4: |
| ; EPILOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; EPILOG-NEXT: %7 = load i32, ptr %arrayidx.4, align 4 |
| ; EPILOG-NEXT: %add.4 = add nsw i32 %7, %add.3 |
| ; EPILOG-NEXT: %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; EPILOG: for.exiting_block.5: |
| ; EPILOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.5, label %latchExit.epilog-lcssa.loopexit, label %latch.5 |
| ; EPILOG: latch.5: |
| ; EPILOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; EPILOG-NEXT: %8 = load i32, ptr %arrayidx.5, align 4 |
| ; EPILOG-NEXT: %add.5 = add nsw i32 %8, %add.4 |
| ; EPILOG-NEXT: %indvars.iv.next.5 = add nuw nsw i64 %indvars.iv, 6 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; EPILOG: for.exiting_block.6: |
| ; EPILOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.6, label %latchExit.epilog-lcssa.loopexit, label %latch.6 |
| ; EPILOG: latch.6: |
| ; EPILOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; EPILOG-NEXT: %9 = load i32, ptr %arrayidx.6, align 4 |
| ; EPILOG-NEXT: %add.6 = add nsw i32 %9, %add.5 |
| ; EPILOG-NEXT: %indvars.iv.next.6 = add nuw nsw i64 %indvars.iv, 7 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; EPILOG: for.exiting_block.7: |
| ; EPILOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.7, label %latchExit.epilog-lcssa.loopexit, label %latch.7 |
| ; EPILOG: latch.7: |
| ; EPILOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; EPILOG-NEXT: %10 = load i32, ptr %arrayidx.7, align 4 |
| ; EPILOG-NEXT: %add.7 = add nsw i32 %10, %add.6 |
| ; EPILOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; EPILOG: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG: latchExit.unr-lcssa: |
| ; EPILOG-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %latch.epil ], [ %indvars.iv.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %sum.02.epil = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %header.epil.preheader ], [ %epil.iter.next, %latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit2, label %for.exiting_block.epil |
| ; EPILOG: for.exiting_block.epil: |
| ; EPILOG-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa.loopexit3, label %latch.epil |
| ; EPILOG: latch.epil: |
| ; EPILOG-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.epil |
| ; EPILOG-NEXT: %11 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-NEXT: %add.epil = add nsw i32 %11, %sum.02.epil |
| ; EPILOG-NEXT: %indvars.iv.next.epil = add i64 %indvars.iv.epil, 1 |
| ; EPILOG-NEXT: %exitcond.epil = icmp eq i64 %indvars.iv.next.epil, %n |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %latchExit.epilog-lcssa.loopexit3, !llvm.loop !5 |
| ; EPILOG: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph1.ph = phi i32 [ 2, %for.exiting_block ], [ 2, %for.exiting_block.1 ], [ 2, %for.exiting_block.2 ], [ 2, %for.exiting_block.3 ], [ 2, %for.exiting_block.4 ], [ 2, %for.exiting_block.5 ], [ 2, %for.exiting_block.6 ], [ 2, %for.exiting_block.7 ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa.loopexit3: |
| ; EPILOG-NEXT: %result.ph1.ph4 = phi i32 [ 2, %for.exiting_block.epil ], [ %add.epil, %latch.epil ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa: |
| ; EPILOG-NEXT: %result.ph1 = phi i32 [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ], [ %result.ph1.ph4, %latchExit.epilog-lcssa.loopexit3 ] |
| ; EPILOG-NEXT: br label %latchExit |
| ; EPILOG: latchExit: |
| ; EPILOG-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i32 %result |
| ; EPILOG: for.exit2.loopexit: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2.loopexit2: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2: |
| ; EPILOG-NEXT: ret i32 42 |
| ; |
| ; EPILOG-BLOCK-LABEL: @otherblock_latch_same_exit( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG-BLOCK: for.exiting_block: |
| ; EPILOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG-BLOCK: latch: |
| ; EPILOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-BLOCK-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-BLOCK-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG-BLOCK: for.exiting_block.1: |
| ; EPILOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG-BLOCK: latch.1: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !5 |
| ; EPILOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG-BLOCK: latchExit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.epil |
| ; EPILOG-BLOCK: for.exiting_block.epil: |
| ; EPILOG-BLOCK-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa, label %latch.epil |
| ; EPILOG-BLOCK: latch.epil: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.unr |
| ; EPILOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.epil = add nsw i32 %5, %sum.02.unr |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph1.ph = phi i32 [ 2, %for.exiting_block ], [ 2, %for.exiting_block.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph1 = phi i32 [ %add.epil, %latch.epil ], [ 2, %for.exiting_block.epil ], [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit |
| ; EPILOG-BLOCK: latchExit: |
| ; EPILOG-BLOCK-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %result |
| ; EPILOG-BLOCK: for.exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %for.exit2 |
| ; EPILOG-BLOCK: for.exit2: |
| ; EPILOG-BLOCK-NEXT: ret i32 42 |
| ; |
| ; PROLOG-LABEL: @otherblock_latch_same_exit( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %n |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %sum.02.prol = phi i32 [ %add.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %header.prol.preheader ], [ %prol.iter.next, %latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit1, label %for.exiting_block.prol |
| ; PROLOG: for.exiting_block.prol: |
| ; PROLOG-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa.loopexit2, label %latch.prol |
| ; PROLOG: latch.prol: |
| ; PROLOG-NEXT: %arrayidx.prol = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.prol |
| ; PROLOG-NEXT: %2 = load i32, ptr %arrayidx.prol, align 4 |
| ; PROLOG-NEXT: %add.prol = add nsw i32 %2, %sum.02.prol |
| ; PROLOG-NEXT: %indvars.iv.next.prol = add i64 %indvars.iv.prol, 1 |
| ; PROLOG-NEXT: %exitcond.prol = icmp eq i64 %indvars.iv.next.prol, %n |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !5 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %result.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ] |
| ; PROLOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %result.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %3 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; PROLOG-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG: for.exiting_block: |
| ; PROLOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG: latch: |
| ; PROLOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG: for.exiting_block.1: |
| ; PROLOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG: latch.1: |
| ; PROLOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; PROLOG: for.exiting_block.2: |
| ; PROLOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.2, label %latchExit.unr-lcssa.loopexit, label %latch.2 |
| ; PROLOG: latch.2: |
| ; PROLOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; PROLOG-NEXT: %6 = load i32, ptr %arrayidx.2, align 4 |
| ; PROLOG-NEXT: %add.2 = add nsw i32 %6, %add.1 |
| ; PROLOG-NEXT: %indvars.iv.next.2 = add i64 %indvars.iv, 3 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; PROLOG: for.exiting_block.3: |
| ; PROLOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.3, label %latchExit.unr-lcssa.loopexit, label %latch.3 |
| ; PROLOG: latch.3: |
| ; PROLOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; PROLOG-NEXT: %7 = load i32, ptr %arrayidx.3, align 4 |
| ; PROLOG-NEXT: %add.3 = add nsw i32 %7, %add.2 |
| ; PROLOG-NEXT: %indvars.iv.next.3 = add i64 %indvars.iv, 4 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; PROLOG: for.exiting_block.4: |
| ; PROLOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.4, label %latchExit.unr-lcssa.loopexit, label %latch.4 |
| ; PROLOG: latch.4: |
| ; PROLOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; PROLOG-NEXT: %8 = load i32, ptr %arrayidx.4, align 4 |
| ; PROLOG-NEXT: %add.4 = add nsw i32 %8, %add.3 |
| ; PROLOG-NEXT: %indvars.iv.next.4 = add i64 %indvars.iv, 5 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; PROLOG: for.exiting_block.5: |
| ; PROLOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.5, label %latchExit.unr-lcssa.loopexit, label %latch.5 |
| ; PROLOG: latch.5: |
| ; PROLOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; PROLOG-NEXT: %9 = load i32, ptr %arrayidx.5, align 4 |
| ; PROLOG-NEXT: %add.5 = add nsw i32 %9, %add.4 |
| ; PROLOG-NEXT: %indvars.iv.next.5 = add i64 %indvars.iv, 6 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; PROLOG: for.exiting_block.6: |
| ; PROLOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.6, label %latchExit.unr-lcssa.loopexit, label %latch.6 |
| ; PROLOG: latch.6: |
| ; PROLOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; PROLOG-NEXT: %10 = load i32, ptr %arrayidx.6, align 4 |
| ; PROLOG-NEXT: %add.6 = add nsw i32 %10, %add.5 |
| ; PROLOG-NEXT: %indvars.iv.next.6 = add i64 %indvars.iv, 7 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; PROLOG: for.exiting_block.7: |
| ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.7, label %latchExit.unr-lcssa.loopexit, label %latch.7 |
| ; PROLOG: latch.7: |
| ; PROLOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; PROLOG-NEXT: %11 = load i32, ptr %arrayidx.7, align 4 |
| ; PROLOG-NEXT: %add.7 = add nsw i32 %11, %add.6 |
| ; PROLOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; PROLOG-NEXT: %exitcond.7 = icmp eq i64 %indvars.iv.next.7, %n |
| ; PROLOG-NEXT: br i1 %exitcond.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; PROLOG: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-NEXT: %result.ph.ph = phi i32 [ 2, %for.exiting_block ], [ 2, %for.exiting_block.1 ], [ 2, %for.exiting_block.2 ], [ 2, %for.exiting_block.3 ], [ 2, %for.exiting_block.4 ], [ 2, %for.exiting_block.5 ], [ 2, %for.exiting_block.6 ], [ 2, %for.exiting_block.7 ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa.loopexit2: |
| ; PROLOG-NEXT: %result.ph.ph3 = phi i32 [ 2, %for.exiting_block.prol ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa: |
| ; PROLOG-NEXT: %result.ph = phi i32 [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ], [ %result.ph.ph3, %latchExit.unr-lcssa.loopexit2 ] |
| ; PROLOG-NEXT: br label %latchExit |
| ; PROLOG: latchExit: |
| ; PROLOG-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-NEXT: ret i32 %result |
| ; PROLOG: for.exit2.loopexit: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2.loopexit1: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2: |
| ; PROLOG-NEXT: ret i32 42 |
| ; |
| ; PROLOG-BLOCK-LABEL: @otherblock_latch_same_exit( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.prol |
| ; PROLOG-BLOCK: for.exiting_block.prol: |
| ; PROLOG-BLOCK-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa, label %latch.prol |
| ; PROLOG-BLOCK: latch.prol: |
| ; PROLOG-BLOCK-NEXT: %2 = load i32, ptr %a, align 4 |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ 1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %3 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG-BLOCK: for.exiting_block: |
| ; PROLOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG-BLOCK: latch: |
| ; PROLOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-BLOCK-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG-BLOCK: for.exiting_block.1: |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG-BLOCK: latch.1: |
| ; PROLOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-BLOCK-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-BLOCK-NEXT: %exitcond.1 = icmp eq i64 %indvars.iv.next.1, %n |
| ; PROLOG-BLOCK-NEXT: br i1 %exitcond.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !5 |
| ; PROLOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ 2, %for.exiting_block ], [ 2, %for.exiting_block.1 ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latchExit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %result.ph = phi i32 [ 2, %for.exiting_block.prol ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit |
| ; PROLOG-BLOCK: latchExit: |
| ; PROLOG-BLOCK-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %result |
| ; PROLOG-BLOCK: for.exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %for.exit2 |
| ; PROLOG-BLOCK: for.exit2: |
| ; PROLOG-BLOCK-NEXT: ret i32 42 |
| ; |
| |
| entry: |
| br label %header |
| |
| header: |
| %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] |
| %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] |
| br i1 %cond, label %for.exit2, label %for.exiting_block |
| |
| for.exiting_block: |
| %cmp = icmp eq i64 %n, 42 |
| br i1 %cmp, label %latchExit, label %latch |
| |
| latch: ; preds = %latch, %entry |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| %0 = load i32, ptr %arrayidx, align 4 |
| %add = add nsw i32 %0, %sum.02 |
| %indvars.iv.next = add i64 %indvars.iv, 1 |
| %exitcond = icmp eq i64 %indvars.iv.next, %n |
| br i1 %exitcond, label %latchExit, label %header |
| |
| latchExit: ; preds = %latch, %entry |
| %result = phi i32 [ 2, %for.exiting_block ], [ %add, %latch ] |
| ret i32 %result |
| |
| for.exit2: |
| ret i32 42 |
| } |
| |
| ; Two exiting blocks to latch where the exiting blocks are Latch and a |
| ; non-header |
| ; Same as above test except the incoming value for latch Phi is from the header |
| ; FIXME: We should be able to runtime unroll. |
| define i32 @otherblock_latch_same_exit2(ptr nocapture %a, i64 %n, i1 %cond) { |
| ; EPILOG-LABEL: @otherblock_latch_same_exit2( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %n |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG: for.exiting_block: |
| ; EPILOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG: latch: |
| ; EPILOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG: for.exiting_block.1: |
| ; EPILOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG: latch.1: |
| ; EPILOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-NEXT: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; EPILOG: for.exiting_block.2: |
| ; EPILOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.2, label %latchExit.epilog-lcssa.loopexit, label %latch.2 |
| ; EPILOG: latch.2: |
| ; EPILOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; EPILOG-NEXT: %5 = load i32, ptr %arrayidx.2, align 4 |
| ; EPILOG-NEXT: %add.2 = add nsw i32 %5, %add.1 |
| ; EPILOG-NEXT: %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; EPILOG: for.exiting_block.3: |
| ; EPILOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.3, label %latchExit.epilog-lcssa.loopexit, label %latch.3 |
| ; EPILOG: latch.3: |
| ; EPILOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; EPILOG-NEXT: %6 = load i32, ptr %arrayidx.3, align 4 |
| ; EPILOG-NEXT: %add.3 = add nsw i32 %6, %add.2 |
| ; EPILOG-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; EPILOG: for.exiting_block.4: |
| ; EPILOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.4, label %latchExit.epilog-lcssa.loopexit, label %latch.4 |
| ; EPILOG: latch.4: |
| ; EPILOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; EPILOG-NEXT: %7 = load i32, ptr %arrayidx.4, align 4 |
| ; EPILOG-NEXT: %add.4 = add nsw i32 %7, %add.3 |
| ; EPILOG-NEXT: %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; EPILOG: for.exiting_block.5: |
| ; EPILOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.5, label %latchExit.epilog-lcssa.loopexit, label %latch.5 |
| ; EPILOG: latch.5: |
| ; EPILOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; EPILOG-NEXT: %8 = load i32, ptr %arrayidx.5, align 4 |
| ; EPILOG-NEXT: %add.5 = add nsw i32 %8, %add.4 |
| ; EPILOG-NEXT: %indvars.iv.next.5 = add nuw nsw i64 %indvars.iv, 6 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; EPILOG: for.exiting_block.6: |
| ; EPILOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.6, label %latchExit.epilog-lcssa.loopexit, label %latch.6 |
| ; EPILOG: latch.6: |
| ; EPILOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; EPILOG-NEXT: %9 = load i32, ptr %arrayidx.6, align 4 |
| ; EPILOG-NEXT: %add.6 = add nsw i32 %9, %add.5 |
| ; EPILOG-NEXT: %indvars.iv.next.6 = add nuw nsw i64 %indvars.iv, 7 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; EPILOG: for.exiting_block.7: |
| ; EPILOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.7, label %latchExit.epilog-lcssa.loopexit, label %latch.7 |
| ; EPILOG: latch.7: |
| ; EPILOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; EPILOG-NEXT: %10 = load i32, ptr %arrayidx.7, align 4 |
| ; EPILOG-NEXT: %add.7 = add nsw i32 %10, %add.6 |
| ; EPILOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; EPILOG: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG: latchExit.unr-lcssa: |
| ; EPILOG-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %latch.epil ], [ %indvars.iv.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %sum.02.epil = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %header.epil.preheader ], [ %epil.iter.next, %latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit2, label %for.exiting_block.epil |
| ; EPILOG: for.exiting_block.epil: |
| ; EPILOG-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa.loopexit3, label %latch.epil |
| ; EPILOG: latch.epil: |
| ; EPILOG-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.epil |
| ; EPILOG-NEXT: %11 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-NEXT: %add.epil = add nsw i32 %11, %sum.02.epil |
| ; EPILOG-NEXT: %indvars.iv.next.epil = add i64 %indvars.iv.epil, 1 |
| ; EPILOG-NEXT: %exitcond.epil = icmp eq i64 %indvars.iv.next.epil, %n |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %latchExit.epilog-lcssa.loopexit3, !llvm.loop !6 |
| ; EPILOG: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph1.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %for.exiting_block.2 ], [ %add.2, %for.exiting_block.3 ], [ %add.3, %for.exiting_block.4 ], [ %add.4, %for.exiting_block.5 ], [ %add.5, %for.exiting_block.6 ], [ %add.6, %for.exiting_block.7 ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa.loopexit3: |
| ; EPILOG-NEXT: %result.ph1.ph4 = phi i32 [ %sum.02.epil, %for.exiting_block.epil ], [ %add.epil, %latch.epil ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa: |
| ; EPILOG-NEXT: %result.ph1 = phi i32 [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ], [ %result.ph1.ph4, %latchExit.epilog-lcssa.loopexit3 ] |
| ; EPILOG-NEXT: br label %latchExit |
| ; EPILOG: latchExit: |
| ; EPILOG-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i32 %result |
| ; EPILOG: for.exit2.loopexit: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2.loopexit2: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2: |
| ; EPILOG-NEXT: ret i32 42 |
| ; |
| ; EPILOG-BLOCK-LABEL: @otherblock_latch_same_exit2( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG-BLOCK: for.exiting_block: |
| ; EPILOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG-BLOCK: latch: |
| ; EPILOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-BLOCK-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-BLOCK-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG-BLOCK: for.exiting_block.1: |
| ; EPILOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG-BLOCK: latch.1: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !6 |
| ; EPILOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG-BLOCK: latchExit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.epil |
| ; EPILOG-BLOCK: for.exiting_block.epil: |
| ; EPILOG-BLOCK-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa, label %latch.epil |
| ; EPILOG-BLOCK: latch.epil: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.unr |
| ; EPILOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.epil = add nsw i32 %5, %sum.02.unr |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph1.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph1 = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %for.exiting_block.epil ], [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit |
| ; EPILOG-BLOCK: latchExit: |
| ; EPILOG-BLOCK-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %result |
| ; EPILOG-BLOCK: for.exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %for.exit2 |
| ; EPILOG-BLOCK: for.exit2: |
| ; EPILOG-BLOCK-NEXT: ret i32 42 |
| ; |
| ; PROLOG-LABEL: @otherblock_latch_same_exit2( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %n |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %sum.02.prol = phi i32 [ %add.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %header.prol.preheader ], [ %prol.iter.next, %latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit1, label %for.exiting_block.prol |
| ; PROLOG: for.exiting_block.prol: |
| ; PROLOG-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa.loopexit2, label %latch.prol |
| ; PROLOG: latch.prol: |
| ; PROLOG-NEXT: %arrayidx.prol = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.prol |
| ; PROLOG-NEXT: %2 = load i32, ptr %arrayidx.prol, align 4 |
| ; PROLOG-NEXT: %add.prol = add nsw i32 %2, %sum.02.prol |
| ; PROLOG-NEXT: %indvars.iv.next.prol = add i64 %indvars.iv.prol, 1 |
| ; PROLOG-NEXT: %exitcond.prol = icmp eq i64 %indvars.iv.next.prol, %n |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !6 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %result.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ] |
| ; PROLOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %result.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %3 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; PROLOG-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG: for.exiting_block: |
| ; PROLOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG: latch: |
| ; PROLOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG: for.exiting_block.1: |
| ; PROLOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG: latch.1: |
| ; PROLOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; PROLOG: for.exiting_block.2: |
| ; PROLOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.2, label %latchExit.unr-lcssa.loopexit, label %latch.2 |
| ; PROLOG: latch.2: |
| ; PROLOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; PROLOG-NEXT: %6 = load i32, ptr %arrayidx.2, align 4 |
| ; PROLOG-NEXT: %add.2 = add nsw i32 %6, %add.1 |
| ; PROLOG-NEXT: %indvars.iv.next.2 = add i64 %indvars.iv, 3 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; PROLOG: for.exiting_block.3: |
| ; PROLOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.3, label %latchExit.unr-lcssa.loopexit, label %latch.3 |
| ; PROLOG: latch.3: |
| ; PROLOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; PROLOG-NEXT: %7 = load i32, ptr %arrayidx.3, align 4 |
| ; PROLOG-NEXT: %add.3 = add nsw i32 %7, %add.2 |
| ; PROLOG-NEXT: %indvars.iv.next.3 = add i64 %indvars.iv, 4 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; PROLOG: for.exiting_block.4: |
| ; PROLOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.4, label %latchExit.unr-lcssa.loopexit, label %latch.4 |
| ; PROLOG: latch.4: |
| ; PROLOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; PROLOG-NEXT: %8 = load i32, ptr %arrayidx.4, align 4 |
| ; PROLOG-NEXT: %add.4 = add nsw i32 %8, %add.3 |
| ; PROLOG-NEXT: %indvars.iv.next.4 = add i64 %indvars.iv, 5 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; PROLOG: for.exiting_block.5: |
| ; PROLOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.5, label %latchExit.unr-lcssa.loopexit, label %latch.5 |
| ; PROLOG: latch.5: |
| ; PROLOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; PROLOG-NEXT: %9 = load i32, ptr %arrayidx.5, align 4 |
| ; PROLOG-NEXT: %add.5 = add nsw i32 %9, %add.4 |
| ; PROLOG-NEXT: %indvars.iv.next.5 = add i64 %indvars.iv, 6 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; PROLOG: for.exiting_block.6: |
| ; PROLOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.6, label %latchExit.unr-lcssa.loopexit, label %latch.6 |
| ; PROLOG: latch.6: |
| ; PROLOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; PROLOG-NEXT: %10 = load i32, ptr %arrayidx.6, align 4 |
| ; PROLOG-NEXT: %add.6 = add nsw i32 %10, %add.5 |
| ; PROLOG-NEXT: %indvars.iv.next.6 = add i64 %indvars.iv, 7 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; PROLOG: for.exiting_block.7: |
| ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.7, label %latchExit.unr-lcssa.loopexit, label %latch.7 |
| ; PROLOG: latch.7: |
| ; PROLOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; PROLOG-NEXT: %11 = load i32, ptr %arrayidx.7, align 4 |
| ; PROLOG-NEXT: %add.7 = add nsw i32 %11, %add.6 |
| ; PROLOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; PROLOG-NEXT: %exitcond.7 = icmp eq i64 %indvars.iv.next.7, %n |
| ; PROLOG-NEXT: br i1 %exitcond.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; PROLOG: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-NEXT: %result.ph.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %for.exiting_block.2 ], [ %add.2, %for.exiting_block.3 ], [ %add.3, %for.exiting_block.4 ], [ %add.4, %for.exiting_block.5 ], [ %add.5, %for.exiting_block.6 ], [ %add.6, %for.exiting_block.7 ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa.loopexit2: |
| ; PROLOG-NEXT: %result.ph.ph3 = phi i32 [ %sum.02.prol, %for.exiting_block.prol ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa: |
| ; PROLOG-NEXT: %result.ph = phi i32 [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ], [ %result.ph.ph3, %latchExit.unr-lcssa.loopexit2 ] |
| ; PROLOG-NEXT: br label %latchExit |
| ; PROLOG: latchExit: |
| ; PROLOG-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-NEXT: ret i32 %result |
| ; PROLOG: for.exit2.loopexit: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2.loopexit1: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2: |
| ; PROLOG-NEXT: ret i32 42 |
| ; |
| ; PROLOG-BLOCK-LABEL: @otherblock_latch_same_exit2( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.prol |
| ; PROLOG-BLOCK: for.exiting_block.prol: |
| ; PROLOG-BLOCK-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa, label %latch.prol |
| ; PROLOG-BLOCK: latch.prol: |
| ; PROLOG-BLOCK-NEXT: %2 = load i32, ptr %a, align 4 |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ 1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %3 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG-BLOCK: for.exiting_block: |
| ; PROLOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG-BLOCK: latch: |
| ; PROLOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-BLOCK-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG-BLOCK: for.exiting_block.1: |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG-BLOCK: latch.1: |
| ; PROLOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-BLOCK-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-BLOCK-NEXT: %exitcond.1 = icmp eq i64 %indvars.iv.next.1, %n |
| ; PROLOG-BLOCK-NEXT: br i1 %exitcond.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !6 |
| ; PROLOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latchExit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %result.ph = phi i32 [ 0, %for.exiting_block.prol ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit |
| ; PROLOG-BLOCK: latchExit: |
| ; PROLOG-BLOCK-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %result |
| ; PROLOG-BLOCK: for.exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %for.exit2 |
| ; PROLOG-BLOCK: for.exit2: |
| ; PROLOG-BLOCK-NEXT: ret i32 42 |
| ; |
| |
| entry: |
| br label %header |
| |
| header: |
| %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] |
| %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] |
| br i1 %cond, label %for.exit2, label %for.exiting_block |
| |
| for.exiting_block: |
| %cmp = icmp eq i64 %n, 42 |
| br i1 %cmp, label %latchExit, label %latch |
| |
| latch: ; preds = %latch, %entry |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| %0 = load i32, ptr %arrayidx, align 4 |
| %add = add nsw i32 %0, %sum.02 |
| %indvars.iv.next = add i64 %indvars.iv, 1 |
| %exitcond = icmp eq i64 %indvars.iv.next, %n |
| br i1 %exitcond, label %latchExit, label %header |
| |
| latchExit: ; preds = %latch, %entry |
| %result = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %latch ] |
| ret i32 %result |
| |
| for.exit2: |
| ret i32 42 |
| } |
| |
| ; Two exiting blocks to latch where the exiting blocks are Latch and a |
| ; non-header |
| ; Same as above test except the incoming value for cloned latch Phi is from the |
| ; for.exiting_block. |
| ; FIXME: We should be able to runtime unroll. |
| define i32 @otherblock_latch_same_exit3(ptr nocapture %a, i64 %n, i1 %cond) { |
| ; EPILOG-LABEL: @otherblock_latch_same_exit3( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %n |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG: for.exiting_block: |
| ; EPILOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG: latch: |
| ; EPILOG-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG: for.exiting_block.1: |
| ; EPILOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG: latch.1: |
| ; EPILOG-NEXT: %indvars.iv.next.1 = add nuw nsw i64 %indvars.iv, 2 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; EPILOG: for.exiting_block.2: |
| ; EPILOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; EPILOG-NEXT: %5 = load i32, ptr %arrayidx.2, align 4 |
| ; EPILOG-NEXT: %add.2 = add nsw i32 %5, %add.1 |
| ; EPILOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.2, label %latchExit.epilog-lcssa.loopexit, label %latch.2 |
| ; EPILOG: latch.2: |
| ; EPILOG-NEXT: %indvars.iv.next.2 = add nuw nsw i64 %indvars.iv, 3 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; EPILOG: for.exiting_block.3: |
| ; EPILOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; EPILOG-NEXT: %6 = load i32, ptr %arrayidx.3, align 4 |
| ; EPILOG-NEXT: %add.3 = add nsw i32 %6, %add.2 |
| ; EPILOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.3, label %latchExit.epilog-lcssa.loopexit, label %latch.3 |
| ; EPILOG: latch.3: |
| ; EPILOG-NEXT: %indvars.iv.next.3 = add nuw nsw i64 %indvars.iv, 4 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; EPILOG: for.exiting_block.4: |
| ; EPILOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; EPILOG-NEXT: %7 = load i32, ptr %arrayidx.4, align 4 |
| ; EPILOG-NEXT: %add.4 = add nsw i32 %7, %add.3 |
| ; EPILOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.4, label %latchExit.epilog-lcssa.loopexit, label %latch.4 |
| ; EPILOG: latch.4: |
| ; EPILOG-NEXT: %indvars.iv.next.4 = add nuw nsw i64 %indvars.iv, 5 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; EPILOG: for.exiting_block.5: |
| ; EPILOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; EPILOG-NEXT: %8 = load i32, ptr %arrayidx.5, align 4 |
| ; EPILOG-NEXT: %add.5 = add nsw i32 %8, %add.4 |
| ; EPILOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.5, label %latchExit.epilog-lcssa.loopexit, label %latch.5 |
| ; EPILOG: latch.5: |
| ; EPILOG-NEXT: %indvars.iv.next.5 = add nuw nsw i64 %indvars.iv, 6 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; EPILOG: for.exiting_block.6: |
| ; EPILOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; EPILOG-NEXT: %9 = load i32, ptr %arrayidx.6, align 4 |
| ; EPILOG-NEXT: %add.6 = add nsw i32 %9, %add.5 |
| ; EPILOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.6, label %latchExit.epilog-lcssa.loopexit, label %latch.6 |
| ; EPILOG: latch.6: |
| ; EPILOG-NEXT: %indvars.iv.next.6 = add nuw nsw i64 %indvars.iv, 7 |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; EPILOG: for.exiting_block.7: |
| ; EPILOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; EPILOG-NEXT: %10 = load i32, ptr %arrayidx.7, align 4 |
| ; EPILOG-NEXT: %add.7 = add nsw i32 %10, %add.6 |
| ; EPILOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.7, label %latchExit.epilog-lcssa.loopexit, label %latch.7 |
| ; EPILOG: latch.7: |
| ; EPILOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; EPILOG: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.7, %latch.7 ] |
| ; EPILOG-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG: latchExit.unr-lcssa: |
| ; EPILOG-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %indvars.iv.epil = phi i64 [ %indvars.iv.next.epil, %latch.epil ], [ %indvars.iv.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %sum.02.epil = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %header.epil.preheader ], [ %epil.iter.next, %latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %for.exit2.loopexit2, label %for.exiting_block.epil |
| ; EPILOG: for.exiting_block.epil: |
| ; EPILOG-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.epil |
| ; EPILOG-NEXT: %11 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-NEXT: %add.epil = add nsw i32 %11, %sum.02.epil |
| ; EPILOG-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa.loopexit3, label %latch.epil |
| ; EPILOG: latch.epil: |
| ; EPILOG-NEXT: %indvars.iv.next.epil = add i64 %indvars.iv.epil, 1 |
| ; EPILOG-NEXT: %exitcond.epil = icmp eq i64 %indvars.iv.next.epil, %n |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %latchExit.epilog-lcssa.loopexit3, !llvm.loop !7 |
| ; EPILOG: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-NEXT: %result.ph1.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %for.exiting_block.2 ], [ %add.2, %for.exiting_block.3 ], [ %add.3, %for.exiting_block.4 ], [ %add.4, %for.exiting_block.5 ], [ %add.5, %for.exiting_block.6 ], [ %add.6, %for.exiting_block.7 ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa.loopexit3: |
| ; EPILOG-NEXT: %result.ph1.ph4 = phi i32 [ %sum.02.epil, %for.exiting_block.epil ], [ %add.epil, %latch.epil ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa: |
| ; EPILOG-NEXT: %result.ph1 = phi i32 [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ], [ %result.ph1.ph4, %latchExit.epilog-lcssa.loopexit3 ] |
| ; EPILOG-NEXT: br label %latchExit |
| ; EPILOG: latchExit: |
| ; EPILOG-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i32 %result |
| ; EPILOG: for.exit2.loopexit: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2.loopexit2: |
| ; EPILOG-NEXT: br label %for.exit2 |
| ; EPILOG: for.exit2: |
| ; EPILOG-NEXT: ret i32 42 |
| ; |
| ; EPILOG-BLOCK-LABEL: @otherblock_latch_same_exit3( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv = phi i64 [ 0, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02 = phi i32 [ 0, %entry.new ], [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; EPILOG-BLOCK: for.exiting_block: |
| ; EPILOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; EPILOG-BLOCK-NEXT: %3 = load i32, ptr %arrayidx, align 4 |
| ; EPILOG-BLOCK-NEXT: %add = add nsw i32 %3, %sum.02 |
| ; EPILOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.epilog-lcssa.loopexit, label %latch |
| ; EPILOG-BLOCK: latch: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; EPILOG-BLOCK: for.exiting_block.1: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; EPILOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx.1, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.1 = add nsw i32 %4, %add |
| ; EPILOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.epilog-lcssa.loopexit, label %latch.1 |
| ; EPILOG-BLOCK: latch.1: |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp eq i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !7 |
| ; EPILOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr.ph = phi i32 [ %add.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG-BLOCK: latchExit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph = phi i32 [ undef, %entry ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.epil |
| ; EPILOG-BLOCK: for.exiting_block.epil: |
| ; EPILOG-BLOCK-NEXT: %arrayidx.epil = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.unr |
| ; EPILOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.epil, align 4 |
| ; EPILOG-BLOCK-NEXT: %add.epil = add nsw i32 %5, %sum.02.unr |
| ; EPILOG-BLOCK-NEXT: %cmp.epil = icmp eq i64 %n, 42 |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp.epil, label %latchExit.epilog-lcssa, label %latch.epil |
| ; EPILOG-BLOCK: latch.epil: |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph1.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa: |
| ; EPILOG-BLOCK-NEXT: %result.ph1 = phi i32 [ %add.epil, %latch.epil ], [ %sum.02.unr, %for.exiting_block.epil ], [ %result.ph1.ph, %latchExit.epilog-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit |
| ; EPILOG-BLOCK: latchExit: |
| ; EPILOG-BLOCK-NEXT: %result = phi i32 [ %result.ph, %latchExit.unr-lcssa ], [ %result.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-BLOCK-NEXT: ret i32 %result |
| ; EPILOG-BLOCK: for.exit2.loopexit: |
| ; EPILOG-BLOCK-NEXT: br label %for.exit2 |
| ; EPILOG-BLOCK: for.exit2: |
| ; EPILOG-BLOCK-NEXT: ret i32 42 |
| ; |
| ; PROLOG-LABEL: @otherblock_latch_same_exit3( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %n |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %indvars.iv.prol = phi i64 [ %indvars.iv.next.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %sum.02.prol = phi i32 [ %add.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %header.prol.preheader ], [ %prol.iter.next, %latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit1, label %for.exiting_block.prol |
| ; PROLOG: for.exiting_block.prol: |
| ; PROLOG-NEXT: %arrayidx.prol = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.prol |
| ; PROLOG-NEXT: %2 = load i32, ptr %arrayidx.prol, align 4 |
| ; PROLOG-NEXT: %add.prol = add nsw i32 %2, %sum.02.prol |
| ; PROLOG-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa.loopexit2, label %latch.prol |
| ; PROLOG: latch.prol: |
| ; PROLOG-NEXT: %indvars.iv.next.prol = add i64 %indvars.iv.prol, 1 |
| ; PROLOG-NEXT: %exitcond.prol = icmp eq i64 %indvars.iv.next.prol, %n |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !7 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %result.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: %indvars.iv.unr.ph = phi i64 [ %indvars.iv.next.prol, %latch.prol ] |
| ; PROLOG-NEXT: %sum.02.unr.ph = phi i32 [ %add.prol, %latch.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %result.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ %indvars.iv.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %sum.02.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %3 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.7, %latch.7 ] |
| ; PROLOG-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG: for.exiting_block: |
| ; PROLOG-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG: latch: |
| ; PROLOG-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG: for.exiting_block.1: |
| ; PROLOG-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG: latch.1: |
| ; PROLOG-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.2 |
| ; PROLOG: for.exiting_block.2: |
| ; PROLOG-NEXT: %arrayidx.2 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.1 |
| ; PROLOG-NEXT: %6 = load i32, ptr %arrayidx.2, align 4 |
| ; PROLOG-NEXT: %add.2 = add nsw i32 %6, %add.1 |
| ; PROLOG-NEXT: %cmp.2 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.2, label %latchExit.unr-lcssa.loopexit, label %latch.2 |
| ; PROLOG: latch.2: |
| ; PROLOG-NEXT: %indvars.iv.next.2 = add i64 %indvars.iv, 3 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.3 |
| ; PROLOG: for.exiting_block.3: |
| ; PROLOG-NEXT: %arrayidx.3 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.2 |
| ; PROLOG-NEXT: %7 = load i32, ptr %arrayidx.3, align 4 |
| ; PROLOG-NEXT: %add.3 = add nsw i32 %7, %add.2 |
| ; PROLOG-NEXT: %cmp.3 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.3, label %latchExit.unr-lcssa.loopexit, label %latch.3 |
| ; PROLOG: latch.3: |
| ; PROLOG-NEXT: %indvars.iv.next.3 = add i64 %indvars.iv, 4 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.4 |
| ; PROLOG: for.exiting_block.4: |
| ; PROLOG-NEXT: %arrayidx.4 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.3 |
| ; PROLOG-NEXT: %8 = load i32, ptr %arrayidx.4, align 4 |
| ; PROLOG-NEXT: %add.4 = add nsw i32 %8, %add.3 |
| ; PROLOG-NEXT: %cmp.4 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.4, label %latchExit.unr-lcssa.loopexit, label %latch.4 |
| ; PROLOG: latch.4: |
| ; PROLOG-NEXT: %indvars.iv.next.4 = add i64 %indvars.iv, 5 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.5 |
| ; PROLOG: for.exiting_block.5: |
| ; PROLOG-NEXT: %arrayidx.5 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.4 |
| ; PROLOG-NEXT: %9 = load i32, ptr %arrayidx.5, align 4 |
| ; PROLOG-NEXT: %add.5 = add nsw i32 %9, %add.4 |
| ; PROLOG-NEXT: %cmp.5 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.5, label %latchExit.unr-lcssa.loopexit, label %latch.5 |
| ; PROLOG: latch.5: |
| ; PROLOG-NEXT: %indvars.iv.next.5 = add i64 %indvars.iv, 6 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.6 |
| ; PROLOG: for.exiting_block.6: |
| ; PROLOG-NEXT: %arrayidx.6 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.5 |
| ; PROLOG-NEXT: %10 = load i32, ptr %arrayidx.6, align 4 |
| ; PROLOG-NEXT: %add.6 = add nsw i32 %10, %add.5 |
| ; PROLOG-NEXT: %cmp.6 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.6, label %latchExit.unr-lcssa.loopexit, label %latch.6 |
| ; PROLOG: latch.6: |
| ; PROLOG-NEXT: %indvars.iv.next.6 = add i64 %indvars.iv, 7 |
| ; PROLOG-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.7 |
| ; PROLOG: for.exiting_block.7: |
| ; PROLOG-NEXT: %arrayidx.7 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next.6 |
| ; PROLOG-NEXT: %11 = load i32, ptr %arrayidx.7, align 4 |
| ; PROLOG-NEXT: %add.7 = add nsw i32 %11, %add.6 |
| ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %n, 42 |
| ; PROLOG-NEXT: br i1 %cmp.7, label %latchExit.unr-lcssa.loopexit, label %latch.7 |
| ; PROLOG: latch.7: |
| ; PROLOG-NEXT: %indvars.iv.next.7 = add i64 %indvars.iv, 8 |
| ; PROLOG-NEXT: %exitcond.7 = icmp eq i64 %indvars.iv.next.7, %n |
| ; PROLOG-NEXT: br i1 %exitcond.7, label %latchExit.unr-lcssa.loopexit, label %header |
| ; PROLOG: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-NEXT: %result.ph.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %for.exiting_block.2 ], [ %add.2, %for.exiting_block.3 ], [ %add.3, %for.exiting_block.4 ], [ %add.4, %for.exiting_block.5 ], [ %add.5, %for.exiting_block.6 ], [ %add.6, %for.exiting_block.7 ], [ %add.7, %latch.7 ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa.loopexit2: |
| ; PROLOG-NEXT: %result.ph.ph3 = phi i32 [ %sum.02.prol, %for.exiting_block.prol ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa: |
| ; PROLOG-NEXT: %result.ph = phi i32 [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ], [ %result.ph.ph3, %latchExit.unr-lcssa.loopexit2 ] |
| ; PROLOG-NEXT: br label %latchExit |
| ; PROLOG: latchExit: |
| ; PROLOG-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-NEXT: ret i32 %result |
| ; PROLOG: for.exit2.loopexit: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2.loopexit1: |
| ; PROLOG-NEXT: br label %for.exit2 |
| ; PROLOG: for.exit2: |
| ; PROLOG-NEXT: ret i32 42 |
| ; |
| ; PROLOG-BLOCK-LABEL: @otherblock_latch_same_exit3( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %n |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2, label %for.exiting_block.prol |
| ; PROLOG-BLOCK: for.exiting_block.prol: |
| ; PROLOG-BLOCK-NEXT: %2 = load i32, ptr %a, align 4 |
| ; PROLOG-BLOCK-NEXT: %cmp.prol = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.prol, label %latchExit.unr-lcssa, label %latch.prol |
| ; PROLOG-BLOCK: latch.prol: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.unr = phi i32 [ undef, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.unr = phi i64 [ 0, %entry ], [ 1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.02.unr = phi i32 [ 0, %entry ], [ %2, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %3 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %3, label %latchExit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv = phi i64 [ %indvars.iv.unr, %entry.new ], [ %indvars.iv.next.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum.02 = phi i32 [ %sum.02.unr, %entry.new ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block |
| ; PROLOG-BLOCK: for.exiting_block: |
| ; PROLOG-BLOCK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| ; PROLOG-BLOCK-NEXT: %4 = load i32, ptr %arrayidx, align 4 |
| ; PROLOG-BLOCK-NEXT: %add = add nsw i32 %4, %sum.02 |
| ; PROLOG-BLOCK-NEXT: %cmp = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp, label %latchExit.unr-lcssa.loopexit, label %latch |
| ; PROLOG-BLOCK: latch: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next = add i64 %indvars.iv, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %for.exit2.loopexit, label %for.exiting_block.1 |
| ; PROLOG-BLOCK: for.exiting_block.1: |
| ; PROLOG-BLOCK-NEXT: %arrayidx.1 = getelementptr inbounds i32, ptr %a, i64 %indvars.iv.next |
| ; PROLOG-BLOCK-NEXT: %5 = load i32, ptr %arrayidx.1, align 4 |
| ; PROLOG-BLOCK-NEXT: %add.1 = add nsw i32 %5, %add |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp eq i64 %n, 42 |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %latchExit.unr-lcssa.loopexit, label %latch.1 |
| ; PROLOG-BLOCK: latch.1: |
| ; PROLOG-BLOCK-NEXT: %indvars.iv.next.1 = add i64 %indvars.iv, 2 |
| ; PROLOG-BLOCK-NEXT: %exitcond.1 = icmp eq i64 %indvars.iv.next.1, %n |
| ; PROLOG-BLOCK-NEXT: br i1 %exitcond.1, label %latchExit.unr-lcssa.loopexit, label %header, !llvm.loop !7 |
| ; PROLOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.ph.ph = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %for.exiting_block.1 ], [ %add.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latchExit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %result.ph = phi i32 [ 0, %for.exiting_block.prol ], [ %result.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit |
| ; PROLOG-BLOCK: latchExit: |
| ; PROLOG-BLOCK-NEXT: %result = phi i32 [ %result.unr, %header.prol.loopexit ], [ %result.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i32 %result |
| ; PROLOG-BLOCK: for.exit2.loopexit: |
| ; PROLOG-BLOCK-NEXT: br label %for.exit2 |
| ; PROLOG-BLOCK: for.exit2: |
| ; PROLOG-BLOCK-NEXT: ret i32 42 |
| ; |
| |
| entry: |
| br label %header |
| |
| header: |
| %indvars.iv = phi i64 [ %indvars.iv.next, %latch ], [ 0, %entry ] |
| %sum.02 = phi i32 [ %add, %latch ], [ 0, %entry ] |
| br i1 %cond, label %for.exit2, label %for.exiting_block |
| |
| for.exiting_block: |
| %arrayidx = getelementptr inbounds i32, ptr %a, i64 %indvars.iv |
| %0 = load i32, ptr %arrayidx, align 4 |
| %add = add nsw i32 %0, %sum.02 |
| %cmp = icmp eq i64 %n, 42 |
| br i1 %cmp, label %latchExit, label %latch |
| |
| latch: ; preds = %latch, %entry |
| %indvars.iv.next = add i64 %indvars.iv, 1 |
| %exitcond = icmp eq i64 %indvars.iv.next, %n |
| br i1 %exitcond, label %latchExit, label %header |
| |
| latchExit: ; preds = %latch, %entry |
| %result = phi i32 [ %sum.02, %for.exiting_block ], [ %add, %latch ] |
| ret i32 %result |
| |
| for.exit2: |
| ret i32 42 |
| } |
| |
| ; Show a case where we have multiple exits, but (provably) exit on the |
| ; first iteration and thus have nothing to unroll |
| define void @non_loop(i32 %arg) { |
| ; CHECK-LABEL: @non_loop( |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: %i = icmp sgt i32 undef, %arg |
| ; CHECK-NEXT: br i1 %i, label %preheader, label %returnblock |
| ; CHECK: preheader: |
| ; CHECK-NEXT: br label %header |
| ; CHECK: header: |
| ; CHECK-NEXT: br i1 true, label %latchExit, label %latch |
| ; CHECK: latch: |
| ; CHECK-NEXT: br label %latchExit |
| ; CHECK: latchExit: |
| ; CHECK-NEXT: %i2.ph = phi i32 [ %arg, %header ], [ -1, %latch ] |
| ; CHECK-NEXT: br label %returnblock |
| ; CHECK: returnblock: |
| ; CHECK-NEXT: %i2 = phi i32 [ -1, %entry ], [ %i2.ph, %latchExit ] |
| ; CHECK-NEXT: ret void |
| ; |
| |
| entry: |
| %i = icmp sgt i32 undef, %arg |
| br i1 %i, label %preheader, label %returnblock |
| |
| preheader: ; preds = %entry |
| br label %header |
| |
| header: ; preds = %preheader, %latch |
| %i4 = phi i32 [ %inc, %latch ], [ %arg, %preheader ] |
| %inc = add nsw i32 %i4, 1 |
| br i1 true, label %latchExit, label %latch |
| |
| latch: ; preds = %header |
| %cmp = icmp slt i32 %inc, undef |
| br i1 %cmp, label %header, label %latchExit |
| |
| latchExit: ; preds = %header, %latch |
| %i2.ph = phi i32 [ %i4, %header ], [ -1, %latch ] |
| br label %returnblock |
| |
| returnblock: ; preds = %latchExit, %entry |
| %i2 = phi i32 [ -1, %entry ], [ %i2.ph, %latchExit ] |
| ret void |
| } |
| |
| ; Latch exit is shared by all exiting blocks |
| define void @unique_exit(i32 %N, i32 %M) { |
| ; EPILOG-LABEL: @unique_exit( |
| ; EPILOG-NEXT: preheader: |
| ; EPILOG-NEXT: %M.shifted = shl i32 %M, 3 |
| ; EPILOG-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) |
| ; EPILOG-NEXT: %0 = freeze i32 %umax |
| ; EPILOG-NEXT: %1 = add i32 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i32 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i32 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %preheader.new |
| ; EPILOG: preheader.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i32 %0, %xtraiter |
| ; EPILOG-NEXT: br label %header |
| ; EPILOG: header: |
| ; EPILOG-NEXT: %i4 = phi i32 [ 0, %preheader.new ], [ %inc.7, %latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i32 [ 0, %preheader.new ], [ %niter.next.7, %latch.7 ] |
| ; EPILOG-NEXT: %inc = add nuw nsw i32 %i4, 1 |
| ; EPILOG-NEXT: %cmp1 = icmp ult i32 %inc, %N |
| ; EPILOG-NEXT: br i1 %cmp1, label %latch, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch: |
| ; EPILOG-NEXT: %inc.1 = add nuw nsw i32 %i4, 2 |
| ; EPILOG-NEXT: %cmp1.1 = icmp ult i32 %inc.1, %N |
| ; EPILOG-NEXT: br i1 %cmp1.1, label %latch.1, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.1: |
| ; EPILOG-NEXT: %inc.2 = add nuw nsw i32 %i4, 3 |
| ; EPILOG-NEXT: %cmp1.2 = icmp ult i32 %inc.2, %N |
| ; EPILOG-NEXT: br i1 %cmp1.2, label %latch.2, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.2: |
| ; EPILOG-NEXT: %inc.3 = add nuw nsw i32 %i4, 4 |
| ; EPILOG-NEXT: %cmp1.3 = icmp ult i32 %inc.3, %N |
| ; EPILOG-NEXT: br i1 %cmp1.3, label %latch.3, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.3: |
| ; EPILOG-NEXT: %inc.4 = add nuw nsw i32 %i4, 5 |
| ; EPILOG-NEXT: %cmp1.4 = icmp ult i32 %inc.4, %N |
| ; EPILOG-NEXT: br i1 %cmp1.4, label %latch.4, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.4: |
| ; EPILOG-NEXT: %inc.5 = add nuw nsw i32 %i4, 6 |
| ; EPILOG-NEXT: %cmp1.5 = icmp ult i32 %inc.5, %N |
| ; EPILOG-NEXT: br i1 %cmp1.5, label %latch.5, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.5: |
| ; EPILOG-NEXT: %inc.6 = add nuw nsw i32 %i4, 7 |
| ; EPILOG-NEXT: %cmp1.6 = icmp ult i32 %inc.6, %N |
| ; EPILOG-NEXT: br i1 %cmp1.6, label %latch.6, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.6: |
| ; EPILOG-NEXT: %inc.7 = add nuw i32 %i4, 8 |
| ; EPILOG-NEXT: %cmp1.7 = icmp ult i32 %inc.7, %N |
| ; EPILOG-NEXT: br i1 %cmp1.7, label %latch.7, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG: latch.7: |
| ; EPILOG-NEXT: %niter.next.7 = add nuw i32 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp ne i32 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %header, label %latchExit.unr-lcssa.loopexit |
| ; EPILOG: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %i2.ph.ph.ph = phi i32 [ -1, %latch.7 ] |
| ; EPILOG-NEXT: %i4.unr.ph = phi i32 [ %inc.7, %latch.7 ] |
| ; EPILOG-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG: latchExit.unr-lcssa: |
| ; EPILOG-NEXT: %i2.ph.ph = phi i32 [ undef, %preheader ], [ %i2.ph.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %i4.unr = phi i32 [ 0, %preheader ], [ %i4.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG: header.epil.preheader: |
| ; EPILOG-NEXT: br label %header.epil |
| ; EPILOG: header.epil: |
| ; EPILOG-NEXT: %i4.epil = phi i32 [ %inc.epil, %latch.epil ], [ %i4.unr, %header.epil.preheader ] |
| ; EPILOG-NEXT: %epil.iter = phi i32 [ 0, %header.epil.preheader ], [ %epil.iter.next, %latch.epil ] |
| ; EPILOG-NEXT: %inc.epil = add nuw i32 %i4.epil, 1 |
| ; EPILOG-NEXT: %cmp1.epil = icmp ult i32 %inc.epil, %N |
| ; EPILOG-NEXT: br i1 %cmp1.epil, label %latch.epil, label %latchExit.epilog-lcssa.loopexit2 |
| ; EPILOG: latch.epil: |
| ; EPILOG-NEXT: %cmp.epil = icmp ult i32 %inc.epil, %M.shifted |
| ; EPILOG-NEXT: %epil.iter.next = add i32 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i32 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %header.epil, label %latchExit.epilog-lcssa.loopexit2, !llvm.loop !8 |
| ; EPILOG: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-NEXT: %i2.ph.ph1.ph = phi i32 [ %i4, %header ], [ %inc, %latch ], [ %inc.1, %latch.1 ], [ %inc.2, %latch.2 ], [ %inc.3, %latch.3 ], [ %inc.4, %latch.4 ], [ %inc.5, %latch.5 ], [ %inc.6, %latch.6 ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa.loopexit2: |
| ; EPILOG-NEXT: %i2.ph.ph1.ph3 = phi i32 [ %i4.epil, %header.epil ], [ -1, %latch.epil ] |
| ; EPILOG-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG: latchExit.epilog-lcssa: |
| ; EPILOG-NEXT: %i2.ph.ph1 = phi i32 [ %i2.ph.ph1.ph, %latchExit.epilog-lcssa.loopexit ], [ %i2.ph.ph1.ph3, %latchExit.epilog-lcssa.loopexit2 ] |
| ; EPILOG-NEXT: br label %latchExit |
| ; EPILOG: latchExit: |
| ; EPILOG-NEXT: %i2.ph = phi i32 [ %i2.ph.ph, %latchExit.unr-lcssa ], [ %i2.ph.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret void |
| ; |
| ; EPILOG-BLOCK-LABEL: @unique_exit( |
| ; EPILOG-BLOCK-NEXT: preheader: |
| ; EPILOG-BLOCK-NEXT: %M.shifted = shl i32 %M, 3 |
| ; EPILOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i32 %umax |
| ; EPILOG-BLOCK-NEXT: %1 = add i32 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i32 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i32 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchExit.unr-lcssa, label %preheader.new |
| ; EPILOG-BLOCK: preheader.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i32 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %header |
| ; EPILOG-BLOCK: header: |
| ; EPILOG-BLOCK-NEXT: %i4 = phi i32 [ 0, %preheader.new ], [ %inc.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i32 [ 0, %preheader.new ], [ %niter.next.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %inc = add nuw nsw i32 %i4, 1 |
| ; EPILOG-BLOCK-NEXT: %cmp1 = icmp ult i32 %inc, %N |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp1, label %latch, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG-BLOCK: latch: |
| ; EPILOG-BLOCK-NEXT: %inc.1 = add nuw i32 %i4, 2 |
| ; EPILOG-BLOCK-NEXT: %cmp1.1 = icmp ult i32 %inc.1, %N |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp1.1, label %latch.1, label %latchExit.epilog-lcssa.loopexit |
| ; EPILOG-BLOCK: latch.1: |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add nuw i32 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp ne i32 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %header, label %latchExit.unr-lcssa.loopexit, !llvm.loop !8 |
| ; EPILOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %i2.ph.ph.ph = phi i32 [ -1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %i4.unr.ph = phi i32 [ %inc.1, %latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; EPILOG-BLOCK: latchExit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %i2.ph.ph = phi i32 [ undef, %preheader ], [ %i2.ph.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %i4.unr = phi i32 [ 0, %preheader ], [ %i4.unr.ph, %latchExit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.epil.preheader, label %latchExit |
| ; EPILOG-BLOCK: header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %header.epil |
| ; EPILOG-BLOCK: header.epil: |
| ; EPILOG-BLOCK-NEXT: %inc.epil = add nuw i32 %i4.unr, 1 |
| ; EPILOG-BLOCK-NEXT: %cmp1.epil = icmp ult i32 %inc.epil, %N |
| ; EPILOG-BLOCK-NEXT: br i1 %cmp1.epil, label %latch.epil, label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latch.epil: |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %i2.ph.ph1.ph = phi i32 [ %i4, %header ], [ %inc, %latch ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit.epilog-lcssa |
| ; EPILOG-BLOCK: latchExit.epilog-lcssa: |
| ; EPILOG-BLOCK-NEXT: %i2.ph.ph1 = phi i32 [ -1, %latch.epil ], [ %i4.unr, %header.epil ], [ %i2.ph.ph1.ph, %latchExit.epilog-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: br label %latchExit |
| ; EPILOG-BLOCK: latchExit: |
| ; EPILOG-BLOCK-NEXT: %i2.ph = phi i32 [ %i2.ph.ph, %latchExit.unr-lcssa ], [ %i2.ph.ph1, %latchExit.epilog-lcssa ] |
| ; EPILOG-BLOCK-NEXT: ret void |
| ; |
| ; PROLOG-LABEL: @unique_exit( |
| ; PROLOG-NEXT: preheader: |
| ; PROLOG-NEXT: %M.shifted = shl i32 %M, 3 |
| ; PROLOG-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) |
| ; PROLOG-NEXT: %0 = freeze i32 %umax |
| ; PROLOG-NEXT: %1 = add i32 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i32 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG: header.prol.preheader: |
| ; PROLOG-NEXT: br label %header.prol |
| ; PROLOG: header.prol: |
| ; PROLOG-NEXT: %i4.prol = phi i32 [ %inc.prol, %latch.prol ], [ 0, %header.prol.preheader ] |
| ; PROLOG-NEXT: %prol.iter = phi i32 [ 0, %header.prol.preheader ], [ %prol.iter.next, %latch.prol ] |
| ; PROLOG-NEXT: %inc.prol = add nuw i32 %i4.prol, 1 |
| ; PROLOG-NEXT: %cmp1.prol = icmp ult i32 %inc.prol, %N |
| ; PROLOG-NEXT: br i1 %cmp1.prol, label %latch.prol, label %latchExit.unr-lcssa.loopexit1 |
| ; PROLOG: latch.prol: |
| ; PROLOG-NEXT: %cmp.prol = icmp ult i32 %inc.prol, %M.shifted |
| ; PROLOG-NEXT: %prol.iter.next = add i32 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i32 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %header.prol, label %header.prol.loopexit.unr-lcssa, !llvm.loop !8 |
| ; PROLOG: header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %i4.unr.ph = phi i32 [ %inc.prol, %latch.prol ] |
| ; PROLOG-NEXT: %i2.ph.unr.ph = phi i32 [ -1, %latch.prol ] |
| ; PROLOG-NEXT: br label %header.prol.loopexit |
| ; PROLOG: header.prol.loopexit: |
| ; PROLOG-NEXT: %i4.unr = phi i32 [ 0, %preheader ], [ %i4.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %i2.ph.unr = phi i32 [ undef, %preheader ], [ %i2.ph.unr.ph, %header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %2 = icmp ult i32 %1, 7 |
| ; PROLOG-NEXT: br i1 %2, label %latchExit, label %preheader.new |
| ; PROLOG: preheader.new: |
| ; PROLOG-NEXT: br label %header |
| ; PROLOG: header: |
| ; PROLOG-NEXT: %i4 = phi i32 [ %i4.unr, %preheader.new ], [ %inc.7, %latch.7 ] |
| ; PROLOG-NEXT: %inc = add nuw i32 %i4, 1 |
| ; PROLOG-NEXT: %cmp1 = icmp ult i32 %inc, %N |
| ; PROLOG-NEXT: br i1 %cmp1, label %latch, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch: |
| ; PROLOG-NEXT: %inc.1 = add nuw i32 %i4, 2 |
| ; PROLOG-NEXT: %cmp1.1 = icmp ult i32 %inc.1, %N |
| ; PROLOG-NEXT: br i1 %cmp1.1, label %latch.1, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.1: |
| ; PROLOG-NEXT: %inc.2 = add nuw i32 %i4, 3 |
| ; PROLOG-NEXT: %cmp1.2 = icmp ult i32 %inc.2, %N |
| ; PROLOG-NEXT: br i1 %cmp1.2, label %latch.2, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.2: |
| ; PROLOG-NEXT: %inc.3 = add nuw i32 %i4, 4 |
| ; PROLOG-NEXT: %cmp1.3 = icmp ult i32 %inc.3, %N |
| ; PROLOG-NEXT: br i1 %cmp1.3, label %latch.3, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.3: |
| ; PROLOG-NEXT: %inc.4 = add nuw i32 %i4, 5 |
| ; PROLOG-NEXT: %cmp1.4 = icmp ult i32 %inc.4, %N |
| ; PROLOG-NEXT: br i1 %cmp1.4, label %latch.4, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.4: |
| ; PROLOG-NEXT: %inc.5 = add nuw i32 %i4, 6 |
| ; PROLOG-NEXT: %cmp1.5 = icmp ult i32 %inc.5, %N |
| ; PROLOG-NEXT: br i1 %cmp1.5, label %latch.5, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.5: |
| ; PROLOG-NEXT: %inc.6 = add nuw i32 %i4, 7 |
| ; PROLOG-NEXT: %cmp1.6 = icmp ult i32 %inc.6, %N |
| ; PROLOG-NEXT: br i1 %cmp1.6, label %latch.6, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.6: |
| ; PROLOG-NEXT: %inc.7 = add nuw i32 %i4, 8 |
| ; PROLOG-NEXT: %cmp1.7 = icmp ult i32 %inc.7, %N |
| ; PROLOG-NEXT: br i1 %cmp1.7, label %latch.7, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latch.7: |
| ; PROLOG-NEXT: %cmp.7 = icmp ult i32 %inc.7, %M.shifted |
| ; PROLOG-NEXT: br i1 %cmp.7, label %header, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-NEXT: %i2.ph.ph.ph = phi i32 [ %i4, %header ], [ %inc, %latch ], [ %inc.1, %latch.1 ], [ %inc.2, %latch.2 ], [ %inc.3, %latch.3 ], [ %inc.4, %latch.4 ], [ %inc.5, %latch.5 ], [ %inc.6, %latch.6 ], [ -1, %latch.7 ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa.loopexit1: |
| ; PROLOG-NEXT: %i2.ph.ph.ph2 = phi i32 [ %i4.prol, %header.prol ] |
| ; PROLOG-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG: latchExit.unr-lcssa: |
| ; PROLOG-NEXT: %i2.ph.ph = phi i32 [ %i2.ph.ph.ph, %latchExit.unr-lcssa.loopexit ], [ %i2.ph.ph.ph2, %latchExit.unr-lcssa.loopexit1 ] |
| ; PROLOG-NEXT: br label %latchExit |
| ; PROLOG: latchExit: |
| ; PROLOG-NEXT: %i2.ph = phi i32 [ %i2.ph.unr, %header.prol.loopexit ], [ %i2.ph.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-NEXT: ret void |
| ; |
| ; PROLOG-BLOCK-LABEL: @unique_exit( |
| ; PROLOG-BLOCK-NEXT: preheader: |
| ; PROLOG-BLOCK-NEXT: %M.shifted = shl i32 %M, 3 |
| ; PROLOG-BLOCK-NEXT: %umax = call i32 @llvm.umax.i32(i32 %M.shifted, i32 1) |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i32 %umax |
| ; PROLOG-BLOCK-NEXT: %1 = add i32 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i32 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i32 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %header.prol.preheader, label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol |
| ; PROLOG-BLOCK: header.prol: |
| ; PROLOG-BLOCK-NEXT: %cmp1.prol = icmp ult i32 1, %N |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp1.prol, label %latch.prol, label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latch.prol: |
| ; PROLOG-BLOCK-NEXT: br label %header.prol.loopexit |
| ; PROLOG-BLOCK: header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %i4.unr = phi i32 [ 0, %preheader ], [ 1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %i2.ph.unr = phi i32 [ undef, %preheader ], [ -1, %latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %2 = icmp ult i32 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %2, label %latchExit, label %preheader.new |
| ; PROLOG-BLOCK: preheader.new: |
| ; PROLOG-BLOCK-NEXT: br label %header |
| ; PROLOG-BLOCK: header: |
| ; PROLOG-BLOCK-NEXT: %i4 = phi i32 [ %i4.unr, %preheader.new ], [ %inc.1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %inc = add nuw i32 %i4, 1 |
| ; PROLOG-BLOCK-NEXT: %cmp1 = icmp ult i32 %inc, %N |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp1, label %latch, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG-BLOCK: latch: |
| ; PROLOG-BLOCK-NEXT: %inc.1 = add nuw i32 %i4, 2 |
| ; PROLOG-BLOCK-NEXT: %cmp1.1 = icmp ult i32 %inc.1, %N |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp1.1, label %latch.1, label %latchExit.unr-lcssa.loopexit |
| ; PROLOG-BLOCK: latch.1: |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp ult i32 %inc.1, %M.shifted |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %header, label %latchExit.unr-lcssa.loopexit, !llvm.loop !8 |
| ; PROLOG-BLOCK: latchExit.unr-lcssa.loopexit: |
| ; PROLOG-BLOCK-NEXT: %i2.ph.ph.ph = phi i32 [ %i4, %header ], [ %inc, %latch ], [ -1, %latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit.unr-lcssa |
| ; PROLOG-BLOCK: latchExit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %i2.ph.ph = phi i32 [ 0, %header.prol ], [ %i2.ph.ph.ph, %latchExit.unr-lcssa.loopexit ] |
| ; PROLOG-BLOCK-NEXT: br label %latchExit |
| ; PROLOG-BLOCK: latchExit: |
| ; PROLOG-BLOCK-NEXT: %i2.ph = phi i32 [ %i2.ph.unr, %header.prol.loopexit ], [ %i2.ph.ph, %latchExit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret void |
| ; |
| |
| preheader: |
| %M.shifted = shl nuw i32 %M, 3 |
| br label %header |
| |
| header: ; preds = %preheader, %latch |
| %i4 = phi i32 [ %inc, %latch ], [ 0, %preheader ] |
| %inc = add nuw i32 %i4, 1 |
| %cmp1 = icmp ult i32 %inc, %N |
| br i1 %cmp1, label %latch, label %latchExit |
| |
| latch: ; preds = %header |
| %cmp = icmp ult i32 %inc, %M.shifted |
| br i1 %cmp, label %header, label %latchExit |
| |
| latchExit: ; preds = %header, %latch |
| %i2.ph = phi i32 [ %i4, %header ], [ -1, %latch ] |
| ret void |
| } |
| |
| |
| ; two exiting and two exit blocks. |
| ; the non-latch exiting block has duplicate edges to the non-latch exit block. |
| define i64 @test5(i64 %trip, i64 %add, i1 %cond) { |
| ; EPILOG-LABEL: @test5( |
| ; EPILOG-NEXT: entry: |
| ; EPILOG-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; EPILOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; EPILOG-NEXT: br i1 %2, label %latchexit.unr-lcssa, label %entry.new |
| ; EPILOG: entry.new: |
| ; EPILOG-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-NEXT: br label %loop_header |
| ; EPILOG: loop_header: |
| ; EPILOG-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting |
| ; EPILOG: loop_exiting: |
| ; EPILOG-NEXT: %ivy = add i64 %iv, %add |
| ; EPILOG-NEXT: switch i64 %sum, label %loop_latch [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch: |
| ; EPILOG-NEXT: %iv_next = add nuw nsw i64 %iv, 1 |
| ; EPILOG-NEXT: %sum.next = add i64 %sum, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting.1 |
| ; EPILOG: loop_exiting.1: |
| ; EPILOG-NEXT: %ivy.1 = add i64 %iv_next, %add |
| ; EPILOG-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.1: |
| ; EPILOG-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; EPILOG-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.2, label %loop_exiting.2 |
| ; EPILOG: loop_exiting.2: |
| ; EPILOG-NEXT: %ivy.2 = add i64 %iv_next.1, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.1, label %loop_latch.2 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.2: |
| ; EPILOG-NEXT: %iv_next.2 = add nuw nsw i64 %iv, 3 |
| ; EPILOG-NEXT: %sum.next.2 = add i64 %sum.next.1, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.3, label %loop_exiting.3 |
| ; EPILOG: loop_exiting.3: |
| ; EPILOG-NEXT: %ivy.3 = add i64 %iv_next.2, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.2, label %loop_latch.3 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.3: |
| ; EPILOG-NEXT: %iv_next.3 = add nuw nsw i64 %iv, 4 |
| ; EPILOG-NEXT: %sum.next.3 = add i64 %sum.next.2, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.4, label %loop_exiting.4 |
| ; EPILOG: loop_exiting.4: |
| ; EPILOG-NEXT: %ivy.4 = add i64 %iv_next.3, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.3, label %loop_latch.4 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.4: |
| ; EPILOG-NEXT: %iv_next.4 = add nuw nsw i64 %iv, 5 |
| ; EPILOG-NEXT: %sum.next.4 = add i64 %sum.next.3, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.5, label %loop_exiting.5 |
| ; EPILOG: loop_exiting.5: |
| ; EPILOG-NEXT: %ivy.5 = add i64 %iv_next.4, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.4, label %loop_latch.5 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.5: |
| ; EPILOG-NEXT: %iv_next.5 = add nuw nsw i64 %iv, 6 |
| ; EPILOG-NEXT: %sum.next.5 = add i64 %sum.next.4, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.6, label %loop_exiting.6 |
| ; EPILOG: loop_exiting.6: |
| ; EPILOG-NEXT: %ivy.6 = add i64 %iv_next.5, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.5, label %loop_latch.6 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.6: |
| ; EPILOG-NEXT: %iv_next.6 = add nuw nsw i64 %iv, 7 |
| ; EPILOG-NEXT: %sum.next.6 = add i64 %sum.next.5, %add |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.7, label %loop_exiting.7 |
| ; EPILOG: loop_exiting.7: |
| ; EPILOG-NEXT: %ivy.7 = add i64 %iv_next.6, %add |
| ; EPILOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.7: |
| ; EPILOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 |
| ; EPILOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add |
| ; EPILOG-NEXT: %niter.next.7 = add i64 %niter, 8 |
| ; EPILOG-NEXT: %niter.ncmp.7 = icmp ne i64 %niter.next.7, %unroll_iter |
| ; EPILOG-NEXT: br i1 %niter.ncmp.7, label %loop_header, label %latchexit.unr-lcssa.loopexit |
| ; EPILOG: exit1.loopexit: |
| ; 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 ], [ %ivy.2, %loop_exiting.2 ], [ %ivy.3, %loop_exiting.3 ], [ %ivy.3, %loop_exiting.3 ], [ %ivy.4, %loop_exiting.4 ], [ %ivy.4, %loop_exiting.4 ], [ %ivy.5, %loop_exiting.5 ], [ %ivy.5, %loop_exiting.5 ], [ %ivy.6, %loop_exiting.6 ], [ %ivy.6, %loop_exiting.6 ], [ %ivy.7, %loop_exiting.7 ], [ %ivy.7, %loop_exiting.7 ] |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1.loopexit2: |
| ; EPILOG-NEXT: %result.ph3 = phi i64 [ %ivy.epil, %loop_exiting.epil ], [ %ivy.epil, %loop_exiting.epil ] |
| ; EPILOG-NEXT: br label %exit1 |
| ; EPILOG: exit1: |
| ; EPILOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %result.ph3, %exit1.loopexit2 ] |
| ; EPILOG-NEXT: ret i64 %result |
| ; EPILOG: latchexit.unr-lcssa.loopexit: |
| ; EPILOG-NEXT: %sum.next.lcssa.ph.ph = phi i64 [ %sum.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: %sum.unr.ph = phi i64 [ %sum.next.7, %loop_latch.7 ] |
| ; EPILOG-NEXT: br label %latchexit.unr-lcssa |
| ; EPILOG: latchexit.unr-lcssa: |
| ; EPILOG-NEXT: %sum.next.lcssa.ph = phi i64 [ undef, %entry ], [ %sum.next.lcssa.ph.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %latchexit |
| ; EPILOG: loop_header.epil.preheader: |
| ; EPILOG-NEXT: br label %loop_header.epil |
| ; EPILOG: loop_header.epil: |
| ; EPILOG-NEXT: %iv.epil = phi i64 [ %iv.unr, %loop_header.epil.preheader ], [ %iv_next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: %sum.epil = phi i64 [ %sum.unr, %loop_header.epil.preheader ], [ %sum.next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: %epil.iter = phi i64 [ 0, %loop_header.epil.preheader ], [ %epil.iter.next, %loop_latch.epil ] |
| ; EPILOG-NEXT: br i1 %cond, label %loop_latch.epil, label %loop_exiting.epil |
| ; EPILOG: loop_exiting.epil: |
| ; EPILOG-NEXT: %ivy.epil = add i64 %iv.epil, %add |
| ; EPILOG-NEXT: switch i64 %sum.epil, label %loop_latch.epil [ |
| ; EPILOG-NEXT: i64 24, label %exit1.loopexit2 |
| ; EPILOG-NEXT: i64 42, label %exit1.loopexit2 |
| ; EPILOG-NEXT: ] |
| ; EPILOG: loop_latch.epil: |
| ; EPILOG-NEXT: %iv_next.epil = add nuw nsw i64 %iv.epil, 1 |
| ; EPILOG-NEXT: %sum.next.epil = add i64 %sum.epil, %add |
| ; EPILOG-NEXT: %cmp.epil = icmp ne i64 %iv_next.epil, %trip |
| ; EPILOG-NEXT: %epil.iter.next = add i64 %epil.iter, 1 |
| ; EPILOG-NEXT: %epil.iter.cmp = icmp ne i64 %epil.iter.next, %xtraiter |
| ; EPILOG-NEXT: br i1 %epil.iter.cmp, label %loop_header.epil, label %latchexit.epilog-lcssa, !llvm.loop !9 |
| ; EPILOG: latchexit.epilog-lcssa: |
| ; EPILOG-NEXT: %sum.next.lcssa.ph1 = phi i64 [ %sum.next.epil, %loop_latch.epil ] |
| ; EPILOG-NEXT: br label %latchexit |
| ; EPILOG: latchexit: |
| ; EPILOG-NEXT: %sum.next.lcssa = phi i64 [ %sum.next.lcssa.ph, %latchexit.unr-lcssa ], [ %sum.next.lcssa.ph1, %latchexit.epilog-lcssa ] |
| ; EPILOG-NEXT: ret i64 %sum.next.lcssa |
| ; |
| ; EPILOG-BLOCK-LABEL: @test5( |
| ; EPILOG-BLOCK-NEXT: entry: |
| ; EPILOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; EPILOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; EPILOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; EPILOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; EPILOG-BLOCK-NEXT: br i1 %2, label %latchexit.unr-lcssa, label %entry.new |
| ; EPILOG-BLOCK: entry.new: |
| ; EPILOG-BLOCK-NEXT: %unroll_iter = sub i64 %0, %xtraiter |
| ; EPILOG-BLOCK-NEXT: br label %loop_header |
| ; EPILOG-BLOCK: loop_header: |
| ; EPILOG-BLOCK-NEXT: %iv = phi i64 [ 0, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum = phi i64 [ 0, %entry.new ], [ %sum.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %niter = phi i64 [ 0, %entry.new ], [ %niter.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting |
| ; EPILOG-BLOCK: loop_exiting: |
| ; EPILOG-BLOCK-NEXT: %ivy = add i64 %iv, %add |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum, label %loop_latch [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: loop_latch: |
| ; EPILOG-BLOCK-NEXT: %iv_next = add nuw nsw i64 %iv, 1 |
| ; EPILOG-BLOCK-NEXT: %sum.next = add i64 %sum, %add |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting.1 |
| ; EPILOG-BLOCK: loop_exiting.1: |
| ; EPILOG-BLOCK-NEXT: %ivy.1 = add i64 %iv_next, %add |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit1.loopexit |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: loop_latch.1: |
| ; EPILOG-BLOCK-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; EPILOG-BLOCK-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; EPILOG-BLOCK-NEXT: %niter.next.1 = add i64 %niter, 2 |
| ; EPILOG-BLOCK-NEXT: %niter.ncmp.1 = icmp ne i64 %niter.next.1, %unroll_iter |
| ; EPILOG-BLOCK-NEXT: br i1 %niter.ncmp.1, label %loop_header, label %latchexit.unr-lcssa.loopexit, !llvm.loop !9 |
| ; EPILOG-BLOCK: exit1.loopexit: |
| ; EPILOG-BLOCK-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %exit1 |
| ; EPILOG-BLOCK: exit1: |
| ; EPILOG-BLOCK-NEXT: %result = phi i64 [ %ivy.epil, %loop_exiting.epil ], [ %ivy.epil, %loop_exiting.epil ], [ %result.ph, %exit1.loopexit ] |
| ; EPILOG-BLOCK-NEXT: ret i64 %result |
| ; EPILOG-BLOCK: latchexit.unr-lcssa.loopexit: |
| ; EPILOG-BLOCK-NEXT: %sum.next.lcssa.ph.ph = phi i64 [ %sum.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %iv.unr.ph = phi i64 [ %iv_next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: %sum.unr.ph = phi i64 [ %sum.next.1, %loop_latch.1 ] |
| ; EPILOG-BLOCK-NEXT: br label %latchexit.unr-lcssa |
| ; EPILOG-BLOCK: latchexit.unr-lcssa: |
| ; EPILOG-BLOCK-NEXT: %sum.next.lcssa.ph = phi i64 [ undef, %entry ], [ %sum.next.lcssa.ph.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %latchexit.unr-lcssa.loopexit ] |
| ; EPILOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; EPILOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.epil.preheader, label %latchexit |
| ; EPILOG-BLOCK: loop_header.epil.preheader: |
| ; EPILOG-BLOCK-NEXT: br label %loop_header.epil |
| ; EPILOG-BLOCK: loop_header.epil: |
| ; EPILOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.epil, label %loop_exiting.epil |
| ; EPILOG-BLOCK: loop_exiting.epil: |
| ; EPILOG-BLOCK-NEXT: %ivy.epil = add i64 %iv.unr, %add |
| ; EPILOG-BLOCK-NEXT: switch i64 %sum.unr, label %loop_latch.epil [ |
| ; EPILOG-BLOCK-NEXT: i64 24, label %exit1 |
| ; EPILOG-BLOCK-NEXT: i64 42, label %exit1 |
| ; EPILOG-BLOCK-NEXT: ] |
| ; EPILOG-BLOCK: loop_latch.epil: |
| ; EPILOG-BLOCK-NEXT: %sum.next.epil = add i64 %sum.unr, %add |
| ; EPILOG-BLOCK-NEXT: br label %latchexit |
| ; EPILOG-BLOCK: latchexit: |
| ; EPILOG-BLOCK-NEXT: %sum.next.lcssa = phi i64 [ %sum.next.lcssa.ph, %latchexit.unr-lcssa ], [ %sum.next.epil, %loop_latch.epil ] |
| ; EPILOG-BLOCK-NEXT: ret i64 %sum.next.lcssa |
| ; |
| ; PROLOG-LABEL: @test5( |
| ; PROLOG-NEXT: entry: |
| ; PROLOG-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-NEXT: %xtraiter = and i64 %0, 7 |
| ; PROLOG-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.preheader: |
| ; PROLOG-NEXT: br label %loop_header.prol |
| ; PROLOG: loop_header.prol: |
| ; PROLOG-NEXT: %iv.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %sum.prol = phi i64 [ 0, %loop_header.prol.preheader ], [ %sum.next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %prol.iter = phi i64 [ 0, %loop_header.prol.preheader ], [ %prol.iter.next, %loop_latch.prol ] |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting.prol |
| ; PROLOG: loop_exiting.prol: |
| ; PROLOG-NEXT: %ivy.prol = add i64 %iv.prol, %add |
| ; PROLOG-NEXT: switch i64 %sum.prol, label %loop_latch.prol [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit1 |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit1 |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.prol: |
| ; PROLOG-NEXT: %iv_next.prol = add nuw nsw i64 %iv.prol, 1 |
| ; PROLOG-NEXT: %sum.next.prol = add i64 %sum.prol, %add |
| ; PROLOG-NEXT: %cmp.prol = icmp ne i64 %iv_next.prol, %trip |
| ; PROLOG-NEXT: %prol.iter.next = add i64 %prol.iter, 1 |
| ; PROLOG-NEXT: %prol.iter.cmp = icmp ne i64 %prol.iter.next, %xtraiter |
| ; PROLOG-NEXT: br i1 %prol.iter.cmp, label %loop_header.prol, label %loop_header.prol.loopexit.unr-lcssa, !llvm.loop !9 |
| ; PROLOG: loop_header.prol.loopexit.unr-lcssa: |
| ; PROLOG-NEXT: %iv.unr.ph = phi i64 [ %iv_next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %sum.unr.ph = phi i64 [ %sum.next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: %sum.next.lcssa.unr.ph = phi i64 [ %sum.next.prol, %loop_latch.prol ] |
| ; PROLOG-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG: loop_header.prol.loopexit: |
| ; PROLOG-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ %iv.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %sum.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %sum.next.lcssa.unr = phi i64 [ undef, %entry ], [ %sum.next.lcssa.unr.ph, %loop_header.prol.loopexit.unr-lcssa ] |
| ; PROLOG-NEXT: %2 = icmp ult i64 %1, 7 |
| ; PROLOG-NEXT: br i1 %2, label %latchexit, label %entry.new |
| ; PROLOG: entry.new: |
| ; PROLOG-NEXT: br label %loop_header |
| ; PROLOG: loop_header: |
| ; PROLOG-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting |
| ; PROLOG: loop_exiting: |
| ; PROLOG-NEXT: %ivy = add i64 %iv, %add |
| ; PROLOG-NEXT: switch i64 %sum, label %loop_latch [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch: |
| ; PROLOG-NEXT: %iv_next = add nuw nsw i64 %iv, 1 |
| ; PROLOG-NEXT: %sum.next = add i64 %sum, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting.1 |
| ; PROLOG: loop_exiting.1: |
| ; PROLOG-NEXT: %ivy.1 = add i64 %iv_next, %add |
| ; PROLOG-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.1: |
| ; PROLOG-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; PROLOG-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.2, label %loop_exiting.2 |
| ; PROLOG: loop_exiting.2: |
| ; PROLOG-NEXT: %ivy.2 = add i64 %iv_next.1, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.1, label %loop_latch.2 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.2: |
| ; PROLOG-NEXT: %iv_next.2 = add nuw nsw i64 %iv, 3 |
| ; PROLOG-NEXT: %sum.next.2 = add i64 %sum.next.1, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.3, label %loop_exiting.3 |
| ; PROLOG: loop_exiting.3: |
| ; PROLOG-NEXT: %ivy.3 = add i64 %iv_next.2, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.2, label %loop_latch.3 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.3: |
| ; PROLOG-NEXT: %iv_next.3 = add nuw nsw i64 %iv, 4 |
| ; PROLOG-NEXT: %sum.next.3 = add i64 %sum.next.2, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.4, label %loop_exiting.4 |
| ; PROLOG: loop_exiting.4: |
| ; PROLOG-NEXT: %ivy.4 = add i64 %iv_next.3, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.3, label %loop_latch.4 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.4: |
| ; PROLOG-NEXT: %iv_next.4 = add nuw nsw i64 %iv, 5 |
| ; PROLOG-NEXT: %sum.next.4 = add i64 %sum.next.3, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.5, label %loop_exiting.5 |
| ; PROLOG: loop_exiting.5: |
| ; PROLOG-NEXT: %ivy.5 = add i64 %iv_next.4, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.4, label %loop_latch.5 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.5: |
| ; PROLOG-NEXT: %iv_next.5 = add nuw nsw i64 %iv, 6 |
| ; PROLOG-NEXT: %sum.next.5 = add i64 %sum.next.4, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.6, label %loop_exiting.6 |
| ; PROLOG: loop_exiting.6: |
| ; PROLOG-NEXT: %ivy.6 = add i64 %iv_next.5, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.5, label %loop_latch.6 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.6: |
| ; PROLOG-NEXT: %iv_next.6 = add nuw nsw i64 %iv, 7 |
| ; PROLOG-NEXT: %sum.next.6 = add i64 %sum.next.5, %add |
| ; PROLOG-NEXT: br i1 %cond, label %loop_latch.7, label %loop_exiting.7 |
| ; PROLOG: loop_exiting.7: |
| ; PROLOG-NEXT: %ivy.7 = add i64 %iv_next.6, %add |
| ; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 [ |
| ; PROLOG-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-NEXT: ] |
| ; PROLOG: loop_latch.7: |
| ; PROLOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 |
| ; PROLOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add |
| ; PROLOG-NEXT: %cmp.7 = icmp ne i64 %iv_next.7, %trip |
| ; PROLOG-NEXT: br i1 %cmp.7, label %loop_header, label %latchexit.unr-lcssa |
| ; PROLOG: exit1.loopexit: |
| ; 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 ], [ %ivy.2, %loop_exiting.2 ], [ %ivy.3, %loop_exiting.3 ], [ %ivy.3, %loop_exiting.3 ], [ %ivy.4, %loop_exiting.4 ], [ %ivy.4, %loop_exiting.4 ], [ %ivy.5, %loop_exiting.5 ], [ %ivy.5, %loop_exiting.5 ], [ %ivy.6, %loop_exiting.6 ], [ %ivy.6, %loop_exiting.6 ], [ %ivy.7, %loop_exiting.7 ], [ %ivy.7, %loop_exiting.7 ] |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1.loopexit1: |
| ; PROLOG-NEXT: %result.ph2 = phi i64 [ %ivy.prol, %loop_exiting.prol ], [ %ivy.prol, %loop_exiting.prol ] |
| ; PROLOG-NEXT: br label %exit1 |
| ; PROLOG: exit1: |
| ; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %result.ph2, %exit1.loopexit1 ] |
| ; PROLOG-NEXT: ret i64 %result |
| ; PROLOG: latchexit.unr-lcssa: |
| ; PROLOG-NEXT: %sum.next.lcssa.ph = phi i64 [ %sum.next.7, %loop_latch.7 ] |
| ; PROLOG-NEXT: br label %latchexit |
| ; PROLOG: latchexit: |
| ; PROLOG-NEXT: %sum.next.lcssa = phi i64 [ %sum.next.lcssa.unr, %loop_header.prol.loopexit ], [ %sum.next.lcssa.ph, %latchexit.unr-lcssa ] |
| ; PROLOG-NEXT: ret i64 %sum.next.lcssa |
| ; |
| ; PROLOG-BLOCK-LABEL: @test5( |
| ; PROLOG-BLOCK-NEXT: entry: |
| ; PROLOG-BLOCK-NEXT: %0 = freeze i64 %trip |
| ; PROLOG-BLOCK-NEXT: %1 = add i64 %0, -1 |
| ; PROLOG-BLOCK-NEXT: %xtraiter = and i64 %0, 1 |
| ; PROLOG-BLOCK-NEXT: %lcmp.mod = icmp ne i64 %xtraiter, 0 |
| ; PROLOG-BLOCK-NEXT: br i1 %lcmp.mod, label %loop_header.prol.preheader, label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.preheader: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol |
| ; PROLOG-BLOCK: loop_header.prol: |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.prol, label %loop_exiting.prol |
| ; PROLOG-BLOCK: loop_exiting.prol: |
| ; PROLOG-BLOCK-NEXT: switch i64 0, label %loop_latch.prol [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1 |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit1 |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: loop_latch.prol: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header.prol.loopexit |
| ; PROLOG-BLOCK: loop_header.prol.loopexit: |
| ; PROLOG-BLOCK-NEXT: %iv.unr = phi i64 [ 0, %entry ], [ 1, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.unr = phi i64 [ 0, %entry ], [ %add, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %sum.next.lcssa.unr = phi i64 [ undef, %entry ], [ %add, %loop_latch.prol ] |
| ; PROLOG-BLOCK-NEXT: %2 = icmp ult i64 %1, 1 |
| ; PROLOG-BLOCK-NEXT: br i1 %2, label %latchexit, label %entry.new |
| ; PROLOG-BLOCK: entry.new: |
| ; PROLOG-BLOCK-NEXT: br label %loop_header |
| ; PROLOG-BLOCK: loop_header: |
| ; PROLOG-BLOCK-NEXT: %iv = phi i64 [ %iv.unr, %entry.new ], [ %iv_next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: %sum = phi i64 [ %sum.unr, %entry.new ], [ %sum.next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch, label %loop_exiting |
| ; PROLOG-BLOCK: loop_exiting: |
| ; PROLOG-BLOCK-NEXT: %ivy = add i64 %iv, %add |
| ; PROLOG-BLOCK-NEXT: switch i64 %sum, label %loop_latch [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: loop_latch: |
| ; PROLOG-BLOCK-NEXT: %iv_next = add nuw nsw i64 %iv, 1 |
| ; PROLOG-BLOCK-NEXT: %sum.next = add i64 %sum, %add |
| ; PROLOG-BLOCK-NEXT: br i1 %cond, label %loop_latch.1, label %loop_exiting.1 |
| ; PROLOG-BLOCK: loop_exiting.1: |
| ; PROLOG-BLOCK-NEXT: %ivy.1 = add i64 %iv_next, %add |
| ; PROLOG-BLOCK-NEXT: switch i64 %sum.next, label %loop_latch.1 [ |
| ; PROLOG-BLOCK-NEXT: i64 24, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: i64 42, label %exit1.loopexit |
| ; PROLOG-BLOCK-NEXT: ] |
| ; PROLOG-BLOCK: loop_latch.1: |
| ; PROLOG-BLOCK-NEXT: %iv_next.1 = add nuw nsw i64 %iv, 2 |
| ; PROLOG-BLOCK-NEXT: %sum.next.1 = add i64 %sum.next, %add |
| ; PROLOG-BLOCK-NEXT: %cmp.1 = icmp ne i64 %iv_next.1, %trip |
| ; PROLOG-BLOCK-NEXT: br i1 %cmp.1, label %loop_header, label %latchexit.unr-lcssa, !llvm.loop !9 |
| ; PROLOG-BLOCK: exit1.loopexit: |
| ; PROLOG-BLOCK-NEXT: %result.ph = phi i64 [ %ivy, %loop_exiting ], [ %ivy, %loop_exiting ], [ %ivy.1, %loop_exiting.1 ], [ %ivy.1, %loop_exiting.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %exit1 |
| ; PROLOG-BLOCK: exit1: |
| ; PROLOG-BLOCK-NEXT: %result = phi i64 [ %add, %loop_exiting.prol ], [ %add, %loop_exiting.prol ], [ %result.ph, %exit1.loopexit ] |
| ; PROLOG-BLOCK-NEXT: ret i64 %result |
| ; PROLOG-BLOCK: latchexit.unr-lcssa: |
| ; PROLOG-BLOCK-NEXT: %sum.next.lcssa.ph = phi i64 [ %sum.next.1, %loop_latch.1 ] |
| ; PROLOG-BLOCK-NEXT: br label %latchexit |
| ; PROLOG-BLOCK: latchexit: |
| ; PROLOG-BLOCK-NEXT: %sum.next.lcssa = phi i64 [ %sum.next.lcssa.unr, %loop_header.prol.loopexit ], [ %sum.next.lcssa.ph, %latchexit.unr-lcssa ] |
| ; PROLOG-BLOCK-NEXT: ret i64 %sum.next.lcssa |
| ; |
| |
| entry: |
| br label %loop_header |
| |
| loop_header: |
| %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop_latch ] |
| %sum = phi i64 [ 0, %entry ], [ %sum.next, %loop_latch ] |
| br i1 %cond, label %loop_latch, label %loop_exiting |
| |
| loop_exiting: |
| %ivy = add i64 %iv, %add |
| switch i64 %sum, label %loop_latch [ |
| i64 24, label %exit1 |
| i64 42, label %exit1 |
| ] |
| |
| loop_latch: |
| %iv_next = add <
|