aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
diff options
context:
space:
mode:
authorAbid Qadeer <haqadeer@amd.com>2025-08-29 16:56:26 +0100
committerGitHub <noreply@github.com>2025-08-29 16:56:26 +0100
commit4159fd819a89cb18e03a91576372ae257ee5fbc7 (patch)
tree0fc1e8d9846077f427c4575889fe4fba6eda87d5 /llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
parent260ee975fcb43621c1979848dc02ebad7bece350 (diff)
downloadllvm-4159fd819a89cb18e03a91576372ae257ee5fbc7.zip
llvm-4159fd819a89cb18e03a91576372ae257ee5fbc7.tar.gz
llvm-4159fd819a89cb18e03a91576372ae257ee5fbc7.tar.bz2
[OMPIRBuilder] Avoid crash in BasicBlock::splice. (#154987)
Calling `BasicBlock::splice` in `spliceBB` when both `Old` and `New` are empty is a `nop` currently but it can cause a crash once debug records are used instead of debug intrinsics. This PR makes the call conditional on at least one of `Old` or `New` being non-empty. Consider the following mlir: ``` omp.target map_entries() { llvm.intr.dbg.declare ... llvm.intr.dbg.declare ... omp.teams ... ... } ``` Current code would translate llvm.intr Ops to llvm intrinsics. Old is the BasicBlock where they were get inserted and it will have 2 llvm debug intrinsics by the time the implementation of `omp.teams` starts. This implementation creates many BasicBlocks by calling `splitBB`. The `New` is the just created BasicBlock which is empty. In the new scheme (using debug records), there will be no instruction in the `Old` BB after llvm.intr Ops get translated but just 2 trailing debug records. So both `Old` and `New` are empty. When control reaches `BasicBlock::splice`, it calls `spliceDebugInfoEmptyBlock`. This function expects that in this case (`Src` is empty but has trailing debug records), the `ToIt` is valid and it can call `adoptDbgRecords` on it. This assumption is not true in this case as `New` is empty and `ToIt` is pointing to end(). The fix is to only call `BasicBlock::splice` when at least of `Old` or `New` is not empty.
Diffstat (limited to 'llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp')
-rw-r--r--llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
index b7a060b..c13570d 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