Skip to content

Commit eb6b7be

Browse files
authored
[flang][cuda] Avoid crash when the force modifier is used (#160176)
1 parent 81cbd97 commit eb6b7be

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
315315

316316
private:
317317
std::int64_t GetAssociatedLoopLevelFromClauses(const parser::AccClauseList &);
318+
bool HasForceCollapseModifier(const parser::AccClauseList &);
318319

319320
Symbol::Flags dataSharingAttributeFlags{Symbol::Flag::AccShared,
320321
Symbol::Flag::AccPrivate, Symbol::Flag::AccFirstPrivate,
@@ -333,7 +334,7 @@ class AccAttributeVisitor : DirectiveAttributeVisitor<llvm::acc::Directive> {
333334
Symbol::Flag::AccDevicePtr, Symbol::Flag::AccDeviceResident,
334335
Symbol::Flag::AccLink, Symbol::Flag::AccPresent};
335336

336-
void CheckAssociatedLoop(const parser::DoConstruct &);
337+
void CheckAssociatedLoop(const parser::DoConstruct &, bool forceCollapsed);
337338
void ResolveAccObjectList(const parser::AccObjectList &, Symbol::Flag);
338339
void ResolveAccObject(const parser::AccObject &, Symbol::Flag);
339340
Symbol *ResolveAcc(const parser::Name &, Symbol::Flag, Scope &);
@@ -1168,7 +1169,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCLoopConstruct &x) {
11681169
ClearDataSharingAttributeObjects();
11691170
SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList));
11701171
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
1171-
CheckAssociatedLoop(*outer);
1172+
CheckAssociatedLoop(*outer, HasForceCollapseModifier(clauseList));
11721173
return true;
11731174
}
11741175

@@ -1366,7 +1367,7 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
13661367
const auto &clauseList{std::get<parser::AccClauseList>(beginBlockDir.t)};
13671368
SetContextAssociatedLoopLevel(GetAssociatedLoopLevelFromClauses(clauseList));
13681369
const auto &outer{std::get<std::optional<parser::DoConstruct>>(x.t)};
1369-
CheckAssociatedLoop(*outer);
1370+
CheckAssociatedLoop(*outer, HasForceCollapseModifier(clauseList));
13701371
ClearDataSharingAttributeObjects();
13711372
return true;
13721373
}
@@ -1478,6 +1479,18 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCacheConstruct &x) {
14781479
return true;
14791480
}
14801481

1482+
bool AccAttributeVisitor::HasForceCollapseModifier(
1483+
const parser::AccClauseList &x) {
1484+
for (const auto &clause : x.v) {
1485+
if (const auto *collapseClause{
1486+
std::get_if<parser::AccClause::Collapse>(&clause.u)}) {
1487+
const parser::AccCollapseArg &arg = collapseClause->v;
1488+
return std::get<bool>(arg.t);
1489+
}
1490+
}
1491+
return false;
1492+
}
1493+
14811494
std::int64_t AccAttributeVisitor::GetAssociatedLoopLevelFromClauses(
14821495
const parser::AccClauseList &x) {
14831496
std::int64_t collapseLevel{0};
@@ -1499,14 +1512,14 @@ std::int64_t AccAttributeVisitor::GetAssociatedLoopLevelFromClauses(
14991512
}
15001513

15011514
void AccAttributeVisitor::CheckAssociatedLoop(
1502-
const parser::DoConstruct &outerDoConstruct) {
1515+
const parser::DoConstruct &outerDoConstruct, bool forceCollapsed) {
15031516
std::int64_t level{GetContext().associatedLoopLevel};
15041517
if (level <= 0) { // collapse value was negative or 0
15051518
return;
15061519
}
15071520

15081521
const auto getNextDoConstruct =
1509-
[this](const parser::Block &block,
1522+
[this, forceCollapsed](const parser::Block &block,
15101523
std::int64_t &level) -> const parser::DoConstruct * {
15111524
for (const auto &entry : block) {
15121525
if (const auto *doConstruct = GetDoConstructIf(entry)) {
@@ -1524,7 +1537,9 @@ void AccAttributeVisitor::CheckAssociatedLoop(
15241537
"LOOP directive not expected in COLLAPSE loop nest"_err_en_US);
15251538
level = 0;
15261539
} else {
1527-
break;
1540+
if (!forceCollapsed) {
1541+
break;
1542+
}
15281543
}
15291544
}
15301545
return nullptr;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenacc -fsyntax-only
2+
3+
! Check that loop with force collapse do not break in the semantic step.
4+
subroutine sub3()
5+
integer :: i, j
6+
integer, parameter :: n = 100, m = 200
7+
real, dimension(n, m) :: a
8+
real, dimension(n) :: bb
9+
real :: r
10+
a = 1
11+
r = 0
12+
!$acc parallel loop collapse(force:2) copy(a)
13+
do i = 1, n
14+
bb(i) = r
15+
do j = 1, m
16+
a(i,j) = r * a(i,j)
17+
enddo
18+
enddo
19+
end subroutine

0 commit comments

Comments
 (0)