Skip to content

Commit 3015bcc

Browse files
committed
[OPENMP] Generalize codegen for 'sections'-based directive.
If 'sections' directive has only one sub-section, the code for 'single'-based directive was emitted. Removed this codegen, because it causes crashes in different cases. llvm-svn: 258495
1 parent 40038d2 commit 3015bcc

10 files changed

+183
-203
lines changed

Diff for: clang/lib/CodeGen/CGOpenMPRuntime.cpp

+4-11
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
483483
if (ThreadID != nullptr)
484484
return ThreadID;
485485
}
486-
if (auto OMPRegionInfo =
486+
if (auto *OMPRegionInfo =
487487
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
488488
if (OMPRegionInfo->getThreadIDVariable()) {
489489
// Check if this an outlined function with thread id passed as argument.
@@ -1356,7 +1356,7 @@ void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
13561356
// return the address of that temp.
13571357
Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
13581358
SourceLocation Loc) {
1359-
if (auto OMPRegionInfo =
1359+
if (auto *OMPRegionInfo =
13601360
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
13611361
if (OMPRegionInfo->getThreadIDVariable())
13621362
return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
@@ -1717,15 +1717,10 @@ void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
17171717
}
17181718
// Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
17191719
// thread_id);
1720-
auto *OMPRegionInfo =
1721-
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
1722-
// Do not emit barrier call in the single directive emitted in some rare cases
1723-
// for sections directives.
1724-
if (OMPRegionInfo && OMPRegionInfo->getDirectiveKind() == OMPD_single)
1725-
return;
17261720
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
17271721
getThreadID(CGF, Loc)};
1728-
if (OMPRegionInfo) {
1722+
if (auto *OMPRegionInfo =
1723+
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
17291724
if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
17301725
auto *Result = CGF.EmitRuntimeCall(
17311726
createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
@@ -3649,8 +3644,6 @@ void CGOpenMPRuntime::emitCancellationPointCall(
36493644
// global_tid, kmp_int32 cncl_kind);
36503645
if (auto *OMPRegionInfo =
36513646
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
3652-
if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
3653-
return;
36543647
if (OMPRegionInfo->hasCancel()) {
36553648
llvm::Value *Args[] = {
36563649
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),

Diff for: clang/lib/CodeGen/CGStmtOpenMP.cpp

+101-132
Original file line numberDiff line numberDiff line change
@@ -1657,50 +1657,51 @@ OpenMPDirectiveKind
16571657
CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
16581658
auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt();
16591659
auto *CS = dyn_cast<CompoundStmt>(Stmt);
1660-
if (CS && CS->size() > 1) {
1661-
bool HasLastprivates = false;
1662-
auto &&CodeGen = [&S, CS, &HasLastprivates](CodeGenFunction &CGF) {
1663-
auto &C = CGF.CGM.getContext();
1664-
auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1665-
// Emit helper vars inits.
1666-
LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
1667-
CGF.Builder.getInt32(0));
1668-
auto *GlobalUBVal = CGF.Builder.getInt32(CS->size() - 1);
1669-
LValue UB =
1670-
createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
1671-
LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
1672-
CGF.Builder.getInt32(1));
1673-
LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
1674-
CGF.Builder.getInt32(0));
1675-
// Loop counter.
1676-
LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
1677-
OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
1678-
CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
1679-
OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
1680-
CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
1681-
// Generate condition for loop.
1682-
BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
1683-
OK_Ordinary, S.getLocStart(),
1684-
/*fpContractable=*/false);
1685-
// Increment for loop counter.
1686-
UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue,
1687-
OK_Ordinary, S.getLocStart());
1688-
auto BodyGen = [CS, &S, &IV](CodeGenFunction &CGF) {
1689-
// Iterate through all sections and emit a switch construct:
1690-
// switch (IV) {
1691-
// case 0:
1692-
// <SectionStmt[0]>;
1693-
// break;
1694-
// ...
1695-
// case <NumSection> - 1:
1696-
// <SectionStmt[<NumSection> - 1]>;
1697-
// break;
1698-
// }
1699-
// .omp.sections.exit:
1700-
auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
1701-
auto *SwitchStmt = CGF.Builder.CreateSwitch(
1702-
CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
1703-
CS->size());
1660+
bool HasLastprivates = false;
1661+
auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF) {
1662+
auto &C = CGF.CGM.getContext();
1663+
auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1664+
// Emit helper vars inits.
1665+
LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
1666+
CGF.Builder.getInt32(0));
1667+
auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1)
1668+
: CGF.Builder.getInt32(0);
1669+
LValue UB =
1670+
createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
1671+
LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
1672+
CGF.Builder.getInt32(1));
1673+
LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
1674+
CGF.Builder.getInt32(0));
1675+
// Loop counter.
1676+
LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
1677+
OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
1678+
CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
1679+
OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue);
1680+
CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
1681+
// Generate condition for loop.
1682+
BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
1683+
OK_Ordinary, S.getLocStart(),
1684+
/*fpContractable=*/false);
1685+
// Increment for loop counter.
1686+
UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
1687+
S.getLocStart());
1688+
auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) {
1689+
// Iterate through all sections and emit a switch construct:
1690+
// switch (IV) {
1691+
// case 0:
1692+
// <SectionStmt[0]>;
1693+
// break;
1694+
// ...
1695+
// case <NumSection> - 1:
1696+
// <SectionStmt[<NumSection> - 1]>;
1697+
// break;
1698+
// }
1699+
// .omp.sections.exit:
1700+
auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
1701+
auto *SwitchStmt = CGF.Builder.CreateSwitch(
1702+
CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB,
1703+
CS == nullptr ? 1 : CS->size());
1704+
if (CS) {
17041705
unsigned CaseNumber = 0;
17051706
for (auto *SubStmt : CS->children()) {
17061707
auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
@@ -1710,103 +1711,72 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
17101711
CGF.EmitBranch(ExitBB);
17111712
++CaseNumber;
17121713
}
1713-
CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
1714-
};
1715-
1716-
CodeGenFunction::OMPPrivateScope LoopScope(CGF);
1717-
if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
1718-
// Emit implicit barrier to synchronize threads and avoid data races on
1719-
// initialization of firstprivate variables.
1720-
CGF.CGM.getOpenMPRuntime().emitBarrierCall(
1721-
CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
1722-
/*ForceSimpleCall=*/true);
1714+
} else {
1715+
auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
1716+
CGF.EmitBlock(CaseBB);
1717+
SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
1718+
CGF.EmitStmt(Stmt);
1719+
CGF.EmitBranch(ExitBB);
17231720
}
1724-
CGF.EmitOMPPrivateClause(S, LoopScope);
1725-
HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1726-
CGF.EmitOMPReductionClauseInit(S, LoopScope);
1727-
(void)LoopScope.Privatize();
1728-
1729-
// Emit static non-chunked loop.
1730-
CGF.CGM.getOpenMPRuntime().emitForStaticInit(
1731-
CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
1732-
/*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(),
1733-
LB.getAddress(), UB.getAddress(), ST.getAddress());
1734-
// UB = min(UB, GlobalUB);
1735-
auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
1736-
auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
1737-
CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1738-
CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
1739-
// IV = LB;
1740-
CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
1741-
// while (idx <= UB) { BODY; ++idx; }
1742-
CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
1743-
[](CodeGenFunction &) {});
1744-
// Tell the runtime we are done.
1745-
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
1746-
CGF.EmitOMPReductionClauseFinal(S);
1747-
1748-
// Emit final copy of the lastprivate variables if IsLastIter != 0.
1749-
if (HasLastprivates)
1750-
CGF.EmitOMPLastprivateClauseFinal(
1751-
S, CGF.Builder.CreateIsNotNull(
1752-
CGF.EmitLoadOfScalar(IL, S.getLocStart())));
1721+
CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
17531722
};
17541723

1755-
bool HasCancel = false;
1756-
if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
1757-
HasCancel = OSD->hasCancel();
1758-
else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
1759-
HasCancel = OPSD->hasCancel();
1760-
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
1761-
HasCancel);
1762-
// Emit barrier for lastprivates only if 'sections' directive has 'nowait'
1763-
// clause. Otherwise the barrier will be generated by the codegen for the
1764-
// directive.
1765-
if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
1724+
CodeGenFunction::OMPPrivateScope LoopScope(CGF);
1725+
if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
17661726
// Emit implicit barrier to synchronize threads and avoid data races on
17671727
// initialization of firstprivate variables.
1768-
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
1769-
OMPD_unknown);
1728+
CGF.CGM.getOpenMPRuntime().emitBarrierCall(
1729+
CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false,
1730+
/*ForceSimpleCall=*/true);
17701731
}
1771-
return OMPD_sections;
1772-
}
1773-
// If only one section is found - no need to generate loop, emit as a single
1774-
// region.
1775-
bool HasFirstprivates;
1776-
// No need to generate reductions for sections with single section region, we
1777-
// can use original shared variables for all operations.
1778-
bool HasReductions = S.hasClausesOfKind<OMPReductionClause>();
1779-
// No need to generate lastprivates for sections with single section region,
1780-
// we can use original shared variable for all calculations with barrier at
1781-
// the end of the sections.
1782-
bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>();
1783-
auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) {
1784-
CodeGenFunction::OMPPrivateScope SingleScope(CGF);
1785-
HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
1786-
CGF.EmitOMPPrivateClause(S, SingleScope);
1787-
(void)SingleScope.Privatize();
1732+
CGF.EmitOMPPrivateClause(S, LoopScope);
1733+
HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
1734+
CGF.EmitOMPReductionClauseInit(S, LoopScope);
1735+
(void)LoopScope.Privatize();
1736+
1737+
// Emit static non-chunked loop.
1738+
CGF.CGM.getOpenMPRuntime().emitForStaticInit(
1739+
CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32,
1740+
/*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(),
1741+
UB.getAddress(), ST.getAddress());
1742+
// UB = min(UB, GlobalUB);
1743+
auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart());
1744+
auto *MinUBGlobalUB = CGF.Builder.CreateSelect(
1745+
CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
1746+
CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
1747+
// IV = LB;
1748+
CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV);
1749+
// while (idx <= UB) { BODY; ++idx; }
1750+
CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
1751+
[](CodeGenFunction &) {});
1752+
// Tell the runtime we are done.
1753+
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
1754+
CGF.EmitOMPReductionClauseFinal(S);
17881755

1789-
auto Exit = CGF.getJumpDestInCurrentScope("omp.sections.exit");
1790-
CGF.BreakContinueStack.push_back(BreakContinue(Exit, Exit));
1791-
CGF.EmitStmt(Stmt);
1792-
CGF.EmitBlock(Exit.getBlock());
1793-
CGF.BreakContinueStack.pop_back();
1756+
// Emit final copy of the lastprivate variables if IsLastIter != 0.
1757+
if (HasLastprivates)
1758+
CGF.EmitOMPLastprivateClauseFinal(
1759+
S, CGF.Builder.CreateIsNotNull(
1760+
CGF.EmitLoadOfScalar(IL, S.getLocStart())));
17941761
};
1795-
CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(),
1796-
llvm::None, llvm::None, llvm::None,
1797-
llvm::None);
1798-
// Emit barrier for firstprivates, lastprivates or reductions only if
1799-
// 'sections' directive has 'nowait' clause. Otherwise the barrier will be
1800-
// generated by the codegen for the directive.
1801-
if ((HasFirstprivates || HasLastprivates || HasReductions) &&
1802-
S.getSingleClause<OMPNowaitClause>()) {
1762+
1763+
bool HasCancel = false;
1764+
if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
1765+
HasCancel = OSD->hasCancel();
1766+
else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
1767+
HasCancel = OPSD->hasCancel();
1768+
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
1769+
HasCancel);
1770+
// Emit barrier for lastprivates only if 'sections' directive has 'nowait'
1771+
// clause. Otherwise the barrier will be generated by the codegen for the
1772+
// directive.
1773+
if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
18031774
// Emit implicit barrier to synchronize threads and avoid data races on
18041775
// initialization of firstprivate variables.
1805-
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown,
1806-
/*EmitChecks=*/false,
1807-
/*ForceSimpleCall=*/true);
1776+
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
1777+
OMPD_unknown);
18081778
}
1809-
return OMPD_single;
1779+
return OMPD_sections;
18101780
}
18111781

18121782
void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
@@ -2651,8 +2621,7 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
26512621
if (Kind == OMPD_parallel || Kind == OMPD_task)
26522622
return ReturnBlock;
26532623
assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
2654-
Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
2655-
Kind == OMPD_single);
2624+
Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
26562625
return BreakContinueStack.back().BreakBlock;
26572626
}
26582627

Diff for: clang/test/OpenMP/cancel_codegen.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ int main (int argc, char **argv) {
1919
{
2020
#pragma omp cancel sections
2121
}
22-
// CHECK: call i32 @__kmpc_single(
22+
// CHECK: call void @__kmpc_for_static_init_4(
2323
// CHECK: call i32 @__kmpc_cancel(
24-
// CHECK: call void @__kmpc_end_single(
24+
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
25+
// CHECK: call void @__kmpc_for_static_fini(
2526
// CHECK: call void @__kmpc_barrier(%ident_t*
2627
#pragma omp sections
2728
{
@@ -125,9 +126,10 @@ for (int i = 0; i < argc; ++i) {
125126
// CHECK: ret i32 0
126127

127128
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
128-
// CHECK: call i32 @__kmpc_single(
129+
// CHECK: call void @__kmpc_for_static_init_4(
129130
// CHECK: call i32 @__kmpc_cancel(
130-
// CHECK: call void @__kmpc_end_single(
131+
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
132+
// CHECK: call void @__kmpc_for_static_fini(
131133
// CHECK: ret void
132134

133135
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})

Diff for: clang/test/OpenMP/cancellation_point_codegen.cpp

+20-6
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,16 @@ int main (int argc, char **argv) {
2222
#pragma omp cancel sections
2323
}
2424
}
25-
// CHECK: call i32 @__kmpc_single(
26-
// CHECK-NOT: @__kmpc_cancellationpoint
27-
// CHECK: call void @__kmpc_end_single(
25+
// CHECK: call void @__kmpc_for_static_init_4(
26+
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 3)
27+
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
28+
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
29+
// CHECK: [[EXIT]]
30+
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
31+
// CHECK: br label
32+
// CHECK: [[CONTINUE]]
33+
// CHECK: br label
34+
// CHECK: call void @__kmpc_for_static_fini(
2835
// CHECK: call void @__kmpc_barrier(%ident_t*
2936
#pragma omp sections
3037
{
@@ -126,9 +133,16 @@ for (int i = 0; i < argc; ++i) {
126133
// CHECK: ret i32 0
127134

128135
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})
129-
// CHECK: call i32 @__kmpc_single(
130-
// CHECK-NOT: @__kmpc_cancellationpoint
131-
// CHECK: call void @__kmpc_end_single(
136+
// CHECK: call void @__kmpc_for_static_init_4(
137+
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancellationpoint(%ident_t* {{[^,]+}}, i32 [[GTID:%.+]], i32 3)
138+
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
139+
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
140+
// CHECK: [[EXIT]]
141+
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
142+
// CHECK: br label
143+
// CHECK: [[CONTINUE]]
144+
// CHECK: br label
145+
// CHECK: call void @__kmpc_for_static_fini(
132146
// CHECK: ret void
133147

134148
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}})

Diff for: clang/test/OpenMP/parallel_sections_codegen.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,10 @@ int main() {
7878
// CHECK-LABEL: tmain
7979
// CHECK: call void {{.*}} @__kmpc_fork_call(
8080
// CHECK-NOT: __kmpc_global_thread_num
81-
// CHECK: [[RES:%.+]] = call i32 @__kmpc_single(
82-
// CHECK-NEXT: [[BOOLRES:%.+]] = icmp ne i32 [[RES]], 0
83-
// CHECK-NEXT: br i1 [[BOOLRES]], label %[[THEN:.+]], label %[[END:.+]]
84-
// CHECK: [[THEN]]
85-
// CHECK-NEXT: invoke void @{{.*}}foo{{.*}}()
81+
// CHECK: call void @__kmpc_for_static_init_4(
82+
// CHECK: invoke void @{{.*}}foo{{.*}}()
8683
// CHECK-NEXT: unwind label %[[TERM_LPAD:.+]]
87-
// CHECK: call void @__kmpc_end_single(
88-
// CHECK-NEXT: br label %[[END]]
89-
// CHECK: [[END]]
84+
// CHECK: call void @__kmpc_for_static_fini(
9085
// CHECK-NEXT: ret
9186
// CHECK: [[TERM_LPAD]]
9287
// CHECK: call void @__clang_call_terminate(i8*

0 commit comments

Comments
 (0)