diff --git a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp --- a/llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1201,6 +1201,22 @@ assert(InitialInst->getModule()); const DataLayout &DL = InitialInst->getModule()->getDataLayout(); + auto GetFirstValidInstruction = [](Instruction *I) { + while (I) { + // BitCastInst wouldn't generate actual code so that we could skip it. + if (isa(I) || I->isDebugOrPseudoInst() || + I->isLifetimeStartOrEnd()) + I = I->getNextNode(); + else if (isInstructionTriviallyDead(I)) + // Duing we are in the middle of the transformation, we need to erase + // the dead instruction manually. + I = &*I->eraseFromParent(); + else + break; + } + return I; + }; + auto TryResolveConstant = [&ResolvedValues](Value *V) { auto It = ResolvedValues.find(V); if (It != ResolvedValues.end()) @@ -1209,8 +1225,7 @@ }; Instruction *I = InitialInst; - while (I->isTerminator() || - (isa(I) && I->getNextNode()->isTerminator())) { + while (I->isTerminator() || isa(I)) { if (isa(I)) { if (I != InitialInst) { // If InitialInst is an unconditional branch, @@ -1227,7 +1242,7 @@ if (I == InitialInst) UnconditionalSucc = Succ; scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues); - I = Succ->getFirstNonPHIOrDbgOrLifetime(); + I = GetFirstValidInstruction(Succ->getFirstNonPHIOrDbgOrLifetime()); continue; } @@ -1247,7 +1262,8 @@ } else if (auto *CondCmp = dyn_cast(I)) { // If the case number of suspended switch instruction is reduced to // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator. - auto *BR = dyn_cast(I->getNextNode()); + auto *BR = dyn_cast( + GetFirstValidInstruction(CondCmp->getNextNode())); if (!BR || !BR->isConditional() || CondCmp != BR->getCondition()) return false; @@ -1280,9 +1296,10 @@ BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor(); scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); - I = BB->getFirstNonPHIOrDbgOrLifetime(); + I = GetFirstValidInstruction(BB->getFirstNonPHIOrDbgOrLifetime()); continue; } + return false; } return false; diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll --- a/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail5.ll @@ -36,10 +36,10 @@ ret void } -; FIXME: The fakeresume1 here should be marked as musttail. ; Verify that in the resume part resume call is marked with musttail. ; CHECK-LABEL: @g.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK-NEXT: ret void declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1 declare i1 @llvm.coro.alloc(token) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll --- a/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail6.ll @@ -40,10 +40,10 @@ ret void } -; FIXME: The fakeresume1 here should be marked as musttail. ; Verify that in the resume part resume call is marked with musttail. ; CHECK-LABEL: @g.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK-NEXT: ret void ; It has a cleanup bb. define void @f() #0 { @@ -92,7 +92,8 @@ ; FIXME: The fakeresume1 here should be marked as musttail. ; Verify that in the resume part resume call is marked with musttail. ; CHECK-LABEL: @f.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK-NEXT: ret void declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1 declare i1 @llvm.coro.alloc(token) #2 diff --git a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll --- a/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll +++ b/llvm/test/Transforms/Coroutines/coro-split-musttail7.ll @@ -41,10 +41,10 @@ ret void } -; FIXME: The fakeresume1 here should be marked as musttail. ; Verify that in the resume part resume call is marked with musttail. ; CHECK-LABEL: @g.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK-NEXT: ret void ; It has a cleanup bb. define void @f() #0 { @@ -94,7 +94,8 @@ ; FIXME: The fakeresume1 here should be marked as musttail. ; Verify that in the resume part resume call is marked with musttail. ; CHECK-LABEL: @f.resume( -; CHECK-NOT: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK: musttail call fastcc void @fakeresume1(i64* align 8 null) +; CHECK-NEXT: ret void declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #1 declare i1 @llvm.coro.alloc(token) #2