[flang-commits] [flang] [flang][OpenMP] Avoid marking named main programs as declare target (PR #190250)
Sairudra More via flang-commits
flang-commits at lists.llvm.org
Wed Apr 8 04:07:11 PDT 2026
https://github.com/Saieiei updated https://github.com/llvm/llvm-project/pull/190250
>From 051e7f980deedc7cbf22ec1e67cc708e7227b5e1 Mon Sep 17 00:00:00 2001
From: Saieiei <sairudra60 at gmail.com>
Date: Thu, 2 Apr 2026 14:40:15 -0500
Subject: [PATCH] [flang][OpenMP] Avoid marking named main programs as declare
target
A bare !$omp declare target could incorrectly mark _QQmain as
omp.declare_target when it appeared in an interface body inside a named
main program. That pulled host-only callees into device compilation and
caused offload link failures.
Fix this by skipping main programs in the implicit-capture path.
Also add a regression test for the named-main interface case and update
real10.f90 to use a valid bare declare target container.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 9 +++--
.../declare-target-named-main-interface.f90 | 34 +++++++++++++++++++
flang/test/Lower/OpenMP/real10.f90 | 6 ++--
3 files changed, 43 insertions(+), 6 deletions(-)
create mode 100644 flang/test/Lower/OpenMP/declare-target-named-main-interface.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 43c6128d46647..d6599dcb24177 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -778,9 +778,12 @@ static void getDeclareTargetInfo(
if (clauses.empty()) {
Fortran::lower::pft::FunctionLikeUnit *owningProc =
eval.getOwningProcedure();
- if (owningProc && (!owningProc->isMainProgram() ||
- owningProc->getMainProgramSymbol())) {
- // Case: declare target, implicit capture of function
+ // Main programs are never device routines. Skip them so that a bare
+ // '!$omp declare target' inside an interface body that lives in a named
+ // main program does not incorrectly mark _QQmain as a device function.
+ if (owningProc && !owningProc->isMainProgram()) {
+ // Case: declare target, implicit capture of enclosing
+ // function/subroutine.
symbolAndClause.emplace_back(mlir::omp::DeclareTargetCaptureClause::to,
owningProc->getSubprogramSymbol());
}
diff --git a/flang/test/Lower/OpenMP/declare-target-named-main-interface.f90 b/flang/test/Lower/OpenMP/declare-target-named-main-interface.f90
new file mode 100644
index 0000000000000..32ba6e7723b15
--- /dev/null
+++ b/flang/test/Lower/OpenMP/declare-target-named-main-interface.f90
@@ -0,0 +1,34 @@
+!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s --check-prefix=HOST
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
+
+! Test that a bare '!$omp declare target' inside an interface body that
+! appears in a *named* main program does not incorrectly mark the main
+! program (_QQmain) as a declare-target function. The subroutines
+! declared in the interface blocks are defined externally and carry their
+! own '!$omp declare target' in their definitions; that path is tested
+! separately.
+!
+! In host compilation _QQmain must not be tagged with declare_target at all.
+! In device compilation the MarkDeclareTargetPass may annotate _QQmain with
+! device_type(host) (harmless); the bug was device_type(any) which caused
+! _QQmain to be emitted into the device image.
+
+! HOST-NOT: func.func @_QQmain{{.*}}omp.declare_target
+! DEVICE-NOT: func.func @_QQmain{{.*}}device_type = (any)
+! DEVICE-NOT: func.func @_QQmain{{.*}}device_type = (nohost)
+! HOST: func.func private @_QPsub_a{{.*}}device_type = (nohost)
+! DEVICE: func.func private @_QPsub_a{{.*}}device_type = (nohost)
+
+program named_main
+ interface
+ subroutine sub_a(x)
+ implicit none
+ !$omp declare target
+ integer, intent(inout) :: x
+ end subroutine sub_a
+ end interface
+ integer :: v = 0
+ !$omp target
+ call sub_a(v)
+ !$omp end target
+end program named_main
diff --git a/flang/test/Lower/OpenMP/real10.f90 b/flang/test/Lower/OpenMP/real10.f90
index c76c2bde0f6f6..7323f421ad2c0 100644
--- a/flang/test/Lower/OpenMP/real10.f90
+++ b/flang/test/Lower/OpenMP/real10.f90
@@ -2,9 +2,9 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp -triple amdgcn -fopenmp -fopenmp-is-target-device -o - %s | FileCheck %s
-!CHECK: hlfir.declare %{{.*}} {uniq_name = "_QFEx"} : (!fir.ref<f80>) -> (!fir.ref<f80>, !fir.ref<f80>)
+!CHECK: hlfir.declare %{{.*}} {uniq_name = "_QFtest_real10Ex"} : (!fir.ref<f80>) -> (!fir.ref<f80>, !fir.ref<f80>)
-program p
+subroutine test_real10()
!$omp declare target
real(10) :: x
-end
+end subroutine test_real10
More information about the flang-commits
mailing list