diff options
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll | 44 |
2 files changed, 51 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 01c9362e4a4..c03fa153678 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -782,11 +782,15 @@ bool llvm::UnrollRuntimeLoopRemainder(Loop *L, unsigned Count, // Add the incoming values from the remainder code to the end of the phi // node. for (unsigned i =0; i < oldNumOperands; i++){ - Value *newVal = VMap[Phi->getIncomingValue(i)]; + Value *newVal = VMap.lookup(Phi->getIncomingValue(i)); // newVal can be a constant or derived from values outside the loop, and - // hence need not have a VMap value. - if (!newVal) + // hence need not have a VMap value. Also, since lookup already generated + // a default "null" VMap entry for this value, we need to populate that + // VMap entry correctly, with the mapped entry being itself. + if (!newVal) { newVal = Phi->getIncomingValue(i); + VMap[Phi->getIncomingValue(i)] = Phi->getIncomingValue(i); + } Phi->addIncoming(newVal, cast<BasicBlock>(VMap[Phi->getIncomingBlock(i)])); } diff --git a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll index 73672e14f78..ef983dffcd2 100644 --- a/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll @@ -4,6 +4,8 @@ ; RUN: opt < %s -loop-unroll -unroll-runtime=true -unroll-runtime-epilog=false -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine -S | FileCheck %s -check-prefix=PROLOG ; RUN: opt < %s -loop-unroll -unroll-runtime -unroll-runtime-epilog=false -unroll-count=2 -unroll-runtime-multi-exit=true -verify-dom-info -verify-loop-info -instcombine +; REQUIRES: asserts + ; the third and fifth RUNs generate an epilog/prolog remainder block for all the test ; cases below (it does not generate a loop). @@ -478,3 +480,45 @@ latch: ; preds = %innerH exit: ; preds = %latch ret void } + +declare i8 addrspace(1)* @foo(i32) +; inner loop prolog unrolled +; a value from outer loop is used in exit block of inner loop. +; Don't create VMap entries for such values (%trip). +define i8 addrspace(1)* @test9(i8* nocapture readonly %arg, i32 %n) { +; PROLOG: test9( +; PROLOG: header.prol: +; PROLOG-NEXT: %phi.prol = phi i64 [ 0, %header.prol.preheader ], [ %iv.next.prol, %latch.prol ] +; PROLOG: latch.prol: +; PROLOG-NOT: trip +; PROLOG: br i1 %prol.iter.cmp, label %header.prol.loopexit.unr-lcssa, label %header.prol +bb: + br label %outerloopHdr + +outerloopHdr: ; preds = %outerLatch, %bb + %trip = add i32 %n, -1 + %outercnd = icmp slt i32 0, %trip + br i1 %outercnd, label %preheader, label %outerLatch + +preheader: ; preds = %outerloopHdr + %tmp4 = zext i32 0 to i64 + br label %header + +header: ; preds = %latch, %preheader + %phi = phi i64 [ %tmp4, %preheader ], [ %iv.next, %latch ] + %tmp7 = trunc i64 %phi to i32 + br i1 true, label %latch, label %innerexit + +innerexit: ; preds = %header + %tmp9 = call i8 addrspace(1)* @foo(i32 %trip) + ret i8 addrspace(1)* %tmp9 + +latch: ; preds = %header + %tmp11 = add nsw i32 %tmp7, 1 + %innercnd = icmp slt i32 %tmp11, %trip + %iv.next = add nuw nsw i64 %phi, 1 + br i1 %innercnd, label %header, label %outerLatch + +outerLatch: ; preds = %latch, %outerloopHdr + br label %outerloopHdr +} |