Skip to content

Commit 0357945

Browse files
authored
[Flang][OpenMP] More elegantly handle declare target in unnamed program (#95834)
This PR is related to the following issue: #63362 It tries to solve the crash (which is now slightly different, since the issue has been languishing for a while sorry about that I missed the original issue ping). The crash occurs due to trying to access the symbol of an undefined/unnamed main when trying to find a declare target symbol that has not been specified (but can be assumed based on it's residence in a function or interface). The solution in this PR will check if we're trying to retrieve a main symbol, and then if that is the case, we make sure it exists (due to being named) before we attempt to retrieve it, this avoids the crash. However, that's only part of the issue in the above example, the other is the significant amount of nested directives, I think we are still a little while away from handling this, I have added a reduced variation of the test in the issue as a replicator which contains a lesser number of nesting directives. To push the issue along further, it will likely be a case of working through a number of variations of nested directives in conjunction with target + parallel. However, this PR pushes the issue above to the point where the issue encountered is identical to the following: #67231
1 parent dd22085 commit 0357945

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,9 @@ static void getDeclareTargetInfo(
296296
} else if (const auto *clauseList{
297297
parser::Unwrap<parser::OmpClauseList>(spec.u)}) {
298298
List<Clause> clauses = makeClauses(*clauseList, semaCtx);
299-
if (clauses.empty()) {
299+
if (clauses.empty() &&
300+
(!eval.getOwningProcedure()->isMainProgram() ||
301+
eval.getOwningProcedure()->getMainProgramSymbol())) {
300302
// Case: declare target, implicit capture of function
301303
symbolAndClause.emplace_back(
302304
mlir::omp::DeclareTargetCaptureClause::to,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s
3+
4+
! This test is a reduced version of the example in issue 63362.
5+
! It aims to test that no crash occurs when declare target is
6+
! utilised within an unnamed main program and that we still
7+
! appropriately mark the function as declare target, even when
8+
! unused within the target region.
9+
10+
!CHECK: func.func @_QPfoo(%{{.*}}: !fir.ref<f32>{{.*}}) -> f32 attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
11+
12+
interface
13+
real function foo (x)
14+
!$omp declare target
15+
real, intent(in) :: x
16+
end function foo
17+
end interface
18+
integer, parameter :: n = 1000
19+
integer, parameter :: c = 100
20+
integer :: i, j
21+
real :: a(n)
22+
do i = 1, n
23+
a(i) = i
24+
end do
25+
do i = 1, n, c
26+
!$omp target map(a(i:i+c-1))
27+
!$omp parallel do
28+
do j = i, i + c - 1
29+
a(j) = a(j)
30+
end do
31+
!$omp end target
32+
end do
33+
do i = 1, n
34+
if (a(i) /= i + 1) stop 1
35+
end do
36+
end
37+
real function foo (x)
38+
!$omp declare target
39+
real, intent(in) :: x
40+
foo = x + 1
41+
end function foo

0 commit comments

Comments
 (0)