diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -60,6 +60,20 @@ "simplifications still taking place"), cl::init(1.5)); +#ifndef NDEBUG +/// Return whether IP1 and IP2 are ambiguous, i.e. that inserting instructions +/// at position IP1 may change the meaning of IP2 or vice-versa. This is because +/// an InsertPoint stores the instruction before something is inserted. For +/// instance, if both point to the same instruction, two IRBuilders alternating +/// creating instruction will cause the instructions to be interleaved. +static bool isConflictIP(IRBuilder<>::InsertPoint IP1, + IRBuilder<>::InsertPoint IP2) { + if (!IP1.isSet() || !IP2.isSet()) + return false; + return IP1.getBlock() == IP2.getBlock() && IP1.getPoint() == IP2.getPoint(); +} +#endif + void OpenMPIRBuilder::addAttributes(omp::RuntimeFunction FnID, Function &Fn) { LLVMContext &Ctx = Fn.getContext(); @@ -527,6 +541,8 @@ BodyGenCallbackTy BodyGenCB, PrivatizeCallbackTy PrivCB, FinalizeCallbackTy FiniCB, Value *IfCondition, Value *NumThreads, omp::ProcBindKind ProcBind, bool IsCancellable) { + assert(!isConflictIP(Loc.IP, OuterAllocaIP) && "IPs must not be ambiguous"); + if (!updateToLocation(Loc)) return Loc.IP; diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -483,6 +483,9 @@ F->setName("func"); IRBuilder<> Builder(BB); + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); AllocaInst *PrivAI = nullptr; @@ -589,6 +592,9 @@ F->setName("func"); IRBuilder<> Builder(BB); + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); unsigned NumInnerBodiesGenerated = 0; @@ -682,6 +688,9 @@ F->setName("func"); IRBuilder<> Builder(BB); + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); unsigned NumInnerBodiesGenerated = 0; @@ -790,6 +799,9 @@ F->setName("func"); IRBuilder<> Builder(BB); + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); AllocaInst *PrivAI = nullptr; @@ -913,6 +925,9 @@ F->setName("func"); IRBuilder<> Builder(BB); + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); unsigned NumBodiesGenerated = 0; @@ -3108,6 +3123,10 @@ OMPBuilder.initialize(); F->setName("func"); IRBuilder<> Builder(BB); + + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); // Create variables to be reduced. @@ -3345,6 +3364,10 @@ OMPBuilder.initialize(); F->setName("func"); IRBuilder<> Builder(BB); + + BasicBlock *EnterBB = BasicBlock::Create(Ctx, "parallel.enter", F); + Builder.CreateBr(EnterBB); + Builder.SetInsertPoint(EnterBB); OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL}); // Create variables to be reduced. diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -249,6 +249,19 @@ // TODO: Is the Parallel construct cancellable? bool isCancellable = false; + // Ensure that the BasicBlock for the the parallel region is sparate from the + // function entry which we may need to insert allocas. + if (builder.GetInsertBlock() == + &builder.GetInsertBlock()->getParent()->getEntryBlock()) { + assert(builder.GetInsertPoint() == builder.GetInsertBlock()->end() && + "Assuming end of basic block"); + llvm::BasicBlock *entryBB = + llvm::BasicBlock::Create(builder.getContext(), "parallel.entry", + builder.GetInsertBlock()->getParent(), + builder.GetInsertBlock()->getNextNode()); + builder.CreateBr(entryBB); + builder.SetInsertPoint(entryBB); + } llvm::OpenMPIRBuilder::LocationDescription ompLoc( builder.saveIP(), builder.getCurrentDebugLocation()); builder.restoreIP(moduleTranslation.getOpenMPBuilder()->createParallel(