Skip to content

Commit e3dafa8

Browse files
authored
[flang][cuda] Allow GOTO, EXIT, CYCLE and SELECT CASE in device procedures (#121612)
1 parent 82c0f68 commit e3dafa8

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

flang/lib/Semantics/check-cuda.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,14 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
302302
[&](const common::Indirection<parser::IfConstruct> &x) {
303303
Check(x.value());
304304
},
305+
[&](const common::Indirection<parser::CaseConstruct> &x) {
306+
const auto &caseList{
307+
std::get<std::list<parser::CaseConstruct::Case>>(
308+
x.value().t)};
309+
for (const parser::CaseConstruct::Case &c : caseList) {
310+
Check(std::get<parser::Block>(c.t));
311+
}
312+
},
305313
[&](const auto &x) {
306314
if (auto source{parser::GetSource(x)}) {
307315
context_.Say(*source,
@@ -347,9 +355,24 @@ template <bool IsCUFKernelDo> class DeviceContextChecker {
347355
hostArray->name());
348356
}
349357
}
358+
void ErrorInCUFKernel(parser::CharBlock source) {
359+
if (IsCUFKernelDo) {
360+
context_.Say(
361+
source, "Statement may not appear in cuf kernel code"_err_en_US);
362+
}
363+
}
350364
void Check(const parser::ActionStmt &stmt, const parser::CharBlock &source) {
351365
common::visit(
352366
common::visitors{
367+
[&](const common::Indirection<parser::CycleStmt> &) {
368+
ErrorInCUFKernel(source);
369+
},
370+
[&](const common::Indirection<parser::ExitStmt> &) {
371+
ErrorInCUFKernel(source);
372+
},
373+
[&](const common::Indirection<parser::GotoStmt> &) {
374+
ErrorInCUFKernel(source);
375+
},
353376
[&](const common::Indirection<parser::StopStmt> &) { return; },
354377
[&](const common::Indirection<parser::PrintStmt> &) {},
355378
[&](const common::Indirection<parser::WriteStmt> &x) {

flang/test/Semantics/cuf09.cuf

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,59 @@ module m
5454
print*,threadIdx%x
5555
stop ! ok
5656
end subroutine
57+
58+
attributes(global) subroutine cycletest()
59+
integer :: i
60+
do i = 1, 10
61+
cycle ! ok
62+
end do
63+
end subroutine
64+
65+
attributes(global) subroutine gototest()
66+
integer :: i
67+
goto 10
68+
10 print *, "X is negative!"
69+
end subroutine
70+
71+
attributes(global) subroutine exittest()
72+
integer :: i
73+
do i = 1, 10
74+
if (i == 1) then
75+
exit ! ok
76+
end if
77+
end do
78+
end subroutine
79+
80+
attributes(global) subroutine selectcasetest()
81+
integer :: i
82+
select case(i)
83+
case (1)
84+
print*,'main'
85+
case default
86+
print*, 'default'
87+
end select
88+
end subroutine
89+
90+
subroutine host()
91+
integer :: i
92+
!$cuf kernel do
93+
do i = 1, 10
94+
!ERROR: Statement may not appear in cuf kernel code
95+
cycle
96+
end do
97+
98+
!$cuf kernel do
99+
do i = 1, 10
100+
if (i == 1) then
101+
!ERROR: Statement may not appear in cuf kernel code
102+
exit ! ok
103+
end if
104+
105+
!ERROR: Statement may not appear in cuf kernel code
106+
goto 10
107+
10 print *, "X is negative!"
108+
end do
109+
end subroutine
57110
end
58111

59112
program main

0 commit comments

Comments
 (0)