Skip to content
Merged
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
9 changes: 9 additions & 0 deletions flang/lib/Semantics/check-omp-loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
EnterDirectiveNest(SIMDNest);
}

if (CurrentDirectiveIsNested() &&
llvm::omp::topTeamsSet.test(GetContext().directive) &&
GetContextParent().directive == llvm::omp::Directive::OMPD_target &&
!GetDirectiveNest(TargetBlockOnlyTeams)) {
Comment on lines +265 to +268
Copy link
Member

Choose a reason for hiding this comment

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

Not exactly relevant to this PR since a similar check is used somewhere else. But for the following example:

!$omp target ....
  !$omp teams ....
    !$omp target ....
      .... some statement ....
      !$omp teams ....
        ....
....

Would the semantic check trigger in this case? I think it won't since GetDirectiveNest(TargetBlockOnlyTeams) will return a non-zero result.

Copy link
Contributor Author

@bhandarkar-pranav bhandarkar-pranav Nov 20, 2025

Choose a reason for hiding this comment

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

I coudn't nest a target directive inside the teams directive because that is not allowed, but I did the following

 !$omp target map(tofrom:counter)
   !$omp teams
    !$omp parallel
      !$omp target
        ... some stmt...
       !$omp teams
        .... a structured block...
       !$omp end teams    
      !$omp end target
    !$omp end parallel
   !$omp end teams
  !$omp end target

This compiled fine but it shouldn't have for the reason you mentioned. Strangely enough, gfortran also accepts the code above, only warning about reverse-offloading. I am torn between spending time fixing it on the one hand while on the other hand letting what seems to be an obscure case slide.

Copy link
Member

Choose a reason for hiding this comment

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

I am torn between spending time fixing it on the one hand while on the other hand letting what seems to be an obscure case slide.

No need to fix it, at least in this PR. Specially since the test is used somewhere else. The way the directive-nest test is currently implemented is just surprising to me (seems a bit too permisive) and wanted to verify if this is really the case.

context_.Say(GetContextParent().directiveSource,
"TARGET construct with nested TEAMS region contains statements or "
"directives outside of the TEAMS construct"_err_en_US);
}

// Combined target loop constructs are target device constructs. Keep track of
// whether any such construct has been visited to later check that REQUIRES
// directives for target-related options don't appear after them.
Expand Down
7 changes: 7 additions & 0 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5215,6 +5215,13 @@ bool OmpStructureChecker::CheckTargetBlockOnlyTeams(
if (dirId == llvm::omp::Directive::OMPD_teams) {
nestedTeams = true;
}
} else if (const auto *ompLoopConstruct{
std::get_if<parser::OpenMPLoopConstruct>(
&ompConstruct->u)}) {
llvm::omp::Directive dirId{ompLoopConstruct->BeginDir().DirId()};
if (llvm::omp::topTeamsSet.test(dirId)) {
nestedTeams = true;
}
}
}

Expand Down
20 changes: 20 additions & 0 deletions flang/test/Semantics/OpenMP/target-teams-nesting.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp

program main
implicit none
integer, parameter :: n = 100
integer, parameter :: expected = n+2
integer :: i
integer :: counter

counter = 0
!ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
!$omp target map(tofrom:counter)
counter = counter+1
!$omp teams distribute reduction(+:counter)
do i=1, n
counter = counter+1
end do
counter = counter+1
!$omp end target
end program