Skip to content

Conversation

@TIFitis
Copy link
Member

@TIFitis TIFitis commented Aug 11, 2025

Add a new AutomapToTargetData pass. This gathers the declare target enter variables which have the AUTOMAP modifier. And adds omp.declare_target_enter/exit mapping directives for fir.alloca and fir.free oeprations on the AUTOMAP enabled variables.

Automap Ref: OpenMP 6.0 section 7.9.7.

Add a new AutomapToTargetData pass. This gathers the declare target enter variables which have the AUTOMAP modifier.
And adds omp.declare_target_enter/exit mapping directives for fir.alloca and fir.free oeprations on the AUTOMAP enabled variables.

Automap Ref: OpenMP 6.0 section 7.9.7.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp offload labels Aug 11, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 11, 2025

@llvm/pr-subscribers-offload
@llvm/pr-subscribers-flang-fir-hlfir

@llvm/pr-subscribers-flang-openmp

Author: Akash Banerjee (TIFitis)

Changes

Add a new AutomapToTargetData pass. This gathers the declare target enter variables which have the AUTOMAP modifier. And adds omp.declare_target_enter/exit mapping directives for fir.alloca and fir.free oeprations on the AUTOMAP enabled variables.

Automap Ref: OpenMP 6.0 section 7.9.7.


Full diff: https://github.com/llvm/llvm-project/pull/153048.diff

8 Files Affected:

  • (modified) flang/include/flang/Optimizer/OpenMP/Passes.td (+11)
  • (modified) flang/include/flang/Support/OpenMP-utils.h (+34)
  • (added) flang/lib/Optimizer/OpenMP/AutomapToTargetData.cpp (+130)
  • (modified) flang/lib/Optimizer/OpenMP/CMakeLists.txt (+1)
  • (modified) flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp (+2-33)
  • (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+6-6)
  • (added) flang/test/Transforms/omp-automap-to-target-data.fir (+58)
  • (added) offload/test/offloading/fortran/declare-target-automap.f90 (+36)
diff --git a/flang/include/flang/Optimizer/OpenMP/Passes.td b/flang/include/flang/Optimizer/OpenMP/Passes.td
index 704faf0ccd856..0bff58f0f6394 100644
--- a/flang/include/flang/Optimizer/OpenMP/Passes.td
+++ b/flang/include/flang/Optimizer/OpenMP/Passes.td
@@ -112,4 +112,15 @@ def GenericLoopConversionPass
   ];
 }
 
+def AutomapToTargetDataPass
+    : Pass<"omp-automap-to-target-data", "::mlir::ModuleOp"> {
+  let summary = "Insert OpenMP target data operations for AUTOMAP variables";
+  let description = [{
+    Inserts `omp.target_enter_data` and `omp.target_exit_data` operations to
+    map variables marked with the `AUTOMAP` modifier when their allocation
+    or deallocation is detected in the FIR.
+  }];
+  let dependentDialects = ["mlir::omp::OpenMPDialect"];
+}
+
 #endif //FORTRAN_OPTIMIZER_OPENMP_PASSES
diff --git a/flang/include/flang/Support/OpenMP-utils.h b/flang/include/flang/Support/OpenMP-utils.h
index 6d9db2b682c50..dc938db88e17d 100644
--- a/flang/include/flang/Support/OpenMP-utils.h
+++ b/flang/include/flang/Support/OpenMP-utils.h
@@ -9,8 +9,13 @@
 #ifndef FORTRAN_SUPPORT_OPENMP_UTILS_H_
 #define FORTRAN_SUPPORT_OPENMP_UTILS_H_
 
+#include "flang/Optimizer/Builder/DirectivesCommon.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Semantics/symbol.h"
 
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/Value.h"
 
@@ -72,6 +77,35 @@ struct EntryBlockArgs {
 /// \param [in]  region - Empty region in which to create the entry block.
 mlir::Block *genEntryBlock(
     mlir::OpBuilder &builder, const EntryBlockArgs &args, mlir::Region &region);
+
+// Returns true if the variable has a dynamic size and therefore requires
+// bounds operations to describe its extents.
+inline bool needsBoundsOps(mlir::Value var) {
+  assert(mlir::isa<mlir::omp::PointerLikeType>(var.getType()) &&
+      "only pointer like types expected");
+  mlir::Type t = fir::unwrapRefType(var.getType());
+  if (mlir::Type inner = fir::dyn_cast_ptrOrBoxEleTy(t))
+    return fir::hasDynamicSize(inner);
+  return fir::hasDynamicSize(t);
+}
+
+// Generate MapBoundsOp operations for the variable if required.
+inline void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value var,
+    llvm::SmallVectorImpl<mlir::Value> &boundsOps) {
+  mlir::Location loc = var.getLoc();
+  fir::factory::AddrAndBoundsInfo info =
+      fir::factory::getDataOperandBaseAddr(builder, var,
+          /*isOptional=*/false, loc);
+  fir::ExtendedValue exv =
+      hlfir::translateToExtendedValue(loc, builder, hlfir::Entity{info.addr},
+          /*contiguousHint=*/true)
+          .first;
+  llvm::SmallVector<mlir::Value> tmp =
+      fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
+          mlir::omp::MapBoundsType>(
+          builder, info, exv, /*dataExvIsAssumedSize=*/false, loc);
+  llvm::append_range(boundsOps, tmp);
+}
 } // namespace Fortran::common::openmp
 
 #endif // FORTRAN_SUPPORT_OPENMP_UTILS_H_
diff --git a/flang/lib/Optimizer/OpenMP/AutomapToTargetData.cpp b/flang/lib/Optimizer/OpenMP/AutomapToTargetData.cpp
new file mode 100644
index 0000000000000..8eeff66921db0
--- /dev/null
+++ b/flang/lib/Optimizer/OpenMP/AutomapToTargetData.cpp
@@ -0,0 +1,130 @@
+//===- AutomapToTargetData.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Support/OpenMP-utils.h"
+
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Operation.h"
+#include "mlir/Pass/Pass.h"
+
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
+
+namespace flangomp {
+#define GEN_PASS_DEF_AUTOMAPTOTARGETDATAPASS
+#include "flang/Optimizer/OpenMP/Passes.h.inc"
+} // namespace flangomp
+
+using namespace mlir;
+using namespace Fortran::common::openmp;
+
+namespace {
+class AutomapToTargetDataPass
+    : public flangomp::impl::AutomapToTargetDataPassBase<
+          AutomapToTargetDataPass> {
+  void findRelatedAllocmemFreemem(fir::AddrOfOp addressOfOp,
+                                  llvm::DenseSet<fir::StoreOp> &allocmems,
+                                  llvm::DenseSet<fir::LoadOp> &freemems) {
+    assert(addressOfOp->hasOneUse() && "op must have single use");
+
+    auto declaredRef =
+        cast<hlfir::DeclareOp>(*addressOfOp->getUsers().begin())->getResult(0);
+
+    for (Operation *refUser : declaredRef.getUsers()) {
+      if (auto storeOp = dyn_cast<fir::StoreOp>(refUser))
+        if (auto emboxOp = storeOp.getValue().getDefiningOp<fir::EmboxOp>())
+          if (auto allocmemOp =
+                  emboxOp.getOperand(0).getDefiningOp<fir::AllocMemOp>())
+            allocmems.insert(storeOp);
+
+      if (auto loadOp = dyn_cast<fir::LoadOp>(refUser))
+        for (Operation *loadUser : loadOp.getResult().getUsers())
+          if (auto boxAddrOp = dyn_cast<fir::BoxAddrOp>(loadUser))
+            for (Operation *boxAddrUser : boxAddrOp.getResult().getUsers())
+              if (auto freememOp = dyn_cast<fir::FreeMemOp>(boxAddrUser))
+                freemems.insert(loadOp);
+    }
+  }
+
+  void runOnOperation() override {
+    ModuleOp module = getOperation()->getParentOfType<ModuleOp>();
+    if (!module)
+      module = dyn_cast<ModuleOp>(getOperation());
+    if (!module)
+      return;
+
+    // Build FIR builder for helper utilities.
+    fir::KindMapping kindMap = fir::getKindMapping(module);
+    fir::FirOpBuilder builder{module, std::move(kindMap)};
+
+    // Collect global variables with AUTOMAP flag.
+    llvm::DenseSet<fir::GlobalOp> automapGlobals;
+    module.walk([&](fir::GlobalOp globalOp) {
+      if (auto iface =
+              dyn_cast<omp::DeclareTargetInterface>(globalOp.getOperation()))
+        if (iface.isDeclareTarget() && iface.getDeclareTargetAutomap() &&
+            iface.getDeclareTargetDeviceType() !=
+                omp::DeclareTargetDeviceType::host)
+          automapGlobals.insert(globalOp);
+    });
+
+    auto addMapInfo = [&](auto globalOp, auto memOp) {
+      builder.setInsertionPointAfter(memOp);
+      SmallVector<Value> bounds;
+      if (needsBoundsOps(memOp.getMemref()))
+        genBoundsOps(builder, memOp.getMemref(), bounds);
+
+      omp::TargetEnterExitUpdateDataOperands clauses;
+      mlir::omp::MapInfoOp mapInfo = mlir::omp::MapInfoOp::create(
+          builder, memOp.getLoc(), memOp.getMemref().getType(),
+          memOp.getMemref(),
+          TypeAttr::get(fir::unwrapRefType(memOp.getMemref().getType())),
+          builder.getIntegerAttr(
+              builder.getIntegerType(64, false),
+              static_cast<unsigned>(
+                  isa<fir::StoreOp>(memOp)
+                      ? llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO
+                      : llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE)),
+          builder.getAttr<omp::VariableCaptureKindAttr>(
+              omp::VariableCaptureKind::ByCopy),
+          /*var_ptr_ptr=*/mlir::Value{},
+          /*members=*/SmallVector<Value>{},
+          /*members_index=*/ArrayAttr{}, bounds,
+          /*mapperId=*/mlir::FlatSymbolRefAttr(), globalOp.getSymNameAttr(),
+          builder.getBoolAttr(false));
+      clauses.mapVars.push_back(mapInfo);
+      isa<fir::StoreOp>(memOp)
+          ? builder.create<omp::TargetEnterDataOp>(memOp.getLoc(), clauses)
+          : builder.create<omp::TargetExitDataOp>(memOp.getLoc(), clauses);
+    };
+
+    for (fir::GlobalOp globalOp : automapGlobals) {
+      if (auto uses = globalOp.getSymbolUses(module.getOperation())) {
+        llvm::DenseSet<fir::StoreOp> allocmemStores;
+        llvm::DenseSet<fir::LoadOp> freememLoads;
+        for (auto &x : *uses)
+          if (auto addrOp = dyn_cast<fir::AddrOfOp>(x.getUser()))
+            findRelatedAllocmemFreemem(addrOp, allocmemStores, freememLoads);
+
+        for (auto storeOp : allocmemStores)
+          addMapInfo(globalOp, storeOp);
+
+        for (auto loadOp : freememLoads)
+          addMapInfo(globalOp, loadOp);
+      }
+    }
+  }
+};
+} // namespace
diff --git a/flang/lib/Optimizer/OpenMP/CMakeLists.txt b/flang/lib/Optimizer/OpenMP/CMakeLists.txt
index e31543328a9f9..afe90985e54fd 100644
--- a/flang/lib/Optimizer/OpenMP/CMakeLists.txt
+++ b/flang/lib/Optimizer/OpenMP/CMakeLists.txt
@@ -1,6 +1,7 @@
 get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
 
 add_flang_library(FlangOpenMPTransforms
+  AutomapToTargetData.cpp
   DoConcurrentConversion.cpp
   FunctionFiltering.cpp
   GenericLoopConversion.cpp
diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
index 970f7d7ab063f..184f991fd91ed 100644
--- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
+++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp
@@ -29,6 +29,7 @@
 #include "flang/Optimizer/Dialect/Support/KindMapping.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "flang/Optimizer/OpenMP/Passes.h"
+#include "flang/Support/OpenMP-utils.h"
 
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
@@ -47,6 +48,7 @@ namespace flangomp {
 } // namespace flangomp
 
 using namespace mlir;
+using namespace Fortran::common::openmp;
 
 namespace {
 class MapsForPrivatizedSymbolsPass
@@ -193,38 +195,5 @@ class MapsForPrivatizedSymbolsPass
       }
     }
   }
-  // As the name suggests, this function examines var to determine if
-  // it has dynamic size. If true, this pass'll have to extract these
-  // bounds from descriptor of var and add the bounds to the resultant
-  // MapInfoOp.
-  bool needsBoundsOps(mlir::Value var) {
-    assert(mlir::isa<omp::PointerLikeType>(var.getType()) &&
-           "needsBoundsOps can deal only with pointer types");
-    mlir::Type t = fir::unwrapRefType(var.getType());
-    // t could be a box, so look inside the box
-    auto innerType = fir::dyn_cast_ptrOrBoxEleTy(t);
-    if (innerType)
-      return fir::hasDynamicSize(innerType);
-    return fir::hasDynamicSize(t);
-  }
-
-  void genBoundsOps(fir::FirOpBuilder &builder, mlir::Value var,
-                    llvm::SmallVector<mlir::Value> &boundsOps) {
-    mlir::Location loc = var.getLoc();
-    fir::factory::AddrAndBoundsInfo info =
-        fir::factory::getDataOperandBaseAddr(builder, var,
-                                             /*isOptional=*/false, loc);
-    fir::ExtendedValue extendedValue =
-        hlfir::translateToExtendedValue(loc, builder, hlfir::Entity{info.addr},
-                                        /*continguousHint=*/true)
-            .first;
-    llvm::SmallVector<mlir::Value> boundsOpsVec =
-        fir::factory::genImplicitBoundsOps<mlir::omp::MapBoundsOp,
-                                           mlir::omp::MapBoundsType>(
-            builder, info, extendedValue,
-            /*dataExvIsAssumedSize=*/false, loc);
-    for (auto bounds : boundsOpsVec)
-      boundsOps.push_back(bounds);
-  }
 };
 } // namespace
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index ca8e820608688..9f02d2df43e68 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -316,13 +316,13 @@ void createOpenMPFIRPassPipeline(mlir::PassManager &pm,
     pm.addPass(flangomp::createDoConcurrentConversionPass(
         opts.doConcurrentMappingKind == DoConcurrentMappingKind::DCMK_Device));
 
-  // The MapsForPrivatizedSymbols pass needs to run before
-  // MapInfoFinalizationPass because the former creates new
-  // MapInfoOp instances, typically for descriptors.
-  // MapInfoFinalizationPass adds MapInfoOp instances for the descriptors
-  // underlying data which is necessary to access the data on the offload
-  // target device.
+  // The MapsForPrivatizedSymbols and AutomapToTargetDataPass pass need to run
+  // before MapInfoFinalizationPass because they create new MapInfoOp
+  // instances, typically for descriptors. MapInfoFinalizationPass adds
+  // MapInfoOp instances for the descriptors underlying data which is necessary
+  // to access the data on the offload target device.
   pm.addPass(flangomp::createMapsForPrivatizedSymbolsPass());
+  pm.addPass(flangomp::createAutomapToTargetDataPass());
   pm.addPass(flangomp::createMapInfoFinalizationPass());
   pm.addPass(flangomp::createMarkDeclareTargetPass());
   pm.addPass(flangomp::createGenericLoopConversionPass());
diff --git a/flang/test/Transforms/omp-automap-to-target-data.fir b/flang/test/Transforms/omp-automap-to-target-data.fir
new file mode 100644
index 0000000000000..7a19705a248b4
--- /dev/null
+++ b/flang/test/Transforms/omp-automap-to-target-data.fir
@@ -0,0 +1,58 @@
+// RUN: fir-opt --omp-automap-to-target-data %s | FileCheck %s
+// Test OMP AutomapToTargetData pass.
+
+module {
+  fir.global
+      @_QMtestEarr{omp.declare_target = #omp.declaretarget<device_type = (any),
+                       capture_clause = (enter), automap = true>} target
+                       : !fir.box<!fir.heap<!fir.array<?xi32>>>
+
+  func.func @automap() {
+    %c0 = arith.constant 0 : index
+    %c10 = arith.constant 10 : i32
+    %addr = fir.address_of(@_QMtestEarr) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+    %decl:2 = hlfir.declare %addr {fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMtestEarr"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+    %idx = fir.convert %c10 : (i32) -> index
+    %cond = arith.cmpi sgt, %idx, %c0 : index
+    %n = arith.select %cond, %idx, %c0 : index
+    %mem = fir.allocmem !fir.array<?xi32>, %n {fir.must_be_heap = true}
+    %shape = fir.shape %n : (index) -> !fir.shape<1>
+    %box = fir.embox %mem(%shape) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+    fir.store %box to %decl#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+    %ld = fir.load %decl#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+    %base = fir.box_addr %ld : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+    fir.freemem %base : !fir.heap<!fir.array<?xi32>>
+    %undef = fir.zero_bits !fir.heap<!fir.array<?xi32>>
+    %sh0 = fir.shape %c0 : (index) -> !fir.shape<1>
+    %empty = fir.embox %undef(%sh0) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+    fir.store %empty to %decl#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+    return
+  }
+}
+
+// CHECK:         fir.global @[[AUTOMAP:.*]] {{{.*}} automap = true
+// CHECK-LABEL:   func.func @automap()
+// CHECK:           %[[AUTOMAP_ADDR:.*]] = fir.address_of(@[[AUTOMAP]])
+// CHECK:           %[[AUTOMAP_DECL:.*]]:2 = hlfir.declare %[[AUTOMAP_ADDR]]
+// CHECK:           %[[ALLOC_MEM:.*]] = fir.allocmem
+// CHECK-NEXT:      fir.shape
+// CHECK-NEXT:      %[[ARR_BOXED:.*]] = fir.embox %[[ALLOC_MEM]]
+// CHECK-NEXT:      fir.store %[[ARR_BOXED]]
+// CHECK-NEXT:      %[[ARR_BOXED_LOADED:.*]] = fir.load %[[AUTOMAP_DECL]]#0
+// CHECK-NEXT:      %[[ARR_HEAP_PTR:.*]] = fir.box_addr %[[ARR_BOXED_LOADED]]
+// CHECK-NEXT:      %[[DIM0:.*]] = arith.constant 0 : index
+// CHECK-NEXT:      %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARR_BOXED_LOADED]], %[[DIM0]]
+// CHECK-NEXT:      %[[ONE:.*]] = arith.constant 1 : index
+// CHECK-NEXT:      %[[ZERO:.*]] = arith.constant 0 : index
+// CHECK-NEXT:      %[[BOX_DIMS2:.*]]:3 = fir.box_dims %[[ARR_BOXED_LOADED]], %[[ZERO]]
+// CHECK-NEXT:      %[[LOWER_BOUND:.*]] = arith.constant 0 : index
+// CHECK-NEXT:      %[[UPPER_BOUND:.*]] = arith.subi %[[BOX_DIMS2]]#1, %[[ONE]] : index
+// CHECK-NEXT:      omp.map.bounds lower_bound(%[[LOWER_BOUND]] : index) upper_bound(%[[UPPER_BOUND]] : index) extent(%[[BOX_DIMS2]]#1 : index) stride(%[[BOX_DIMS2]]#2 : index) start_idx(%[[BOX_DIMS]]#0 : index) {stride_in_bytes = true}
+// CHECK-NEXT:      arith.muli %[[BOX_DIMS2]]#2, %[[BOX_DIMS2]]#1 : index
+// CHECK-NEXT:      %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[AUTOMAP_DECL]]#0 {{.*}} map_clauses(to) capture(ByCopy)
+// CHECK-NEXT:      omp.target_enter_data map_entries(%[[MAP_INFO]]
+// CHECK:           %[[LOAD:.*]] = fir.load %[[AUTOMAP_DECL]]#0
+// CHECK:           %[[EXIT_MAP:.*]] = omp.map.info var_ptr(%[[AUTOMAP_DECL]]#0 {{.*}} map_clauses(delete) capture(ByCopy)
+// CHECK-NEXT:      omp.target_exit_data map_entries(%[[EXIT_MAP]]
+// CHECK-NEXT:      %[[BOXADDR:.*]] = fir.box_addr %[[LOAD]]
+// CHECK-NEXT:      fir.freemem %[[BOXADDR]]
diff --git a/offload/test/offloading/fortran/declare-target-automap.f90 b/offload/test/offloading/fortran/declare-target-automap.f90
new file mode 100644
index 0000000000000..50e8c124c25fc
--- /dev/null
+++ b/offload/test/offloading/fortran/declare-target-automap.f90
@@ -0,0 +1,36 @@
+!Offloading test for AUTOMAP modifier in declare target enter
+! REQUIRES: flang, amdgpu
+
+program automap_program
+   use iso_c_binding, only: c_loc
+   use omp_lib, only: omp_get_default_device, omp_target_is_present
+   integer, parameter :: N = 10
+   integer :: i
+   integer, allocatable, target :: automap_array(:)
+   !$omp declare target enter(automap:automap_array)
+
+   ! false since the storage is not present even though the descriptor is present
+   write (*, *) omp_target_is_present(c_loc(automap_array), omp_get_default_device())
+   ! CHECK: 0
+
+   allocate (automap_array(N))
+   ! true since the storage should be allocated and reference count incremented by the allocate
+   write (*, *) omp_target_is_present(c_loc(automap_array), omp_get_default_device())
+   ! CHECK: 1
+
+   ! since storage is present this should not be a runtime error
+   !$omp target teams loop
+   do i = 1, N
+      automap_array(i) = i
+   end do
+
+   !$omp target update from(automap_array)
+   write (*, *) automap_array
+   ! CHECK: 1 2 3 4 5 6 7 8 9 10
+
+   deallocate (automap_array)
+
+   ! automap_array should have it's storage unmapped on device here
+   write (*, *) omp_target_is_present(c_loc(automap_array), omp_get_default_device())
+   ! CHECK: 0
+end program

@TIFitis
Copy link
Member Author

TIFitis commented Aug 11, 2025

@skatrak @bhandarkar-pranav Adding the BoundsOp helper functions to flang/lib/Support/OpenMP-utils.cpp caused build failures. I tried adding FIRBuilder as adependancy to the Cmake but this resulted in a cyclic dependency.

I've tried to go around this issue by moving the function definitios to flang/include/flang/Support/OpenMP-utils.h and inlining them.

Let me know if you're fine with this alteration or have a better suggestion.

@skatrak
Copy link
Member

skatrak commented Aug 12, 2025

I see the problem... The Support library, which is where OpenMP-utils is located, is linked by the Optimizer library and these new functions need access to it. The problem I see with making these definitions inline in the header is that it introduces an implicit requirement for whoever includes it to also link another unrelated library.

How about adding these in a new header/source pair in flang/include/flang/Optimizer/OpenMP/Support + flang/lib/Optimizer/OpenMP/Support? I think that should make it accessible to the right places.

@TIFitis
Copy link
Member Author

TIFitis commented Aug 12, 2025

I see the problem... The Support library, which is where OpenMP-utils is located, is linked by the Optimizer library and these new functions need access to it. The problem I see with making these definitions inline in the header is that it introduces an implicit requirement for whoever includes it to also link another unrelated library.

How about adding these in a new header/source pair in flang/include/flang/Optimizer/OpenMP/Support + flang/lib/Optimizer/OpenMP/Support? I think that should make it accessible to the right places.

At the moment, it's only this pass and MapsForPrivatizedSymbols which are using these methods, and neither don't need any additional linker related changes. If the user list for these grow in the future, perhaps that would be a better time to revisit a better location for these?

Copy link
Member

@skatrak skatrak left a comment

Choose a reason for hiding this comment

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

I was looking into it and I can't find a good place to put code dependent on FIRBuilder somewhere shared between FlangOpenMPTransforms and FortranLower without causing a circular dependency. I guess we can define it there inline for now, but we should think about a long term solution, because sooner or later we're likely going to find ourselves needing to share more logic between lowering and passes.

@TIFitis TIFitis merged commit 4e6d510 into llvm:main Aug 12, 2025
14 checks passed
@TIFitis TIFitis deleted the automap_pass branch August 12, 2025 14:18
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 12, 2025

LLVM Buildbot has detected a new failure on builder flang-aarch64-sharedlibs running on linaro-flang-aarch64-sharedlibs while building flang,offload at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/80/builds/15344

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
1290.979 [127/35/7640] Linking CXX executable bin/clang-check
1291.579 [118/43/7641] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/canonicalize-omp.cpp.o
1291.985 [118/42/7642] Linking CXX shared library lib/libclangInterpreter.so.22.0git
1292.048 [118/41/7643] Linking CXX executable bin/clang-22
1294.738 [118/40/7644] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-return.cpp.o
1294.839 [106/51/7645] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-nullify.cpp.o
1294.896 [105/51/7646] Creating library symlink lib/libclangInterpreter.so
1294.896 [105/50/7647] Creating executable symlink bin/clang
1294.920 [105/49/7648] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-dsa.cpp.o
1295.213 [105/48/7649] Linking CXX shared library lib/libFortranSupport.so.22.0git
FAILED: lib/libFortranSupport.so.22.0git 
: && /usr/local/bin/c++ -fPIC -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wno-deprecated-copy -Wno-string-conversion -Wno-ctad-maybe-unsupported -Wno-unused-command-line-argument -Wstring-conversion           -Wcovered-switch-default -Wno-nested-anon-types -Xclang -fno-pch-timestamp -O3 -DNDEBUG  -Wl,-z,defs -Wl,-z,nodelete   -Wl,-rpath-link,/home/tcwg-buildbot/worker/flang-aarch64-sharedlibs/build/./lib  -Wl,--gc-sections -shared -Wl,-soname,libFortranSupport.so.22.0git -o lib/libFortranSupport.so.22.0git tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/default-kinds.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Flags.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Fortran.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Fortran-features.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/idioms.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/LangOptions.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Timing.cpp.o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Version.cpp.o  -Wl,-rpath,"\$ORIGIN/../lib:/home/tcwg-buildbot/worker/flang-aarch64-sharedlibs/build/lib:"  lib/libMLIRIR.so.22.0git  lib/libMLIRSupport.so.22.0git  lib/libLLVMSupport.so.22.0git  -Wl,-rpath-link,/home/tcwg-buildbot/worker/flang-aarch64-sharedlibs/build/lib && :
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::CharBoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir12CharBoxValue4dumpEv[_ZNK3fir12CharBoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::CharBoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::PolymorphicValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir16PolymorphicValue4dumpEv[_ZNK3fir16PolymorphicValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::PolymorphicValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::ArrayBoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir13ArrayBoxValue4dumpEv[_ZNK3fir13ArrayBoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::ArrayBoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::CharArrayBoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir17CharArrayBoxValue4dumpEv[_ZNK3fir17CharArrayBoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::CharArrayBoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::ProcBoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir12ProcBoxValue4dumpEv[_ZNK3fir12ProcBoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::ProcBoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::BoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir8BoxValue4dumpEv[_ZNK3fir8BoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::BoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::MutableBoxValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir15MutableBoxValue4dumpEv[_ZNK3fir15MutableBoxValue4dumpEv]+0x20): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::MutableBoxValue const&)'
/usr/bin/ld: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o: in function `fir::ExtendedValue::dump() const':
OpenMP-utils.cpp:(.text._ZNK3fir13ExtendedValue4dumpEv[_ZNK3fir13ExtendedValue4dumpEv]+0x18): undefined reference to `fir::operator<<(llvm::raw_ostream&, fir::ExtendedValue const&)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
1299.973 [105/47/7650] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/openmp-modifiers.cpp.o
1300.909 [105/46/7651] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/canonicalize-directives.cpp.o
1305.593 [105/45/7652] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-stop.cpp.o
1307.512 [105/44/7653] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/program-tree.cpp.o
1312.723 [105/43/7654] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-select-type.cpp.o
1313.825 [105/42/7655] Building CXX object tools/flang/lib/Evaluate/CMakeFiles/FortranEvaluate.dir/tools.cpp.o
1315.583 [105/41/7656] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/compute-offsets.cpp.o
1316.196 [105/40/7657] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-omp-metadirective.cpp.o
1317.769 [105/39/7658] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/unparse.cpp.o
1321.455 [105/38/7659] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-acc-structure.cpp.o
1322.153 [105/37/7660] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-deallocate.cpp.o
1322.873 [105/36/7661] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/dump-expr.cpp.o
1323.965 [105/35/7662] Building CXX object tools/flang/lib/Frontend/CMakeFiles/flangFrontend.dir/CompilerInstance.cpp.o
1332.440 [105/34/7663] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-declarations.cpp.o
1339.220 [105/33/7664] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-select-rank.cpp.o
1353.357 [105/32/7665] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-data.cpp.o
1353.448 [105/31/7666] Building CXX object tools/flang/lib/Evaluate/CMakeFiles/FortranEvaluate.dir/fold-integer.cpp.o
1357.385 [105/30/7667] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/check-io.cpp.o
1360.023 [105/29/7668] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/definable.cpp.o
1372.550 [105/28/7669] Building CXX object tools/flang/lib/Semantics/CMakeFiles/FortranSemantics.dir/resolve-labels.cpp.o

TIFitis added a commit that referenced this pull request Aug 12, 2025
@TIFitis
Copy link
Member Author

TIFitis commented Aug 12, 2025

@skatrak It seems the linker issue is still there on some builds with the inlining change. I will work on a fix and update here.

@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 12, 2025

LLVM Buildbot has detected a new failure on builder ppc64-flang-aix running on ppc64-flang-aix-test while building flang,offload at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/201/builds/5874

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
4973.782 [3896/10/4399] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/LangOptions.cpp.o
4974.150 [3895/10/4400] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Fortran-features.cpp.o
4974.311 [3894/10/4401] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Timing.cpp.o
4974.448 [3893/10/4402] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/Version.cpp.o
4974.504 [3892/10/4403] Linking CXX static library lib/libLLVMFrontendOpenACC.a
4975.106 [3891/10/4404] Linking CXX static library lib/libclangSema.a
4975.289 [3890/10/4405] Linking CXX static library lib/libclangToolingCore.a
4983.437 [3889/10/4406] Building CXX object tools/flang/lib/Optimizer/Dialect/CUF/Attributes/CMakeFiles/CUFAttrs.dir/CUFAttr.cpp.o
4987.451 [3888/10/4407] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/ASTReaderDecl.cpp.o
4987.587 [3887/10/4408] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o
FAILED: tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o 
/home/llvm/llvm-external-buildbots/clang.19.1.2/bin/clang++ -DFLANG_INCLUDE_TESTS=1 -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LARGE_FILE_API -D_XOPEN_SOURCE=700 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/flang/lib/Support -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/lib/Support -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/flang/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/include -I/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/llvm/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/../mlir/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/mlir/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/build/tools/clang/include -isystem /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/llvm/../clang/include -mcmodel=large -fPIC -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Werror -Wno-deprecated-copy -Wno-string-conversion -Wno-ctad-maybe-unsupported -Wno-unused-command-line-argument -Wstring-conversion           -Wcovered-switch-default -Wno-nested-anon-types -Xclang -fno-pch-timestamp -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -pthread -MD -MT tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o -MF tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o.d -o tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o -c /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/lib/Support/OpenMP-utils.cpp
In file included from /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/lib/Support/OpenMP-utils.cpp:9:
In file included from /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include/flang/Support/OpenMP-utils.h:12:
In file included from /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include/flang/Optimizer/Builder/DirectivesCommon.h:25:
In file included from /home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include/flang/Optimizer/HLFIR/HLFIROps.h:17:
/home/llvm/llvm-external-buildbots/workers/ppc64-flang-aix-test/ppc64-flang-aix-build/llvm-project/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h:28:10: fatal error: 'flang/Optimizer/HLFIR/HLFIRDialect.h.inc' file not found
   28 | #include "flang/Optimizer/HLFIR/HLFIRDialect.h.inc"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
4988.294 [3887/9/4409] Building CXX object tools/flang/lib/Optimizer/Dialect/Support/CMakeFiles/FIRDialectSupport.dir/FIRContext.cpp.o
4989.377 [3887/8/4410] Building CXX object tools/flang/lib/Optimizer/Dialect/Support/CMakeFiles/FIRDialectSupport.dir/KindMapping.cpp.o
4991.566 [3887/7/4411] Building CXX object tools/mlir/lib/Target/LLVMIR/CMakeFiles/obj.MLIRTargetLLVMIRImport.dir/DataLayoutImporter.cpp.o
4994.017 [3887/6/4412] Building CXX object tools/mlir/lib/CMakeFiles/obj.MLIRRegisterAllExtensions.dir/RegisterAllExtensions.cpp.o
4995.797 [3887/5/4413] Building CXX object tools/flang/lib/Parser/CMakeFiles/FortranParser.dir/cmake_pch.hxx.pch
5007.653 [3887/4/4414] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/ASTWriter.cpp.o
5007.892 [3887/3/4415] Building CXX object tools/mlir/lib/Target/LLVMIR/CMakeFiles/obj.MLIRTargetLLVMIRImport.dir/DebugImporter.cpp.o
5019.024 [3887/2/4416] Building CXX object tools/clang/lib/Serialization/CMakeFiles/obj.clangSerialization.dir/ASTReader.cpp.o
5046.298 [3887/1/4417] Building CXX object tools/mlir/lib/CMakeFiles/obj.MLIRRegisterAllDialects.dir/RegisterAllDialects.cpp.o
ninja: build stopped: subcommand failed.

searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Aug 13, 2025
TIFitis added a commit that referenced this pull request Aug 15, 2025
…153048)

Add a new AutomapToTargetData pass. This gathers the declare target
enter variables which have the AUTOMAP modifier. And adds
omp.declare_target_enter/exit mapping directives for fir.alloca and
fir.free oeprations on the AUTOMAP enabled variables.

Automap Ref: OpenMP 6.0 section 7.9.7.
@mgorny
Copy link
Member

mgorny commented Aug 16, 2025

The added test seems to be broken:

UNRESOLVED: libomptarget :: x86_64-unknown-linux-gnu :: offloading/fortran/declare-target-automap.f90 (129 of 746)
******************** TEST 'libomptarget :: x86_64-unknown-linux-gnu :: offloading/fortran/declare-target-automap.f90' FAILED ********************
Test has no 'RUN:' line
********************
UNRESOLVED: libomptarget :: x86_64-unknown-linux-gnu-LTO :: offloading/fortran/declare-target-automap.f90 (502 of 746)
******************** TEST 'libomptarget :: x86_64-unknown-linux-gnu-LTO :: offloading/fortran/declare-target-automap.f90' FAILED ********************
Test has no 'RUN:' line
********************

@TIFitis
Copy link
Member Author

TIFitis commented Aug 18, 2025

The added test seems to be broken:

UNRESOLVED: libomptarget :: x86_64-unknown-linux-gnu :: offloading/fortran/declare-target-automap.f90 (129 of 746)
******************** TEST 'libomptarget :: x86_64-unknown-linux-gnu :: offloading/fortran/declare-target-automap.f90' FAILED ********************
Test has no 'RUN:' line
********************
UNRESOLVED: libomptarget :: x86_64-unknown-linux-gnu-LTO :: offloading/fortran/declare-target-automap.f90 (502 of 746)
******************** TEST 'libomptarget :: x86_64-unknown-linux-gnu-LTO :: offloading/fortran/declare-target-automap.f90' FAILED ********************
Test has no 'RUN:' line
********************

Sorry about that.

I've fixed it in 6aafe65.

@mgorny
Copy link
Member

mgorny commented Aug 18, 2025

Thanks. I'll test it when #153956 lands.

@mgorny
Copy link
Member

mgorny commented Aug 31, 2025

Oh, sorry, I forgot to post an update: it works now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang:openmp flang Flang issues not falling into any other category offload

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants