diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp index c0e956840f989..e740c2819fec9 100644 --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -307,7 +307,19 @@ void llvm::spliceBB(IRBuilderBase::InsertPoint IP, BasicBlock *New, // Move instructions to new block. BasicBlock *Old = IP.getBlock(); - New->splice(New->begin(), Old, IP.getPoint(), Old->end()); + // If the `Old` block is empty then there are no instructions to move. But in + // the new debug scheme, it could have trailing debug records which will be + // moved to `New` in `spliceDebugInfoEmptyBlock`. We dont want that for 2 + // reasons: + // 1. If `New` is also empty, `BasicBlock::splice` crashes. + // 2. Even if `New` is not empty, the rationale to move those records to `New` + // (in `spliceDebugInfoEmptyBlock`) does not apply here. That function + // assumes that `Old` is optimized out and is going away. This is not the case + // here. The `Old` block is still being used e.g. a branch instruction is + // added to it later in this function. + // So we call `BasicBlock::splice` only when `Old` is not empty. + if (!Old->empty()) + New->splice(New->begin(), Old, IP.getPoint(), Old->end()); if (CreateBranch) { auto *NewBr = BranchInst::Create(New, Old); diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp index b7a060bb3563d..c13570dc803b3 100644 --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -7852,4 +7852,28 @@ TEST_F(OpenMPIRBuilderTest, splitBB) { EXPECT_TRUE(DL == AllocaBB->getTerminator()->getStableDebugLoc()); } +TEST_F(OpenMPIRBuilderTest, spliceBBWithEmptyBB) { + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.Config.IsTargetDevice = false; + OMPBuilder.initialize(); + F->setName("func"); + IRBuilder<> Builder(BB); + + // Test calling spliceBB with an empty Block (but having trailing debug + // records). + DIBuilder DIB(*M); + DISubprogram *SP = F->getSubprogram(); + DIType *VoidPtrTy = + DIB.createQualifiedType(dwarf::DW_TAG_pointer_type, nullptr); + DILocalVariable *Var = DIB.createParameterVariable( + SP, "test", /*ArgNo*/ 1, SP->getFile(), /*LineNo=*/0, VoidPtrTy); + DIB.insertDeclare(F->getArg(0), Var, DIB.createExpression(), DL, + Builder.GetInsertPoint()); + BasicBlock *New = BasicBlock::Create(Ctx, "", F); + spliceBB(Builder.saveIP(), New, true, DL); + Instruction *Terminator = BB->getTerminator(); + EXPECT_NE(Terminator, nullptr); + EXPECT_FALSE(Terminator->getDbgRecordRange().empty()); +} + } // namespace