Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions clang/test/OpenMP/cancel_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,16 +811,16 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE23_SECTION_AFTER:%.*]]
// CHECK3: omp_section_loop.body.case23.section.after:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
// CHECK3: omp_section_loop.body.case25:
// CHECK3: omp_section_loop.body.case26:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM27:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM27]], i32 3)
// CHECK3-NEXT: [[TMP19:%.*]] = icmp eq i32 [[TMP18]], 0
// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_SECTION_LOOP_BODY_CASE25_SPLIT:%.*]], label [[OMP_SECTION_LOOP_BODY_CASE25_CNCL:%.*]]
// CHECK3: omp_section_loop.body.case25.split:
// CHECK3: omp_section_loop.body.case26.split:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER26:%.*]]
// CHECK3: omp_section_loop.body.case25.section.after26:
// CHECK3: omp_section_loop.body.case26.section.after27:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY_CASE25_SECTION_AFTER:%.*]]
// CHECK3: omp_section_loop.body.case25.section.after:
// CHECK3: omp_section_loop.body.case26.section.after:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_BODY16_SECTIONS_AFTER]]
// CHECK3: omp_section_loop.body16.sections.after:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_INC17]]
Expand Down Expand Up @@ -891,10 +891,12 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .cancel.exit:
// CHECK3-NEXT: br label [[CANCEL_EXIT:%.*]]
// CHECK3: omp_section_loop.body.case.cncl:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT]]
// CHECK3: omp_section_loop.body.case23.cncl:
// CHECK3-NEXT: br label [[FINI10:.*]]
// CHECK3: .fini25:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]]
// CHECK3: omp_section_loop.body.case25.cncl:
// CHECK3: omp_section_loop.body.case26.cncl:
// CHECK3-NEXT: br label [[FINI29:.*]]
// CHECK3: .fini29:
// CHECK3-NEXT: br label [[OMP_SECTION_LOOP_EXIT18]]
// CHECK3: .cancel.continue:
// CHECK3-NEXT: br label [[OMP_IF_END:%.*]]
Expand Down Expand Up @@ -967,8 +969,10 @@ for (int i = 0; i < argc; ++i) {
// CHECK3-NEXT: [[TMP8:%.*]] = call i32 @__kmpc_cancel_barrier(ptr @[[GLOB3:[0-9]+]], i32 [[OMP_GLOBAL_THREAD_NUM4]])
// CHECK3-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
// CHECK3-NEXT: br i1 [[TMP9]], label [[DOTCONT:%.*]], label [[DOTCNCL5:%.*]]
// CHECK3: .cncl5:
// CHECK3-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB:%.*]]
// CHECK3: .cncl4:
// CHECK3-NEXT: br label [[FINI:%.*]]
// CHECK3: .fini
// CHECK3-NEXT: br label %[[EXIT_STUB:omp.par.exit.exitStub]]
// CHECK3: .cont:
// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[LOADGEP_ARGC_ADDR]], align 4
// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[LOADGEP_ARGV_ADDR]], align 8
Expand All @@ -984,16 +988,14 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: omp.par.region.parallel.after:
// CHECK3-NEXT: br label [[OMP_PAR_PRE_FINALIZE:%.*]]
// CHECK3: omp.par.pre_finalize:
// CHECK3-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB]]
// CHECK3-NEXT: br label [[FINI]]
// CHECK3: 14:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP15:%.*]] = call i32 @__kmpc_cancel(ptr @[[GLOB1]], i32 [[OMP_GLOBAL_THREAD_NUM1]], i32 1)
// CHECK3-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], 0
// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTSPLIT:%.*]], label [[DOTCNCL:%.*]]
// CHECK3: .cncl:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM2:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
// CHECK3-NEXT: [[TMP17:%.*]] = call i32 @__kmpc_cancel_barrier(ptr @[[GLOB2]], i32 [[OMP_GLOBAL_THREAD_NUM2]])
// CHECK3-NEXT: br label [[OMP_PAR_OUTLINED_EXIT_EXITSTUB]]
// CHECK3-NEXT: br label [[FINI]]
// CHECK3: .split:
// CHECK3-NEXT: br label [[TMP4]]
// CHECK3: omp.par.exit.exitStub:
Expand Down Expand Up @@ -1089,7 +1091,7 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .omp.sections.case.split:
// CHECK3-NEXT: br label [[DOTOMP_SECTIONS_EXIT]]
// CHECK3: .omp.sections.case.cncl:
// CHECK3-NEXT: br label [[CANCEL_CONT:%.*]]
// CHECK3-NEXT: br label [[FINI:%.*]]
// CHECK3: .omp.sections.exit:
// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK3: omp.inner.for.inc:
Expand All @@ -1100,7 +1102,7 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: omp.inner.for.end:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB19:[0-9]+]])
// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB15]], i32 [[OMP_GLOBAL_THREAD_NUM3]])
// CHECK3-NEXT: br label [[CANCEL_CONT]]
// CHECK3-NEXT: br label [[CANCEL_CONT:.*]]
// CHECK3: cancel.cont:
// CHECK3-NEXT: ret void
// CHECK3: cancel.exit:
Expand Down Expand Up @@ -1153,6 +1155,8 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .omp.sections.case.split:
// CHECK3-NEXT: br label [[DOTOMP_SECTIONS_EXIT]]
// CHECK3: .omp.sections.case.cncl:
// CHECK3-NEXT: br label [[DOTFINI:.%*]]
// CHECK3: .fini:
// CHECK3-NEXT: br label [[CANCEL_CONT:%.*]]
// CHECK3: .omp.sections.case2:
// CHECK3-NEXT: [[OMP_GLOBAL_THREAD_NUM3:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]])
Expand All @@ -1164,7 +1168,7 @@ for (int i = 0; i < argc; ++i) {
// CHECK3: .omp.sections.case2.section.after:
// CHECK3-NEXT: br label [[DOTOMP_SECTIONS_EXIT]]
// CHECK3: .omp.sections.case2.cncl:
// CHECK3-NEXT: br label [[OMP_INNER_FOR_END]]
// CHECK3-NEXT: br label [[FINI:.*]]
// CHECK3: .omp.sections.exit:
// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
// CHECK3: omp.inner.for.inc:
Expand Down
8 changes: 6 additions & 2 deletions llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ class OpenMPIRBuilder {

/// Flag to indicate if the directive is cancellable.
bool IsCancellable;

/// The basic block to which control should be transferred to
/// implement the FiniCB. Memoized to avoid generating finalization
/// multiple times.
llvm::BasicBlock *FiniBB = nullptr;
};

/// Push a finalization callback on the finalization stack.
Expand Down Expand Up @@ -2181,8 +2186,7 @@ class OpenMPIRBuilder {
///
/// \return an error, if any were triggered during execution.
LLVM_ABI Error emitCancelationCheckImpl(Value *CancelFlag,
omp::Directive CanceledDirective,
FinalizeCallbackTy ExitCB = {});
omp::Directive CanceledDirective);

/// Generate a target region entry call.
///
Expand Down
72 changes: 31 additions & 41 deletions llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,21 +1108,9 @@ OpenMPIRBuilder::createCancel(const LocationDescription &Loc,
Value *Args[] = {Ident, getOrCreateThreadID(Ident), CancelKind};
Value *Result = Builder.CreateCall(
getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_cancel), Args);
auto ExitCB = [this, CanceledDirective, Loc](InsertPointTy IP) -> Error {
if (CanceledDirective == OMPD_parallel) {
IRBuilder<>::InsertPointGuard IPG(Builder);
Builder.restoreIP(IP);
return createBarrier(LocationDescription(Builder.saveIP(), Loc.DL),
omp::Directive::OMPD_unknown,
/* ForceSimpleCall */ false,
/* CheckCancelFlag */ false)
.takeError();
}
return Error::success();
};

// The actual cancel logic is shared with others, e.g., cancel_barriers.
if (Error Err = emitCancelationCheckImpl(Result, CanceledDirective, ExitCB))
if (Error Err = emitCancelationCheckImpl(Result, CanceledDirective))
return Err;

// Update the insertion point and remove the terminator we introduced.
Expand Down Expand Up @@ -1159,21 +1147,9 @@ OpenMPIRBuilder::createCancellationPoint(const LocationDescription &Loc,
Value *Args[] = {Ident, getOrCreateThreadID(Ident), CancelKind};
Value *Result = Builder.CreateCall(
getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_cancellationpoint), Args);
auto ExitCB = [this, CanceledDirective, Loc](InsertPointTy IP) -> Error {
if (CanceledDirective == OMPD_parallel) {
IRBuilder<>::InsertPointGuard IPG(Builder);
Builder.restoreIP(IP);
return createBarrier(LocationDescription(Builder.saveIP(), Loc.DL),
omp::Directive::OMPD_unknown,
/* ForceSimpleCall */ false,
/* CheckCancelFlag */ false)
.takeError();
}
return Error::success();
};

// The actual cancel logic is shared with others, e.g., cancel_barriers.
if (Error Err = emitCancelationCheckImpl(Result, CanceledDirective, ExitCB))
if (Error Err = emitCancelationCheckImpl(Result, CanceledDirective))
return Err;

// Update the insertion point and remove the terminator we introduced.
Expand Down Expand Up @@ -1277,8 +1253,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::emitKernelLaunch(
}

Error OpenMPIRBuilder::emitCancelationCheckImpl(
Value *CancelFlag, omp::Directive CanceledDirective,
FinalizeCallbackTy ExitCB) {
Value *CancelFlag, omp::Directive CanceledDirective) {
assert(isLastFinalizationInfoCancellable(CanceledDirective) &&
"Unexpected cancellation!");

Expand All @@ -1305,13 +1280,17 @@ Error OpenMPIRBuilder::emitCancelationCheckImpl(

// From the cancellation block we finalize all variables and go to the
// post finalization block that is known to the FiniCB callback.
Builder.SetInsertPoint(CancellationBlock);
if (ExitCB)
if (Error Err = ExitCB(Builder.saveIP()))
return Err;
auto &FI = FinalizationStack.back();
if (Error Err = FI.FiniCB(Builder.saveIP()))
return Err;
if (!FI.FiniBB) {
llvm::IRBuilderBase::InsertPointGuard Guard(Builder);
FI.FiniBB = BasicBlock::Create(BB->getContext(), ".fini", BB->getParent());
Builder.SetInsertPoint(FI.FiniBB);
// FiniCB adds the branch to the exit stub.
if (Error Err = FI.FiniCB(Builder.saveIP()))
return Err;
}
Builder.SetInsertPoint(CancellationBlock);
Builder.CreateBr(FI.FiniBB);

// The continuation block is where code generation continues.
Builder.SetInsertPoint(NonCancellationBlock, NonCancellationBlock->begin());
Expand Down Expand Up @@ -1800,8 +1779,18 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createParallel(
Instruction *PRegPreFiniTI = PRegPreFiniBB->getTerminator();

InsertPointTy PreFiniIP(PRegPreFiniBB, PRegPreFiniTI->getIterator());
if (Error Err = FiniCB(PreFiniIP))
return Err;
if (!FiniInfo.FiniBB) {
if (Error Err = FiniCB(PreFiniIP))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would set FiniInfo.FiniBB?

If it is a call to createBarrier that the FiniCB is expected to make, that's the kind of devil's contract that makes the callback-driven design so bad.

Copy link
Contributor Author

@tblah tblah Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The finalisation basic block could have already been created if the body of the parallel operation contained a cancellation point or cancel. In that case we should just branch straight to the block created previously. I agree the control flow with all of the callbacks and the cancellation stack are a bit hard to follow. This is not new with this patch.

In most cases, no cancellation will have already created a finalisation block so finalisation should be generated right here as was done before this patch.

The intention here is to only run the finalisation callback once and have all exists branch to that one instance (and also to include the barrier in that unique exit so that all threads block on the same barrier).

It is not expected that the FiniCB creates FiniBB.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we improve the situation a bit to make it more predictable? There seem to be two code locations where FiniCB is called and FiniBB is assigned, here or in commonDirectiveExit. I propose refactoring this out into a different function whose task it is to get the FiniBB: If it was already created, return it; otherwise emit one. Such as

struct FinalizationInfo {
  ...
  BasicBlock *getOrCreateFinializationBranchTarget() {
    if (!FiniBB) {
     FiniCB(FiniIP);
     FiniBB = FinIP.getBlock();
    }
    return FiniBB;
  }
};

return Err;
} else {
IRBuilderBase::InsertPointGuard Guard{Builder};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brace-initialization is uncommon in llvm/

Builder.restoreIP(PreFiniIP);
Builder.CreateBr(FiniInfo.FiniBB);
// There's currently a branch to omp.par.exit. Delete it. We will get there
// via the fini block
if (llvm::Instruction *Term = Builder.GetInsertBlock()->getTerminator())
Term->eraseFromParent();
}

// Register the outlined info.
addOutlineInfo(std::move(OI));
Expand Down Expand Up @@ -6556,13 +6545,14 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::emitCommonDirectiveExit(
FinalizationInfo Fi = FinalizationStack.pop_back_val();
assert(Fi.DK == OMPD && "Unexpected Directive for Finalization call!");

if (Error Err = Fi.FiniCB(FinIP))
return Err;

BasicBlock *FiniBB = FinIP.getBlock();
Instruction *FiniBBTI = FiniBB->getTerminator();
if (!Fi.FiniBB) {
if (Error Err = Fi.FiniCB(FinIP))
return Err;
Fi.FiniBB = FinIP.getBlock();
Copy link
Member

@Meinersbur Meinersbur Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[serious] Is there a guarantee that FinIP is a BasicBlock exclusive to finialization, and does not contain other code that would be executed if we reuse that block?

(Note: this is why CanonicalLoopInfo has a predefined control-flow structure)

}

// set Builder IP for call creation
Instruction *FiniBBTI = Fi.FiniBB->getTerminator();
Builder.SetInsertPoint(FiniBBTI);
}

Expand Down
65 changes: 27 additions & 38 deletions llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,8 @@ TEST_F(OpenMPIRBuilderTest, CreateCancel) {
OMPBuilder.createCancel(Loc, nullptr, OMPD_parallel));
Builder.restoreIP(NewIP);
EXPECT_FALSE(M->global_empty());
EXPECT_EQ(M->size(), 4U);
EXPECT_EQ(F->size(), 4U);
EXPECT_EQ(M->size(), 3U);
EXPECT_EQ(F->size(), 5U);
EXPECT_EQ(BB->size(), 4U);

CallInst *GTID = dyn_cast<CallInst>(&BB->front());
Expand All @@ -449,23 +449,16 @@ TEST_F(OpenMPIRBuilderTest, CreateCancel) {
Instruction *CancelBBTI = Cancel->getParent()->getTerminator();
EXPECT_EQ(CancelBBTI->getNumSuccessors(), 2U);
EXPECT_EQ(CancelBBTI->getSuccessor(0), NewIP.getBlock());
EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 3U);
CallInst *GTID1 = dyn_cast<CallInst>(&CancelBBTI->getSuccessor(1)->front());
EXPECT_NE(GTID1, nullptr);
EXPECT_EQ(GTID1->arg_size(), 1U);
EXPECT_EQ(GTID1->getCalledFunction()->getName(), "__kmpc_global_thread_num");
EXPECT_FALSE(GTID1->getCalledFunction()->doesNotAccessMemory());
EXPECT_FALSE(GTID1->getCalledFunction()->doesNotFreeMemory());
CallInst *Barrier = dyn_cast<CallInst>(GTID1->getNextNode());
EXPECT_NE(Barrier, nullptr);
EXPECT_EQ(Barrier->arg_size(), 2U);
EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
EXPECT_TRUE(Barrier->use_empty());
EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U);
EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
1U);
EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0), CBB);
// cancel branch instruction (1) -> .cncl -> .fini -> CBB
EXPECT_EQ(CancelBBTI->getSuccessor(1)
->getTerminator()
->getSuccessor(0)
->getTerminator()
->getSuccessor(0),
CBB);

EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID);

Expand Down Expand Up @@ -497,8 +490,8 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) {
OMPBuilder.createCancel(Loc, Builder.getTrue(), OMPD_parallel));
Builder.restoreIP(NewIP);
EXPECT_FALSE(M->global_empty());
EXPECT_EQ(M->size(), 4U);
EXPECT_EQ(F->size(), 7U);
EXPECT_EQ(M->size(), 3U);
EXPECT_EQ(F->size(), 8U);
EXPECT_EQ(BB->size(), 1U);
ASSERT_TRUE(isa<BranchInst>(BB->getTerminator()));
ASSERT_EQ(BB->getTerminator()->getNumSuccessors(), 2U);
Expand All @@ -524,23 +517,15 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelIfCond) {
EXPECT_EQ(CancelBBTI->getSuccessor(0)->size(), 1U);
EXPECT_EQ(CancelBBTI->getSuccessor(0)->getUniqueSuccessor(),
NewIP.getBlock());
EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 3U);
CallInst *GTID1 = dyn_cast<CallInst>(&CancelBBTI->getSuccessor(1)->front());
EXPECT_NE(GTID1, nullptr);
EXPECT_EQ(GTID1->arg_size(), 1U);
EXPECT_EQ(GTID1->getCalledFunction()->getName(), "__kmpc_global_thread_num");
EXPECT_FALSE(GTID1->getCalledFunction()->doesNotAccessMemory());
EXPECT_FALSE(GTID1->getCalledFunction()->doesNotFreeMemory());
CallInst *Barrier = dyn_cast<CallInst>(GTID1->getNextNode());
EXPECT_NE(Barrier, nullptr);
EXPECT_EQ(Barrier->arg_size(), 2U);
EXPECT_EQ(Barrier->getCalledFunction()->getName(), "__kmpc_cancel_barrier");
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotAccessMemory());
EXPECT_FALSE(Barrier->getCalledFunction()->doesNotFreeMemory());
EXPECT_TRUE(Barrier->use_empty());
EXPECT_EQ(CancelBBTI->getSuccessor(1)->size(), 1U);
EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
1U);
EXPECT_EQ(CancelBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0), CBB);
EXPECT_EQ(CancelBBTI->getSuccessor(1)
->getTerminator()
->getSuccessor(0)
->getTerminator()
->getSuccessor(0),
CBB);

EXPECT_EQ(cast<CallInst>(Cancel)->getArgOperand(1), GTID);

Expand Down Expand Up @@ -572,7 +557,7 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) {
Builder.restoreIP(NewIP);
EXPECT_FALSE(M->global_empty());
EXPECT_EQ(M->size(), 3U);
EXPECT_EQ(F->size(), 4U);
EXPECT_EQ(F->size(), 5U);
EXPECT_EQ(BB->size(), 4U);

CallInst *GTID = dyn_cast<CallInst>(&BB->front());
Expand All @@ -595,7 +580,11 @@ TEST_F(OpenMPIRBuilderTest, CreateCancelBarrier) {
EXPECT_EQ(BarrierBBTI->getSuccessor(1)->size(), 1U);
EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getNumSuccessors(),
1U);
EXPECT_EQ(BarrierBBTI->getSuccessor(1)->getTerminator()->getSuccessor(0),
EXPECT_EQ(BarrierBBTI->getSuccessor(1)
->getTerminator()
->getSuccessor(0)
->getTerminator()
->getSuccessor(0),
CBB);

EXPECT_EQ(cast<CallInst>(Barrier)->getArgOperand(1), GTID);
Expand Down Expand Up @@ -1291,8 +1280,8 @@ TEST_F(OpenMPIRBuilderTest, ParallelCancelBarrier) {

EXPECT_EQ(NumBodiesGenerated, 1U);
EXPECT_EQ(NumPrivatizedVars, 0U);
EXPECT_EQ(NumFinalizationPoints, 2U);
EXPECT_TRUE(FakeDestructor->hasNUses(2));
EXPECT_EQ(NumFinalizationPoints, 1U);
EXPECT_TRUE(FakeDestructor->hasNUses(1));

Builder.restoreIP(AfterIP);
Builder.CreateRetVoid();
Expand Down
Loading