Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -1201,6 +1201,28 @@ 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; + } + assert(I); + return I; + }; + + auto GetFirstValidInstructionInBB = + [&GetFirstValidInstruction](BasicBlock *BB) { + return GetFirstValidInstruction(BB->getFirstNonPHIOrDbgOrLifetime()); + }; + auto TryResolveConstant = [&ResolvedValues](Value *V) { auto It = ResolvedValues.find(V); if (It != ResolvedValues.end()) @@ -1209,8 +1231,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 +1248,7 @@ if (I == InitialInst) UnconditionalSucc = Succ; scanPHIsAndUpdateValueMap(I, Succ, ResolvedValues); - I = Succ->getFirstNonPHIOrDbgOrLifetime(); + I = GetFirstValidInstructionInBB(Succ); continue; } @@ -1245,9 +1266,8 @@ continue; } } 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 +1300,10 @@ BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor(); scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); - I = BB->getFirstNonPHIOrDbgOrLifetime(); + I = GetFirstValidInstructionInBB(BB); continue; } + return false; } return false; Index: llvm/test/Transforms/Coroutines/coro-split-musttail5.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-split-musttail5.ll +++ 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 Index: llvm/test/Transforms/Coroutines/coro-split-musttail6.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-split-musttail6.ll +++ llvm/test/Transforms/Coroutines/coro-split-musttail6.ll @@ -43,7 +43,8 @@ ; 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 +93,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 Index: llvm/test/Transforms/Coroutines/coro-split-musttail7.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-split-musttail7.ll +++ llvm/test/Transforms/Coroutines/coro-split-musttail7.ll @@ -44,7 +44,8 @@ ; 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 +95,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