[llvm-branch-commits] [clang] [flang] [mlir] [MLIR][OpenMP] Support calls added between MarkDeclareTarget runs (PR #214185)

Sergio Afonso via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Aug 5 04:07:21 PDT 2026


https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/214185

>From 2195023cd13ae49c24a47a9bcd147ef27c014f18 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Tue, 4 Aug 2026 16:59:21 +0100
Subject: [PATCH] [MLIR][OpenMP] Support calls added between MarkDeclareTarget
 runs

Currently, if there are multiple executions of the `MarkDeclareTarget`
pass in a compiler pipeline and somewhere between both runs function
calls get added to a non-declare_target function that was marked as such
implicitly, potential changes to the `device_type` won't get propagated.

This is because we can't distinguish between a user-specified
`declare_target` function attribute and one added by that pass. This
patch addresses this by adding a new parameter to `DeclareTargetAttr`
that is used by that pass to know whether new `declare_target`
information could be propagated to it.

The `automap` and `implicit` parameters are given default values to
simplify the representation of these attributes.
---
 clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp |   2 +-
 flang/lib/Lower/OpenMP/OpenMP.cpp             |   6 +-
 .../OpenMP/function-filtering-2.f90           |   8 +-
 flang/test/Lower/OpenMP/common-block-map.f90  |   2 +-
 .../test/Lower/OpenMP/declare-target-data.f90 |  38 +++----
 ...are-target-deferred-marking-reductions.f90 |   4 +-
 .../declare-target-deferred-marking.f90       |   8 +-
 .../OpenMP/declare-target-func-and-subr.f90   |  46 ++++----
 ...arget-implicit-func-and-subr-cap-enter.f90 |  38 +++----
 ...lare-target-implicit-func-and-subr-cap.f90 |  42 ++++----
 .../declare-target-implicit-tarop-cap.f90     |  14 +--
 .../OpenMP/declare-target-unnamed-main.f90    |   2 +-
 .../OpenMP/omp-declare-target-program-var.f90 |   2 +-
 .../mlir/Dialect/OpenMP/OpenMPAttrDefs.td     |   3 +-
 .../Dialect/OpenMP/OpenMPOpsInterfaces.td     |  19 +++-
 .../OpenMP/Transforms/FunctionFiltering.cpp   |  19 ++--
 .../OpenMP/Transforms/MarkDeclareTarget.cpp   |  72 +++++--------
 .../Dialect/OpenMP/mark-declare-target.mlir   | 102 +++++++++++-------
 18 files changed, 221 insertions(+), 206 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
index 9a0746e63b6e9..93ec2248f76eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
@@ -190,5 +190,5 @@ void CIRGenOpenMPRuntime::emitDeclareTargetFunction(const FunctionDecl *fd,
       llvm::cast<mlir::omp::DeclareTargetInterface>(funcOp.getOperation());
   declTargetIface.setDeclareTarget(convertDeviceType(attr->getDevType()),
                                    convertCaptureClause(attr->getMapType()),
-                                   /*automap=*/false);
+                                   /*automap=*/false, /*implicit=*/false);
 }
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index f6711bff65a2e..db9af0a288f06 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1793,11 +1793,13 @@ markDeclareTarget(mlir::Operation *op, lower::AbstractConverter &converter,
   if (declareTargetOp.isDeclareTarget()) {
     if (declareTargetOp.getDeclareTargetDeviceType() != deviceType)
       declareTargetOp.setDeclareTarget(mlir::omp::DeclareTargetDeviceType::any,
-                                       captureClause, automap);
+                                       captureClause, automap,
+                                       /*implicit=*/false);
     return;
   }
 
-  declareTargetOp.setDeclareTarget(deviceType, captureClause, automap);
+  declareTargetOp.setDeclareTarget(deviceType, captureClause, automap,
+                                   /*implicit=*/false);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/flang/test/Integration/OpenMP/function-filtering-2.f90 b/flang/test/Integration/OpenMP/function-filtering-2.f90
index ee0c68adc78b3..a5bb5d2165fe7 100644
--- a/flang/test/Integration/OpenMP/function-filtering-2.f90
+++ b/flang/test/Integration/OpenMP/function-filtering-2.f90
@@ -24,13 +24,13 @@ program main
     !$omp end target
 
     contains
-    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}implicit_invocation() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}implicit_invocation() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
     ! MLIR-ALL: llvm.return
     ! LLVM-ALL: define {{.*}} @{{.*}}implicit_invocation{{.*}}(
     subroutine implicit_invocation()
     end subroutine implicit_invocation
 
-    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}declaretarget() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}declaretarget() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
     ! MLIR-ALL: llvm.return
     ! LLVM-ALL: define {{.*}} @{{.*}}declaretarget{{.*}}(
     subroutine declaretarget()
@@ -38,7 +38,7 @@ subroutine declaretarget()
         call implicit_invocation()
     end subroutine declaretarget
 
-    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}declaretarget_enter() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}declaretarget_enter() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
     ! MLIR-ALL: llvm.return
     ! LLVM-ALL: define {{.*}} @{{.*}}declaretarget_enter{{.*}}(
     subroutine declaretarget_enter()
@@ -46,7 +46,7 @@ subroutine declaretarget_enter()
         call implicit_invocation()
     end subroutine declaretarget_enter
 
-    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}no_declaretarget() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+    ! MLIR-ALL: llvm.func{{.*}} @{{.*}}no_declaretarget() attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
     ! MLIR-ALL: llvm.return
     ! LLVM-ALL: define {{.*}} @{{.*}}no_declaretarget{{.*}}(
     subroutine no_declaretarget()
diff --git a/flang/test/Lower/OpenMP/common-block-map.f90 b/flang/test/Lower/OpenMP/common-block-map.f90
index 98836306ef041..a1d9a1430141a 100644
--- a/flang/test/Lower/OpenMP/common-block-map.f90
+++ b/flang/test/Lower/OpenMP/common-block-map.f90
@@ -1,7 +1,7 @@
 !RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
 
 !CHECK: fir.global common @var_common_(dense<0> : vector<8xi8>) {{.*}} : !fir.array<8xi8>
-!CHECK: fir.global common @var_common_link_(dense<0> : vector<8xi8>) {{{.*}} omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : !fir.array<8xi8>
+!CHECK: fir.global common @var_common_link_(dense<0> : vector<8xi8>) {{{.*}} omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<8xi8>
 
 !CHECK-LABEL: func.func @_QPmap_full_block
 !CHECK: %[[CB_ADDR:.*]] = fir.address_of(@var_common_) : !fir.ref<!fir.array<8xi8>>
diff --git a/flang/test/Lower/OpenMP/declare-target-data.f90 b/flang/test/Lower/OpenMP/declare-target-data.f90
index 2e3790303984c..d4f1fb273e068 100644
--- a/flang/test/Lower/OpenMP/declare-target-data.f90
+++ b/flang/test/Lower/OpenMP/declare-target-data.f90
@@ -4,56 +4,56 @@
 module test_0
     implicit none
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_int {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : i32
+!CHECK-DAG: fir.global @_QMtest_0Edata_int {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32
 INTEGER :: data_int = 10
 !$omp declare target link(data_int)
 
-!CHECK-DAG: fir.global @_QMtest_0Earray_1d({{.*}}) {alignment = 64 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : !fir.array<3xi32>
+!CHECK-DAG: fir.global @_QMtest_0Earray_1d({{.*}}) {alignment = 64 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<3xi32>
 INTEGER :: array_1d(3) = (/1,2,3/)
 !$omp declare target link(array_1d)
 
-!CHECK-DAG: fir.global @_QMtest_0Earray_2d({{.*}}) {alignment = 64 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : !fir.array<2x2xi32>
+!CHECK-DAG: fir.global @_QMtest_0Earray_2d({{.*}}) {alignment = 64 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<2x2xi32>
 INTEGER :: array_2d(2,2) = reshape((/1,2,3,4/), (/2,2/))
 !$omp declare target link(array_2d)
 
-!CHECK-DAG: fir.global @_QMtest_0Ept1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : !fir.box<!fir.ptr<i32>>
+!CHECK-DAG: fir.global @_QMtest_0Ept1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.box<!fir.ptr<i32>>
 INTEGER, POINTER :: pt1
 !$omp declare target link(pt1)
 
-!CHECK-DAG: fir.global @_QMtest_0Ept2_tar {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} target : i32
+!CHECK-DAG: fir.global @_QMtest_0Ept2_tar {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} target : i32
 INTEGER, TARGET :: pt2_tar = 5
 !$omp declare target link(pt2_tar)
 
-!CHECK-DAG: fir.global @_QMtest_0Ept2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : !fir.box<!fir.ptr<i32>>
+!CHECK-DAG: fir.global @_QMtest_0Ept2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.box<!fir.ptr<i32>>
 INTEGER, POINTER :: pt2 => pt2_tar
 !$omp declare target link(pt2)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_int_to {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : i32
+!CHECK-DAG: fir.global @_QMtest_0Edata_int_to {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : i32
 INTEGER :: data_int_to = 5
 !$omp declare target to(data_int_to)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_int_enter {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : i32
+!CHECK-DAG: fir.global @_QMtest_0Edata_int_enter {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : i32
 INTEGER :: data_int_enter = 5
 !$omp declare target enter(data_int_enter)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_int_clauseless {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : i32
+!CHECK-DAG: fir.global @_QMtest_0Edata_int_clauseless {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : i32
 INTEGER :: data_int_clauseless = 1
 !$omp declare target(data_int_clauseless)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_to_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : f32
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_to_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_to_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_to_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : f32
 REAL :: data_extended_to_1 = 2
 REAL :: data_extended_to_2 = 3
 !$omp declare target to(data_extended_to_1, data_extended_to_2)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_enter_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : f32
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_enter_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_enter_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_enter_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : f32
 REAL :: data_extended_enter_1 = 2
 REAL :: data_extended_enter_2 = 3
 !$omp declare target enter(data_extended_enter_1, data_extended_enter_2)
 
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_link_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : f32
-!CHECK-DAG: fir.global @_QMtest_0Edata_extended_link_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_link_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32
+!CHECK-DAG: fir.global @_QMtest_0Edata_extended_link_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32
 REAL :: data_extended_link_1 = 2
 REAL :: data_extended_link_2 = 3
 !$omp declare target link(data_extended_link_1, data_extended_link_2)
@@ -66,25 +66,25 @@ module test_0
 end module test_0
 
 PROGRAM commons
-    !CHECK-DAG: fir.global @numbers_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : tuple<f32, f32> {
+    !CHECK-DAG: fir.global @numbers_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
     REAL :: one = 1
     REAL :: two = 2
     COMMON /numbers/ one, two
     !$omp declare target(/numbers/)
 
-    !CHECK-DAG: fir.global @numbers_link_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link), automap = false>} : tuple<f32, f32> {
+    !CHECK-DAG: fir.global @numbers_link_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : tuple<f32, f32> {
     REAL :: one_link = 1
     REAL :: two_link = 2
     COMMON /numbers_link/ one_link, two_link
     !$omp declare target link(/numbers_link/)
 
-    !CHECK-DAG: fir.global @numbers_to_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : tuple<f32, f32> {
+    !CHECK-DAG: fir.global @numbers_to_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : tuple<f32, f32> {
     REAL :: one_to = 1
     REAL :: two_to = 2
     COMMON /numbers_to/ one_to, two_to
     !$omp declare target to(/numbers_to/)
 
-    !CHECK-DAG: fir.global @numbers_enter_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>} : tuple<f32, f32> {
+    !CHECK-DAG: fir.global @numbers_enter_ {alignment = 4 : i64, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>} : tuple<f32, f32> {
     REAL :: one_enter = 1
     REAL :: two_enter = 2
     COMMON /numbers_enter/ one_enter, two_enter
diff --git a/flang/test/Lower/OpenMP/declare-target-deferred-marking-reductions.f90 b/flang/test/Lower/OpenMP/declare-target-deferred-marking-reductions.f90
index a95561389364c..4741de56ff704 100644
--- a/flang/test/Lower/OpenMP/declare-target-deferred-marking-reductions.f90
+++ b/flang/test/Lower/OpenMP/declare-target-deferred-marking-reductions.f90
@@ -31,6 +31,6 @@ end function mycombine
  end program main
 
 !CHECK: llvm.func @myinit(!llvm.ptr, !llvm.ptr)
-!CHECK-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+!CHECK-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}
 !CHECK-LABEL: llvm.func @mycombine(!llvm.ptr, !llvm.ptr)
-!CHECK-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+!CHECK-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}
diff --git a/flang/test/Lower/OpenMP/declare-target-deferred-marking.f90 b/flang/test/Lower/OpenMP/declare-target-deferred-marking.f90
index a82e2f31afa93..9fdfcdae3e7e1 100644
--- a/flang/test/Lower/OpenMP/declare-target-deferred-marking.f90
+++ b/flang/test/Lower/OpenMP/declare-target-deferred-marking.f90
@@ -51,10 +51,10 @@ end subroutine unused_unemitted_interface
  end program main
 
 !HOST-LABEL: llvm.func @host_interface()
-!HOST-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}
+!HOST-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}
 !ALL-LABEL: llvm.func @called_from_target_interface(!llvm.ptr, !llvm.ptr)
-!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}
 !ALL-LABEL: llvm.func @any_interface()
-!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>{{.*}}
+!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}
 !ALL-LABEL: llvm.func @device_interface()
-!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}
+!ALL-SAME: {{.*}}, omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
diff --git a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90 b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
index 46465eece5050..8db8c620042c5 100644
--- a/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
+++ b/flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
@@ -6,7 +6,7 @@
 ! zero clause declare target
 
 ! DEVICE-LABEL: func.func @_QPfunc_t_device()
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_T_DEVICE() RESULT(I)
 !$omp declare target to(FUNC_T_DEVICE) device_type(nohost)
     INTEGER :: I
@@ -14,7 +14,7 @@ FUNCTION FUNC_T_DEVICE() RESULT(I)
 END FUNCTION FUNC_T_DEVICE
 
 ! DEVICE-LABEL: func.func @_QPfunc_enter_device()
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
 FUNCTION FUNC_ENTER_DEVICE() RESULT(I)
 !$omp declare target enter(FUNC_ENTER_DEVICE) device_type(nohost)
     INTEGER :: I
@@ -22,7 +22,7 @@ FUNCTION FUNC_ENTER_DEVICE() RESULT(I)
 END FUNCTION FUNC_ENTER_DEVICE
 
 ! HOST-LABEL: func.func @_QPfunc_t_host()
-! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}
+! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_T_HOST() RESULT(I)
 !$omp declare target to(FUNC_T_HOST) device_type(host)
     INTEGER :: I
@@ -30,7 +30,7 @@ FUNCTION FUNC_T_HOST() RESULT(I)
 END FUNCTION FUNC_T_HOST
 
 ! HOST-LABEL: func.func @_QPfunc_enter_host()
-! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}
+! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}
 FUNCTION FUNC_ENTER_HOST() RESULT(I)
 !$omp declare target enter(FUNC_ENTER_HOST) device_type(host)
     INTEGER :: I
@@ -38,7 +38,7 @@ FUNCTION FUNC_ENTER_HOST() RESULT(I)
 END FUNCTION FUNC_ENTER_HOST
 
 ! ALL-LABEL: func.func @_QPfunc_t_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_T_ANY() RESULT(I)
 !$omp declare target to(FUNC_T_ANY) device_type(any)
     INTEGER :: I
@@ -46,7 +46,7 @@ FUNCTION FUNC_T_ANY() RESULT(I)
 END FUNCTION FUNC_T_ANY
 
 ! ALL-LABEL: func.func @_QPfunc_enter_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}
 FUNCTION FUNC_ENTER_ANY() RESULT(I)
 !$omp declare target enter(FUNC_ENTER_ANY) device_type(any)
     INTEGER :: I
@@ -54,7 +54,7 @@ FUNCTION FUNC_ENTER_ANY() RESULT(I)
 END FUNCTION FUNC_ENTER_ANY
 
 ! ALL-LABEL: func.func @_QPfunc_default_t_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_DEFAULT_T_ANY() RESULT(I)
 !$omp declare target to(FUNC_DEFAULT_T_ANY)
     INTEGER :: I
@@ -62,7 +62,7 @@ FUNCTION FUNC_DEFAULT_T_ANY() RESULT(I)
 END FUNCTION FUNC_DEFAULT_T_ANY
 
 ! ALL-LABEL: func.func @_QPfunc_default_enter_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}
 FUNCTION FUNC_DEFAULT_ENTER_ANY() RESULT(I)
 !$omp declare target enter(FUNC_DEFAULT_ENTER_ANY)
     INTEGER :: I
@@ -70,7 +70,7 @@ FUNCTION FUNC_DEFAULT_ENTER_ANY() RESULT(I)
 END FUNCTION FUNC_DEFAULT_ENTER_ANY
 
 ! ALL-LABEL: func.func @_QPfunc_default_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_DEFAULT_ANY() RESULT(I)
 !$omp declare target
     INTEGER :: I
@@ -78,7 +78,7 @@ FUNCTION FUNC_DEFAULT_ANY() RESULT(I)
 END FUNCTION FUNC_DEFAULT_ANY
 
 ! ALL-LABEL: func.func @_QPfunc_default_extendedlist()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_DEFAULT_EXTENDEDLIST() RESULT(I)
 !$omp declare target(FUNC_DEFAULT_EXTENDEDLIST)
     INTEGER :: I
@@ -86,7 +86,7 @@ FUNCTION FUNC_DEFAULT_EXTENDEDLIST() RESULT(I)
 END FUNCTION FUNC_DEFAULT_EXTENDEDLIST
 
 ! ALL-LABEL: func.func @_QPfunc_name_as_result()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 FUNCTION FUNC_NAME_AS_RESULT()
 !$omp declare target(FUNC_NAME_AS_RESULT)
   FUNC_NAME_AS_RESULT = 1.0
@@ -99,61 +99,61 @@ END FUNCTION FUNC_NAME_AS_RESULT
 ! zero clause declare target
 
 ! DEVICE-LABEL: func.func @_QPsubr_t_device()
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_T_DEVICE()
 !$omp declare target to(SUBR_T_DEVICE) device_type(nohost)
 END
 
 ! DEVICE-LABEL: func.func @_QPsubr_enter_device()
-! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
 SUBROUTINE SUBR_ENTER_DEVICE()
 !$omp declare target enter(SUBR_ENTER_DEVICE) device_type(nohost)
 END
 
 ! HOST-LABEL: func.func @_QPsubr_t_host()
-! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}
+! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_T_HOST()
 !$omp declare target to(SUBR_T_HOST) device_type(host)
 END
 
 ! HOST-LABEL: func.func @_QPsubr_enter_host()
-! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}
+! HOST-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}
 SUBROUTINE SUBR_ENTER_HOST()
 !$omp declare target enter(SUBR_ENTER_HOST) device_type(host)
 END
 
 ! ALL-LABEL: func.func @_QPsubr_t_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_T_ANY()
 !$omp declare target to(SUBR_T_ANY) device_type(any)
 END
 
 ! ALL-LABEL: func.func @_QPsubr_enter_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}
 SUBROUTINE SUBR_ENTER_ANY()
 !$omp declare target enter(SUBR_ENTER_ANY) device_type(any)
 END
 
 ! ALL-LABEL: func.func @_QPsubr_default_t_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_DEFAULT_T_ANY()
 !$omp declare target to(SUBR_DEFAULT_T_ANY)
 END
 
 ! ALL-LABEL: func.func @_QPsubr_default_enter_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}
 SUBROUTINE SUBR_DEFAULT_ENTER_ANY()
 !$omp declare target enter(SUBR_DEFAULT_ENTER_ANY)
 END
 
 ! ALL-LABEL: func.func @_QPsubr_default_any()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_DEFAULT_ANY()
 !$omp declare target
 END
 
 ! ALL-LABEL: func.func @_QPsubr_default_extendedlist()
-! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}
+! ALL-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}
 SUBROUTINE SUBR_DEFAULT_EXTENDEDLIST()
 !$omp declare target(SUBR_DEFAULT_EXTENDEDLIST)
 END
@@ -161,7 +161,7 @@ SUBROUTINE SUBR_DEFAULT_EXTENDEDLIST()
 !! -----
 
 ! DEVICE-LABEL: func.func @_QPrecursive_declare_target
-! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}
 RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
 !$omp declare target to(RECURSIVE_DECLARE_TARGET) device_type(nohost)
     INTEGER :: INCREMENT, K
@@ -173,7 +173,7 @@ RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET(INCREMENT) RESULT(K)
 END FUNCTION RECURSIVE_DECLARE_TARGET
 
 ! DEVICE-LABEL: func.func @_QPrecursive_declare_target_enter
-! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}
+! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}
 RECURSIVE FUNCTION RECURSIVE_DECLARE_TARGET_ENTER(INCREMENT) RESULT(K)
 !$omp declare target enter(RECURSIVE_DECLARE_TARGET_ENTER) device_type(nohost)
     INTEGER :: INCREMENT, K
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
index 26a458e34c950..0d16e5bc1b0d1 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap-enter.f90
@@ -28,7 +28,7 @@ recursive subroutine implicitly_captured_recursive(increment)
 
    contains
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_twice
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_twice() result(k)
       integer :: i
       i = 10
@@ -36,7 +36,7 @@ function implicitly_captured_twice() result(k)
    end function implicitly_captured_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPtarget_function_twice_host()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}}
    function target_function_twice_host() result(i)
    !$omp declare target enter(target_function_twice_host) device_type(host)
       integer :: i
@@ -44,7 +44,7 @@ function target_function_twice_host() result(i)
    end function target_function_twice_host
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_twice_device()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
    function target_function_twice_device() result(i)
    !$omp declare target enter(target_function_twice_device) device_type(nohost)
       integer :: i
@@ -54,7 +54,7 @@ end function target_function_twice_device
    !! -----
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest() result(k)
       integer :: i
       i = 10
@@ -62,13 +62,13 @@ function implicitly_captured_nest() result(k)
    end function implicitly_captured_nest
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to){{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_one() result(k)
       k = implicitly_captured_nest()
    end function implicitly_captured_one
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_two()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two() result(k)
       integer :: i
       i = 10
@@ -76,7 +76,7 @@ function implicitly_captured_two() result(k)
    end function implicitly_captured_two
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_test()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
    function target_function_test() result(j)
    !$omp declare target enter(target_function_test) device_type(nohost)
       integer :: i, j
@@ -87,7 +87,7 @@ end function target_function_test
    !! -----
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice() result(k)
       integer :: i
       i = 10
@@ -95,13 +95,13 @@ function implicitly_captured_nest_twice() result(k)
    end function implicitly_captured_nest_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_one_twice() result(k)
       k = implicitly_captured_nest_twice()
    end function implicitly_captured_one_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_two_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two_twice() result(k)
       integer :: i
       i = 10
@@ -109,7 +109,7 @@ function implicitly_captured_two_twice() result(k)
    end function implicitly_captured_two_twice
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_test_device()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
    function target_function_test_device() result(j)
       !$omp declare target enter(target_function_test_device) device_type(nohost)
       integer :: i, j
@@ -118,7 +118,7 @@ function target_function_test_device() result(j)
    end function target_function_test_device
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPtarget_function_test_host()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}}
    function target_function_test_host() result(j)
       !$omp declare target enter(target_function_test_host) device_type(host)
       integer :: i, j
@@ -142,7 +142,7 @@ recursive function implicitly_captured_with_dev_type_recursive(increment) result
 end function implicitly_captured_with_dev_type_recursive
 
 ! DEVICE-LABEL: llvm.func @_QPtarget_function_with_dev_type_recurse()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
 function target_function_with_dev_type_recurse() result(i)
 !$omp declare target enter(target_function_with_dev_type_recurse) device_type(nohost)
    integer :: i
@@ -154,28 +154,28 @@ end function target_function_with_dev_type_recurse
 module test_module
 contains
 ! CHECK-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_nest_twice()
-! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice() result(i)
       integer :: i
       i = 10
    end function implicitly_captured_nest_twice
 
 ! CHECK-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_one_twice()
-! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}}
+! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}}
    function implicitly_captured_one_twice() result(k)
       !$omp declare target enter(implicitly_captured_one_twice) device_type(host)
       k = implicitly_captured_nest_twice()
    end function implicitly_captured_one_twice
 
 ! DEVICE-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_two_twice()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two_twice() result(y)
       integer :: y
       y = 5
    end function implicitly_captured_two_twice
 
 ! DEVICE-LABEL: llvm.func @_QMtest_modulePtarget_function_test_device()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
    function target_function_test_device() result(j)
       !$omp declare target enter(target_function_test_device) device_type(nohost)
       integer :: i, j
@@ -187,7 +187,7 @@ end module test_module
 !! -----
 
 ! DEVICE-LABEL: llvm.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
 recursive subroutine implicitly_captured_recursive(increment)
    integer :: increment
    if (increment == 10) then
@@ -198,7 +198,7 @@ recursive subroutine implicitly_captured_recursive(increment)
 end subroutine
 
 ! DEVICE-LABEL: llvm.func @_QPcaller_recursive
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (enter)>{{.*}}}
 subroutine caller_recursive
 !$omp declare target enter(caller_recursive) device_type(nohost)
    call implicitly_captured_recursive(0)
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
index 7fd3ca9b4e32e..dbce61c44e85b 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-func-and-subr-cap.f90
@@ -29,7 +29,7 @@ recursive subroutine implicitly_captured_recursive(increment)
 
    contains
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured(
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured(toggle) result(k)
       integer :: i, j, k
       logical :: toggle
@@ -43,7 +43,7 @@ function implicitly_captured(toggle) result(k)
    end function implicitly_captured
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPtarget_function(
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
    function target_function(toggle) result(i)
    !$omp declare target
       integer :: i
@@ -54,7 +54,7 @@ end function target_function
    !! -----
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_twice() result(k)
       integer :: i
       i = 10
@@ -62,7 +62,7 @@ function implicitly_captured_twice() result(k)
    end function implicitly_captured_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPtarget_function_twice_host()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}}
    function target_function_twice_host() result(i)
    !$omp declare target to(target_function_twice_host) device_type(host)
       integer :: i
@@ -70,7 +70,7 @@ function target_function_twice_host() result(i)
    end function target_function_twice_host
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_twice_device()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
    function target_function_twice_device() result(i)
    !$omp declare target to(target_function_twice_device) device_type(nohost)
       integer :: i
@@ -80,7 +80,7 @@ end function target_function_twice_device
    !! -----
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest() result(k)
       integer :: i
       i = 10
@@ -88,13 +88,13 @@ function implicitly_captured_nest() result(k)
    end function implicitly_captured_nest
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to){{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_one() result(k)
       k = implicitly_captured_nest()
    end function implicitly_captured_one
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_two()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two() result(k)
       integer :: i
       i = 10
@@ -102,7 +102,7 @@ function implicitly_captured_two() result(k)
    end function implicitly_captured_two
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_test()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
    function target_function_test() result(j)
    !$omp declare target to(target_function_test) device_type(nohost)
       integer :: i, j
@@ -113,7 +113,7 @@ end function target_function_test
    !! -----
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice() result(k)
       integer :: i
       i = 10
@@ -121,13 +121,13 @@ function implicitly_captured_nest_twice() result(k)
    end function implicitly_captured_nest_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_one_twice() result(k)
       k = implicitly_captured_nest_twice()
    end function implicitly_captured_one_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_two_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two_twice() result(k)
       integer :: i
       i = 10
@@ -135,7 +135,7 @@ function implicitly_captured_two_twice() result(k)
    end function implicitly_captured_two_twice
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPtarget_function_test_device()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
    function target_function_test_device() result(j)
       !$omp declare target to(target_function_test_device) device_type(nohost)
       integer :: i, j
@@ -144,7 +144,7 @@ function target_function_test_device() result(j)
    end function target_function_test_device
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPtarget_function_test_host()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}}
    function target_function_test_host() result(j)
       !$omp declare target to(target_function_test_host) device_type(host)
       integer :: i, j
@@ -168,7 +168,7 @@ recursive function implicitly_captured_with_dev_type_recursive(increment) result
 end function implicitly_captured_with_dev_type_recursive
 
 ! DEVICE-LABEL: llvm.func @_QPtarget_function_with_dev_type_recurse()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
 function target_function_with_dev_type_recurse() result(i)
 !$omp declare target to(target_function_with_dev_type_recurse) device_type(nohost)
    integer :: i
@@ -180,28 +180,28 @@ end function target_function_with_dev_type_recurse
 module test_module
 contains
 ! CHECK-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_nest_twice()
-! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice() result(i)
       integer :: i
       i = 10
    end function implicitly_captured_nest_twice
 
 ! CHECK-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_one_twice()
-! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}}
    function implicitly_captured_one_twice() result(k)
       !$omp declare target to(implicitly_captured_one_twice) device_type(host)
       k = implicitly_captured_nest_twice()
    end function implicitly_captured_one_twice
 
 ! DEVICE-LABEL: llvm.func @_QMtest_modulePimplicitly_captured_two_twice()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two_twice() result(y)
       integer :: y
       y = 5
    end function implicitly_captured_two_twice
 
 ! DEVICE-LABEL: llvm.func @_QMtest_modulePtarget_function_test_device()
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
    function target_function_test_device() result(j)
       !$omp declare target to(target_function_test_device) device_type(nohost)
       integer :: i, j
@@ -213,7 +213,7 @@ end module test_module
 !! -----
 
 ! DEVICE-LABEL: llvm.func @_QPimplicitly_captured_recursive
-! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>{{.*}}}
 recursive subroutine implicitly_captured_recursive(increment)
    integer :: increment
    if (increment == 10) then
@@ -224,7 +224,7 @@ recursive subroutine implicitly_captured_recursive(increment)
 end subroutine
 
 ! DEVICE-LABEL: llvm.func @_QPcaller_recursive
-! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
 subroutine caller_recursive
 !$omp declare target to(caller_recursive) device_type(nohost)
    call implicitly_captured_recursive(0)
diff --git a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90 b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
index eca6e5ba39267..f89484d988d2d 100644
--- a/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
+++ b/flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
@@ -15,7 +15,7 @@ program main
 
    contains
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicit_capture()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicit_capture() result(i)
       implicit none
       integer :: i
@@ -32,35 +32,35 @@ subroutine subr_target()
    !! -----
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice() result(i)
       integer :: i
       i = 10
    end function implicitly_captured_nest_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one_twice()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>{{.*}}}
    function implicitly_captured_one_twice() result(k)
    !$omp declare target to(implicitly_captured_one_twice) device_type(host)
       k = implicitly_captured_nest_twice()
    end function implicitly_captured_one_twice
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_nest_twice_enter()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_nest_twice_enter() result(i)
       integer :: i
       i = 10
    end function implicitly_captured_nest_twice_enter
 
    ! CHECK-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_one_twice_enter()
-   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter), automap = false>{{.*}}}
+   ! CHECK-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (enter)>{{.*}}}
    function implicitly_captured_one_twice_enter() result(k)
    !$omp declare target enter(implicitly_captured_one_twice_enter) device_type(host)
       k = implicitly_captured_nest_twice_enter()
    end function implicitly_captured_one_twice_enter
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_two_twice()
-   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    function implicitly_captured_two_twice() result(y)
       integer :: y
       y = 5
@@ -78,7 +78,7 @@ end function target_function_test_device
    !! -----
 
    ! DEVICE-LABEL: llvm.func{{.*}} @_QFPimplicitly_captured_recursive(
-   ! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>{{.*}}}
+   ! DEVICE-SAME: {{.*}}attributes {{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>{{.*}}}
    recursive function implicitly_captured_recursive(increment) result(k)
       integer :: increment, k
       if (increment == 10) then
diff --git a/flang/test/Lower/OpenMP/declare-target-unnamed-main.f90 b/flang/test/Lower/OpenMP/declare-target-unnamed-main.f90
index f54f7ed14d1d5..b7d6d2fa232ad 100644
--- a/flang/test/Lower/OpenMP/declare-target-unnamed-main.f90
+++ b/flang/test/Lower/OpenMP/declare-target-unnamed-main.f90
@@ -7,7 +7,7 @@
 ! appropriately mark the function as declare target, even when
 ! unused within the target region.
 
-!CHECK: func.func @_QPfoo(%{{.*}}: !fir.ref<f32>{{.*}}) -> f32 attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>{{.*}}}
+!CHECK: func.func @_QPfoo(%{{.*}}: !fir.ref<f32>{{.*}}) -> f32 attributes {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
 
 interface
 real function foo (x)
diff --git a/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90 b/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90
index dc23a8190cb8d..d18f42ae3ceb0 100644
--- a/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90
+++ b/flang/test/Lower/OpenMP/omp-declare-target-program-var.f90
@@ -5,7 +5,7 @@ PROGRAM main
     ! HOST-DAG: %[[I_REF:.*]] = fir.alloca f32 {bindc_name = "i", uniq_name = "_QFEi"}
     ! HOST-DAG: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]] {uniq_name = "_QFEi"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
     REAL :: I
-    ! ALL-DAG: fir.global internal @_QFEi {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>} : f32 {
+    ! ALL-DAG: fir.global internal @_QFEi {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : f32 {
     ! ALL-DAG: %[[UNDEF:.*]] = fir.zero_bits f32
     ! ALL-DAG: fir.has_value %[[UNDEF]] : f32
     ! ALL-DAG: }
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
index f6bc8f11ccccb..4eb0d9c04e305 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPAttrDefs.td
@@ -45,7 +45,8 @@ def DeclareTargetAttr : OpenMP_Attr<"DeclareTarget", "declaretarget"> {
   let parameters =
       (ins OptionalParameter<"DeclareTargetDeviceTypeAttr">:$device_type,
           OptionalParameter<"DeclareTargetCaptureClauseAttr">:$capture_clause,
-          OptionalParameter<"BoolAttr">:$automap);
+          DefaultValuedParameter<"bool", "false">:$automap,
+          DefaultValuedParameter<"bool", "false">:$implicit);
 
   let assemblyFormat = "`<` struct(params) `>`";
 }
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
index 51f925b17f47e..66730ae52d8ee 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
@@ -376,7 +376,7 @@ def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
       /*methodName=*/"setDeclareTarget",
       (ins "mlir::omp::DeclareTargetDeviceType":$deviceType,
            "mlir::omp::DeclareTargetCaptureClause":$captureClause,
-           "bool":$automap), [{}], [{
+           "bool":$automap, "bool":$implicit), [{}], [{
         $_op->setAttr("omp.declare_target",
                   mlir::omp::DeclareTargetAttr::get(
                       $_op->getContext(),
@@ -384,7 +384,7 @@ def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
                           $_op->getContext(), deviceType),
                       mlir::omp::DeclareTargetCaptureClauseAttr::get(
                           $_op->getContext(), captureClause),
-                      mlir::BoolAttr::get($_op->getContext(), automap)));
+                      automap, implicit));
       }]>,
       InterfaceMethod<
       /*description=*/[{
@@ -432,8 +432,19 @@ def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
       (ins), [{}], [{
         if (mlir::Attribute dTar = $_op->getAttr("omp.declare_target"))
           if (auto dAttr = llvm::dyn_cast_or_null<mlir::omp::DeclareTargetAttr>(dTar))
-            if (auto autoVal = dAttr.getAutomap())
-              return autoVal.getValue();
+            return dAttr.getAutomap();
+         return false;
+      }]>,
+      InterfaceMethod<
+      /*description=*/[{
+        Return true if the DeclareTarget attribute has been implicitly added.
+      }],
+      /*retTy=*/"bool",
+      /*methodName=*/"isImplicitDeclareTarget",
+      (ins), [{}], [{
+        if (mlir::Attribute dTar = $_op->getAttr("omp.declare_target"))
+          if (auto dAttr = llvm::dyn_cast_or_null<mlir::omp::DeclareTargetAttr>(dTar))
+            return dAttr.getImplicit();
          return false;
       }]>
   ];
diff --git a/mlir/lib/Dialect/OpenMP/Transforms/FunctionFiltering.cpp b/mlir/lib/Dialect/OpenMP/Transforms/FunctionFiltering.cpp
index 1d4eaaa0fb6de..3b236dd69f425 100644
--- a/mlir/lib/Dialect/OpenMP/Transforms/FunctionFiltering.cpp
+++ b/mlir/lib/Dialect/OpenMP/Transforms/FunctionFiltering.cpp
@@ -58,11 +58,8 @@ class FunctionFilteringPass
       if (declareTargetOp && declareTargetOp.isDeclareTarget())
         declareType = declareTargetOp.getDeclareTargetDeviceType();
 
-      // Filtering a function here means deleting it if it doesn't contain a
-      // target region. Else we explicitly set the omp.declare_target
-      // attribute. The second stage of function filtering at the MLIR to LLVM
-      // IR translation level will remove functions that contain the target
-      // region from the generated LLVM IR.
+      // Only filter host functions from device modules because the host needs
+      // to provide fallback implementations of device code.
       if (declareType != omp::DeclareTargetDeviceType::host)
         return WalkResult::advance();
 
@@ -97,10 +94,14 @@ class FunctionFilteringPass
         return WalkResult::skip();
       }
 
-      if (declareTargetOp)
-        declareTargetOp.setDeclareTarget(
-            declareType, omp::DeclareTargetCaptureClause::to,
-            declareTargetOp.getDeclareTargetAutomap());
+      // MLIR to LLVM IR translation relies on host functions being explicitly
+      // marked as such to perform the second stage removal them from the device
+      // module, where functions that contain target regions are deleted from
+      // the generated LLVM IR.
+      if (declareTargetOp && !declareTargetOp.isDeclareTarget())
+        declareTargetOp.setDeclareTarget(omp::DeclareTargetDeviceType::host,
+                                         omp::DeclareTargetCaptureClause::to,
+                                         /*automap=*/false, /*implicit=*/true);
       return WalkResult::advance();
     });
   }
diff --git a/mlir/lib/Dialect/OpenMP/Transforms/MarkDeclareTarget.cpp b/mlir/lib/Dialect/OpenMP/Transforms/MarkDeclareTarget.cpp
index 138f36f74f644..d988752da84b9 100644
--- a/mlir/lib/Dialect/OpenMP/Transforms/MarkDeclareTarget.cpp
+++ b/mlir/lib/Dialect/OpenMP/Transforms/MarkDeclareTarget.cpp
@@ -154,17 +154,6 @@ static void gatherNestedSymbolUses(Operation &op,
 
 namespace {
 
-// If this pass runs more than once, something like this can happen:
-// - 1st run: The pass marks an external function as declare_target with
-//   device_type(nohost) based on there being a single call from an omp.target.
-// - Somewhere in between: New calls to that external function are added to the
-//   host part of the application (e.g. it is part of a standard library).
-// - 2nd run: The pass doesn't update the function after seeing it's reachable
-//   by the host because it's unable to tell that the declare_target information
-//   wasn't explicitly added by the user.
-// TODO: This can be fixed by adding a discardable attribute only used by this
-// pass or by extending the DeclareTargetInterface to also store whether it is
-// implicit or explicit.
 class MarkDeclareTargetPass
     : public omp::impl::MarkDeclareTargetPassBase<MarkDeclareTargetPass> {
 
@@ -245,10 +234,9 @@ class MarkDeclareTargetPass
       worklist.push_back(
           {callee.getKey(), omp::DeclareTargetDeviceType::nohost});
 
-    // Process the work list storing intermediate declare target information
-    // separately to avoid mixing up explicit declare_target functions with
-    // implicitly propagated information.
-    llvm::StringMap<omp::DeclareTargetDeviceType> intermediateInfos;
+    // Process the work list by propagating changes to other non-explicit
+    // declare_target functions based on the call graph, until no updates are
+    // left.
     while (!worklist.empty()) {
       std::pair<StringRef, omp::DeclareTargetDeviceType> workItem =
           worklist.pop_back_val();
@@ -259,27 +247,16 @@ class MarkDeclareTargetPass
       // doesn't support the interface. We only want to propagate implicit
       // declare_target information to functions for which the user hasn't
       // specified an explicit behavior.
-      if (auto declareTargetOp =
-              dyn_cast<omp::DeclareTargetInterface>(*funcOp)) {
-        if (declareTargetOp.isDeclareTarget())
-          continue;
-      } else {
+      auto declareTargetOp = dyn_cast<omp::DeclareTargetInterface>(*funcOp);
+      if (!declareTargetOp || (declareTargetOp.isDeclareTarget() &&
+                               !declareTargetOp.isImplicitDeclareTarget()))
         continue;
-      }
 
       omp::DeclareTargetDeviceType changedDeviceType;
-      if (!intermediateInfos.contains(workItem.first)) {
-        // Prevent public and external functions from being restricted to a
-        // device. We don't have visibility over all their uses.
-        if (funcOp.isPublic() || funcOp.isExternal())
-          changedDeviceType = omp::DeclareTargetDeviceType::any;
-        else
-          changedDeviceType = workItem.second;
-
-        intermediateInfos.try_emplace(workItem.first, changedDeviceType);
-      } else {
-        omp::DeclareTargetDeviceType &currentDeviceType =
-            intermediateInfos[workItem.first];
+      if (declareTargetOp.isDeclareTarget()) {
+        // Implicit declare_target update.
+        omp::DeclareTargetDeviceType currentDeviceType =
+            declareTargetOp.getDeclareTargetDeviceType();
 
         // Skip the update (and adding callees to the worklist) if the added
         // info doesn't change anything.
@@ -290,25 +267,26 @@ class MarkDeclareTargetPass
 
         // Update intermediate information about this function. By the previous
         // check, we know it's host + nohost = any.
-        changedDeviceType = currentDeviceType =
-            omp::DeclareTargetDeviceType::any;
+        changedDeviceType = omp::DeclareTargetDeviceType::any;
+      } else {
+        // No declare_target information present.
+
+        // Prevent public and external functions from being restricted to a
+        // device. We don't have visibility over all their uses.
+        if (funcOp.isPublic() || funcOp.isExternal())
+          changedDeviceType = omp::DeclareTargetDeviceType::any;
+        else
+          changedDeviceType = workItem.second;
       }
 
-      // Add callees to the worklist to propagate the update.
+      // Update the operation and add callees to the worklist to propagate it.
+      declareTargetOp.setDeclareTarget(changedDeviceType,
+                                       omp::DeclareTargetCaptureClause::to,
+                                       /*automap=*/false, /*implicit=*/true);
+
       for (auto &callee : calls[workItem.first])
         worklist.push_back({callee.getKey(), changedDeviceType});
     }
-
-    // Apply the final intermediate results to the corresponding operations.
-    for (auto &[funcName, deviceType] : intermediateInfos) {
-      auto declareTargetOp =
-          modOp.lookupSymbol<omp::DeclareTargetInterface>(funcName);
-      assert(declareTargetOp &&
-             "declare_target info attached to incompatible operation");
-      declareTargetOp.setDeclareTarget(deviceType,
-                                       omp::DeclareTargetCaptureClause::to,
-                                       /*automap=*/false);
-    }
   }
 };
 } // namespace
diff --git a/mlir/test/Dialect/OpenMP/mark-declare-target.mlir b/mlir/test/Dialect/OpenMP/mark-declare-target.mlir
index 389510c4eedb4..a50e4678aa37d 100644
--- a/mlir/test/Dialect/OpenMP/mark-declare-target.mlir
+++ b/mlir/test/Dialect/OpenMP/mark-declare-target.mlir
@@ -17,23 +17,23 @@ omp.private {type = firstprivate} @priv : !llvm.struct<(ptr)> init {
 }
 
 // CHECK: llvm.func {{.*}}@priv_callee_nested()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee_nested() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@priv_callee_init()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee_init() attributes {sym_visibility = "private"} {
   llvm.call @priv_callee_nested() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@priv_callee_copy()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee_copy() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@priv_callee_dealloc()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee_dealloc() attributes {sym_visibility = "private"} {
   llvm.return
 }
@@ -74,31 +74,31 @@ cleanup {
 }
 
 // CHECK: llvm.func {{.*}}@red_callee_nested()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>
 llvm.func @red_callee_nested() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@red_callee_init()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>
 llvm.func @red_callee_init() attributes {sym_visibility = "private"} {
   llvm.call @red_callee_nested() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@red_callee_combiner()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>
 llvm.func @red_callee_combiner() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@red_callee_cleanup()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>
 llvm.func @red_callee_cleanup() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@main(
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>
 llvm.func @main(%arg0 : !llvm.ptr) attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (host), capture_clause = (to), automap = false>} {
+        device_type = (host), capture_clause = (to)>} {
   omp.parallel reduction(@red %arg0 -> %arg1 : !llvm.ptr) {
     omp.terminator
   }
@@ -138,24 +138,24 @@ cleanup {
 }
 
 // CHECK: llvm.func {{.*}}@red_callee_nested2()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @red_callee_nested2() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@red_callee_nested()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @red_callee_nested() attributes {sym_visibility = "private"} {
   llvm.call @red_callee_nested2() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@red_callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @red_callee() attributes {sym_visibility = "private"} {
   llvm.call @red_callee_nested() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@priv_callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee() attributes {sym_visibility = "private"} {
   %0 = llvm.mlir.constant(1 : i64) : i64
   %1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr
@@ -165,7 +165,7 @@ llvm.func @priv_callee() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@main_callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @main_callee() attributes {sym_visibility = "private"} {
   %0 = llvm.mlir.constant(1 : i64) : i64
   %1 = llvm.alloca %0 x i32 : (i64) -> !llvm.ptr
@@ -175,10 +175,10 @@ llvm.func @main_callee() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@main()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>
 llvm.func @main() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (nohost), capture_clause = (to), automap = false>} {
+        device_type = (nohost), capture_clause = (to)>} {
   llvm.call @main_callee() : () -> ()
   llvm.return
 }
@@ -208,18 +208,18 @@ llvm.func @main() {
 // If they aren't compatible, this is a user error.
 
 // CHECK: llvm.func {{.*}}@callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>
 llvm.func @callee() attributes {
     sym_visibility = "private",
     omp.declare_target = #omp.declaretarget<
-        device_type = (host), capture_clause = (to), automap = false>} {
+        device_type = (host), capture_clause = (to)>} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@main()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>
 llvm.func @main() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (nohost), capture_clause = (to), automap = false>} {
+        device_type = (nohost), capture_clause = (to)>} {
   llvm.call @callee() : () -> ()
   llvm.return
 }
@@ -230,29 +230,29 @@ llvm.func @main() attributes {
 // device_type(any) and it propagates to nested callees.
 
 // CHECK: llvm.func {{.*}}@callee_nested()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @callee_nested() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @callee() attributes {sym_visibility = "private"} {
   llvm.call @callee_nested() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@fn_host()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>
 llvm.func @fn_host() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (host), capture_clause = (to), automap = false>} {
+        device_type = (host), capture_clause = (to)>} {
   llvm.call @callee() : () -> ()
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@fn_nohost()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>
 llvm.func @fn_nohost() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (nohost), capture_clause = (to), automap = false>} {
+        device_type = (nohost), capture_clause = (to)>} {
   llvm.call @callee() : () -> ()
   llvm.return
 }
@@ -262,34 +262,34 @@ llvm.func @fn_nohost() attributes {
 // Always use implicit device_type(any) for external and public functions.
 
 // CHECK: llvm.func {{.*}}@external_host()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @external_host()
 // CHECK: llvm.func {{.*}}@external_nohost()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @external_nohost()
 // CHECK: llvm.func {{.*}}@external_both()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @external_both()
 // CHECK: llvm.func {{.*}}@public_host()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @public_host() {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@public_nohost()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @public_nohost() {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@public_both()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
 llvm.func @public_both() {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@fn_host()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>
 llvm.func @fn_host() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (host), capture_clause = (to), automap = false>} {
+        device_type = (host), capture_clause = (to)>} {
   llvm.call @external_host() : () -> ()
   llvm.call @external_both() : () -> ()
   llvm.call @public_host() : () -> ()
@@ -297,10 +297,10 @@ llvm.func @fn_host() attributes {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@fn_nohost()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>
 llvm.func @fn_nohost() attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (nohost), capture_clause = (to), automap = false>} {
+        device_type = (nohost), capture_clause = (to)>} {
   llvm.call @external_nohost() : () -> ()
   llvm.call @external_both() : () -> ()
   llvm.call @public_nohost() : () -> ()
@@ -340,19 +340,19 @@ cleanup {
 }
 
 // CHECK: llvm.func {{.*}}@red_callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to), implicit = true>
 llvm.func @red_callee() attributes {sym_visibility = "private"} {
   llvm.return
 }
 // CHECK: llvm.func {{.*}}@priv_callee()
-// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), automap = false>
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to), implicit = true>
 llvm.func @priv_callee() attributes {sym_visibility = "private"} {
   llvm.return
 }
 
 llvm.func @main(%arg0 : !llvm.ptr) attributes {
     omp.declare_target = #omp.declaretarget<
-        device_type = (host), capture_clause = (to), automap = false>} {
+        device_type = (host), capture_clause = (to)>} {
   %0 = omp.map.info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(tofrom) capture(ByRef) -> !llvm.ptr
   omp.target kernel_type(generic) in_reduction(@red %arg0 : !llvm.ptr)
              map_entries(%0 -> %arg1 : !llvm.ptr)
@@ -361,3 +361,25 @@ llvm.func @main(%arg0 : !llvm.ptr) attributes {
   }
   llvm.return
 }
+
+// -----
+
+// Implicit declare_target information should be updatable by another run of the
+// pass.
+
+// CHECK: llvm.func {{.*}}@callee()
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to), implicit = true>
+llvm.func @callee() attributes {
+    sym_visibility = "private",
+    omp.declare_target = #omp.declaretarget<
+        device_type = (host), capture_clause = (to), implicit = true>} {
+  llvm.return
+}
+// CHECK: llvm.func {{.*}}@main()
+// CHECK-SAME: omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>
+llvm.func @main() attributes {
+    omp.declare_target = #omp.declaretarget<
+        device_type = (nohost), capture_clause = (to)>} {
+  llvm.call @callee() : () -> ()
+  llvm.return
+}



More information about the llvm-branch-commits mailing list