[flang-commits] [flang] [flang][acc] Implement MappableType interfaces for fir.box and fir.array (PR #122495)

via flang-commits flang-commits at lists.llvm.org
Fri Jan 10 08:59:42 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver

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

Author: Razvan Lupusoru (razvanlupusoru)

<details>
<summary>Changes</summary>

The newly introduced MappableType interface in `acc` dialect was primarily intended to allow variables with non-materialized storage to be used in acc data clauses (previously everything was required to be `pointer-like`). One motivator for this was `fir.box` since it is possible to be passed to functions without a wrapping `fir.ref` and also it can be generated directly via operations like `fir.embox` - and unlike other variable representations in FIR, the underlying storage for it does not get materialized until LLVM codegen.

The new interface is being attached to both `fir.box` and `fir.array`. Strictly speaking, attaching to the latter is primarily for consistency since the MappableType interface requires implementation of utilities to compute byte size - and it made sense that a
`fir.box<fir.array<10xi32>>` and `fir.array<10xi32>` would have a consistently computable size. This decision may be revisited as MappableType interface evolves.

The new interface attachments are made in a new library named `FIROpenACCSupport`. The reason for this is to avoid circular dependencies since the implementation of this library is reusing code from lowering of OpenACC. More specifically, the types are defined in `FIRDialect` and `FortranLower` depends on it. Thus we cannot attach these interfaces in `FIRDialect`.

---

Patch is 24.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/122495.diff


17 Files Affected:

- (added) flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h (+43) 
- (added) flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h (+22) 
- (modified) flang/include/flang/Optimizer/Support/InitFIR.h (+2) 
- (modified) flang/lib/Frontend/CMakeLists.txt (+1) 
- (modified) flang/lib/Optimizer/CMakeLists.txt (+1) 
- (modified) flang/lib/Optimizer/Dialect/CMakeLists.txt (+1-1) 
- (added) flang/lib/Optimizer/OpenACC/CMakeLists.txt (+22) 
- (added) flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp (+221) 
- (added) flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp (+28) 
- (added) flang/test/Fir/OpenACC/openacc-mappable.fir (+25) 
- (modified) flang/test/lib/CMakeLists.txt (+1) 
- (added) flang/test/lib/OpenACC/CMakeLists.txt (+21) 
- (added) flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp (+85) 
- (modified) flang/tools/fir-lsp-server/CMakeLists.txt (+1) 
- (modified) flang/tools/fir-opt/CMakeLists.txt (+2) 
- (modified) flang/tools/fir-opt/fir-opt.cpp (+2) 
- (modified) flang/tools/tco/CMakeLists.txt (+1) 


``````````diff
diff --git a/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h b/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h
new file mode 100644
index 00000000000000..c1bea32a22361d
--- /dev/null
+++ b/flang/include/flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h
@@ -0,0 +1,43 @@
+//===- FIROpenACCTypeInterfaces.h -------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains external dialect interfaces for FIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
+#define FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
+
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+
+namespace fir::acc {
+
+template <typename T>
+struct OpenACCMappableModel
+    : public mlir::acc::MappableType::ExternalModel<OpenACCMappableModel<T>,
+                                                    T> {
+  mlir::TypedValue<mlir::acc::PointerLikeType> getVarPtr(::mlir::Type type,
+                                                         mlir::Value var) const;
+
+  std::optional<llvm::TypeSize>
+  getSizeInBytes(mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+                 const mlir::DataLayout &dataLayout) const;
+
+  std::optional<int64_t>
+  getOffsetInBytes(mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+                   const mlir::DataLayout &dataLayout) const;
+
+  llvm::SmallVector<mlir::Value>
+  generateAccBounds(mlir::Type type, mlir::Value var,
+                    mlir::OpBuilder &builder) const;
+};
+
+} // namespace fir::acc
+
+#endif // FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
diff --git a/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h b/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h
new file mode 100644
index 00000000000000..efaddd72ebbf2b
--- /dev/null
+++ b/flang/include/flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h
@@ -0,0 +1,22 @@
+//===- RegisterOpenACCExtensions.h - OpenACC Extension Registration --===--===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
+#define FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
+
+namespace mlir {
+class DialectRegistry;
+} // namespace mlir
+
+namespace fir::acc {
+
+void registerOpenACCExtensions(mlir::DialectRegistry &registry);
+
+} // namespace fir::acc
+
+#endif // FLANG_OPTIMIZER_OPENACC_REGISTEROPENACCEXTENSIONS_H_
diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 1c61c367199923..94995ac6136edd 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -17,6 +17,7 @@
 #include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
 #include "flang/Optimizer/Dialect/FIRDialect.h"
 #include "flang/Optimizer/HLFIR/HLFIRDialect.h"
+#include "flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h"
 #include "mlir/Conversion/Passes.h"
 #include "mlir/Dialect/Affine/Passes.h"
 #include "mlir/Dialect/Complex/IR/Complex.h"
@@ -63,6 +64,7 @@ inline void addFIRExtensions(mlir::DialectRegistry &registry,
     addFIRInlinerExtension(registry);
   addFIRToLLVMIRExtension(registry);
   cuf::registerCUFDialectTranslation(registry);
+  fir::acc::registerOpenACCExtensions(registry);
 }
 
 inline void loadNonCodegenDialects(mlir::MLIRContext &context) {
diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt
index e954800c3b88b0..f00566d7791575 100644
--- a/flang/lib/Frontend/CMakeLists.txt
+++ b/flang/lib/Frontend/CMakeLists.txt
@@ -38,6 +38,7 @@ add_flang_library(flangFrontend
   HLFIRDialect
   HLFIRTransforms
   flangPasses
+  FIROpenACCSupport
   FlangOpenMPTransforms
   MLIRTransforms
   MLIRBuiltinToLLVMIRTranslation
diff --git a/flang/lib/Optimizer/CMakeLists.txt b/flang/lib/Optimizer/CMakeLists.txt
index 5354d7181e6516..72aba51b858708 100644
--- a/flang/lib/Optimizer/CMakeLists.txt
+++ b/flang/lib/Optimizer/CMakeLists.txt
@@ -3,6 +3,7 @@ add_subdirectory(Builder)
 add_subdirectory(CodeGen)
 add_subdirectory(Dialect)
 add_subdirectory(HLFIR)
+add_subdirectory(OpenACC)
 add_subdirectory(OpenMP)
 add_subdirectory(Passes)
 add_subdirectory(Support)
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index a8235f841b879d..08caa15700d4ca 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -6,8 +6,8 @@ add_flang_library(FIRDialect
   FIRDialect.cpp
   FIROps.cpp
   FIRType.cpp
-  FortranVariableInterface.cpp
   FirAliasTagOpInterface.cpp
+  FortranVariableInterface.cpp
   Inliner.cpp
 
   DEPENDS
diff --git a/flang/lib/Optimizer/OpenACC/CMakeLists.txt b/flang/lib/Optimizer/OpenACC/CMakeLists.txt
new file mode 100644
index 00000000000000..ed673121353c16
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/CMakeLists.txt
@@ -0,0 +1,22 @@
+get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
+
+add_flang_library(FIROpenACCSupport
+  FIROpenACCTypeInterfaces.cpp
+  RegisterOpenACCExtensions.cpp
+
+  DEPENDS
+  FIRBuilder
+  FIRDialect
+  FIRDialectSupport
+  FIRSupport
+  HLFIRDialect
+  MLIROpenACCDialect
+
+  LINK_LIBS
+  FIRBuilder
+  FIRDialect
+  FIRDialectSupport
+  FIRSupport
+  HLFIRDialect
+  MLIROpenACCDialect
+)
diff --git a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
new file mode 100644
index 00000000000000..ebcc54add0ed12
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
@@ -0,0 +1,221 @@
+//===-- FIROpenACCTypeInterfaces.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of external dialect interfaces for FIR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h"
+#include "flang/Lower/DirectivesCommon.h"
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Support/LLVM.h"
+
+namespace fir::acc {
+
+static mlir::TypedValue<mlir::acc::PointerLikeType>
+getPtrFromVar(mlir::Value var) {
+  if (auto ptr =
+          mlir::dyn_cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(var))
+    return ptr;
+
+  if (auto load = mlir::dyn_cast_if_present<fir::LoadOp>(var.getDefiningOp())) {
+    // All FIR reference types implement the PointerLikeType interface.
+    return mlir::cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(
+        load.getMemref());
+  }
+
+  return {};
+}
+
+template <>
+mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::SequenceType>::getVarPtr(mlir::Type type,
+                                                   mlir::Value var) const {
+  return getPtrFromVar(var);
+}
+
+template <>
+mlir::TypedValue<mlir::acc::PointerLikeType>
+OpenACCMappableModel<fir::BaseBoxType>::getVarPtr(mlir::Type type,
+                                                  mlir::Value var) const {
+  return getPtrFromVar(var);
+}
+
+template <>
+std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::SequenceType>::getSizeInBytes(
+    mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+    const mlir::DataLayout &dataLayout) const {
+  // TODO: Bounds operation affect the total size - add support to take them
+  // into account.
+  if (!accBounds.empty())
+    return {};
+
+  // Dynamic extents or unknown ranks generally do not have compile-time
+  // computable dimensions.
+  auto seqType = mlir::cast<fir::SequenceType>(type);
+  if (seqType.hasDynamicExtents() || seqType.hasUnknownShape())
+    return {};
+
+  // Without a defining op, cannot look up appropriate kindMapping for the
+  // current context.
+  if (!var.getDefiningOp())
+    return {};
+  auto kindMap = fir::getKindMapping(var.getDefiningOp());
+  auto sizeAndAlignment =
+      fir::getTypeSizeAndAlignment(var.getLoc(), type, dataLayout, kindMap);
+  if (!sizeAndAlignment.has_value())
+    return {};
+
+  return {llvm::TypeSize::getFixed(sizeAndAlignment->first)};
+}
+
+template <>
+std::optional<llvm::TypeSize>
+OpenACCMappableModel<fir::BaseBoxType>::getSizeInBytes(
+    mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+    const mlir::DataLayout &dataLayout) const {
+  // If we have a box value instead of box reference, the intent is to
+  // get the size of the data not the box itself.
+  if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+    if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+            fir::unwrapRefType(boxTy.getEleTy()))) {
+      return mappableTy.getSizeInBytes(var, accBounds, dataLayout);
+    }
+  }
+  // Size for boxes is not computable until it gets materialized.
+  return {};
+}
+
+template <>
+std::optional<int64_t>
+OpenACCMappableModel<fir::SequenceType>::getOffsetInBytes(
+    mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+    const mlir::DataLayout &dataLayout) const {
+  // TODO: Bounds operation affect the offset- add support to take them
+  // into account.
+  if (!accBounds.empty())
+    return {};
+
+  // Dynamic extents (aka descriptor-based arrays) - may have a offset.
+  // For example, a negative stride may mean a negative offset to compute the
+  // start of array.
+  auto seqType = mlir::cast<fir::SequenceType>(type);
+  if (seqType.hasDynamicExtents() || seqType.hasUnknownShape())
+    return {};
+
+  // We have non-dynamic extents - but if for some reason the size is not
+  // computable - assume offset is not either. Otherwise, it is an offset of
+  // zero.
+  if (getSizeInBytes(type, var, accBounds, dataLayout).has_value()) {
+    return {0};
+  }
+  return {};
+}
+
+template <>
+std::optional<int64_t> OpenACCMappableModel<fir::BaseBoxType>::getOffsetInBytes(
+    mlir::Type type, mlir::Value var, mlir::ValueRange accBounds,
+    const mlir::DataLayout &dataLayout) const {
+  // If we have a box value instead of box reference, the intent is to
+  // get the offset of the data not the offset of the box itself.
+  if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+    if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+            fir::unwrapRefType(boxTy.getEleTy()))) {
+      return mappableTy.getOffsetInBytes(var, accBounds, dataLayout);
+    }
+  }
+  // Until boxes get materialized, the offset is not evident because it is
+  // relative to the pointer being held.
+  return {};
+}
+
+template <>
+llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::SequenceType>::generateAccBounds(
+    mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const {
+  assert((mlir::isa<mlir::acc::PointerLikeType>(var.getType()) ||
+          mlir::isa<mlir::acc::MappableType>(var.getType())) &&
+         "must be pointer-like or mappable");
+
+  fir::FirOpBuilder firBuilder(builder, var.getDefiningOp());
+  auto seqType = mlir::cast<fir::SequenceType>(type);
+  mlir::Location loc = var.getLoc();
+
+  mlir::Value varPtr =
+      mlir::isa<mlir::acc::PointerLikeType>(var.getType())
+          ? var
+          : mlir::cast<mlir::acc::MappableType>(var.getType()).getVarPtr(var);
+
+  if (seqType.hasDynamicExtents() || seqType.hasUnknownShape()) {
+    if (auto boxAddr =
+            mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
+      mlir::Value box = boxAddr.getVal();
+      auto res =
+          hlfir::translateToExtendedValue(loc, firBuilder, hlfir::Entity(box));
+      fir::ExtendedValue exv = res.first;
+      mlir::Value boxRef = box;
+      if (auto boxPtr = getPtrFromVar(box)) {
+        boxRef = boxPtr;
+      }
+      // TODO: Handle Fortran optional.
+      const mlir::Value isPresent;
+      Fortran::lower::AddrAndBoundsInfo info(box, boxRef, isPresent,
+                                             box.getType());
+      return Fortran::lower::genBoundsOpsFromBox<mlir::acc::DataBoundsOp,
+                                                 mlir::acc::DataBoundsType>(
+          firBuilder, loc, exv, info);
+    }
+    assert(false && "array with unknown dimension expected to have descriptor");
+    return {};
+  }
+
+  // TODO: Detect assumed-size case.
+  const bool isAssumedSize = false;
+  auto valToCheck = varPtr;
+  if (auto boxAddr =
+          mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
+    valToCheck = boxAddr.getVal();
+  }
+  auto res = hlfir::translateToExtendedValue(loc, firBuilder,
+                                             hlfir::Entity(valToCheck));
+  fir::ExtendedValue exv = res.first;
+  return Fortran::lower::genBaseBoundsOps<mlir::acc::DataBoundsOp,
+                                          mlir::acc::DataBoundsType>(
+      firBuilder, loc, exv,
+      /*isAssumedSize=*/isAssumedSize);
+}
+
+template <>
+llvm::SmallVector<mlir::Value>
+OpenACCMappableModel<fir::BaseBoxType>::generateAccBounds(
+    mlir::Type type, mlir::Value var, mlir::OpBuilder &builder) const {
+  // If we have a box value instead of box reference, the intent is to
+  // get the bounds of the data not the bounds of the box itself.
+  if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType())) {
+    if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(
+            fir::unwrapRefType(boxTy.getEleTy()))) {
+      mlir::Value data = builder.create<fir::BoxAddrOp>(var.getLoc(), var);
+      return mappableTy.generateAccBounds(data, builder);
+    }
+  }
+  // Box references are not arrays - thus generating acc.bounds does not make
+  // sense.
+  return {};
+}
+
+} // namespace fir::acc
diff --git a/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp
new file mode 100644
index 00000000000000..34ea122f6b997d
--- /dev/null
+++ b/flang/lib/Optimizer/OpenACC/RegisterOpenACCExtensions.cpp
@@ -0,0 +1,28 @@
+//===-- RegisterOpenACCExtensions.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Registration for OpenACC extensions as applied to FIR dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/OpenACC/RegisterOpenACCExtensions.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/OpenACC/FIROpenACCTypeInterfaces.h"
+
+namespace fir::acc {
+void registerOpenACCExtensions(mlir::DialectRegistry &registry) {
+  registry.addExtension(+[](mlir::MLIRContext *ctx,
+                            fir::FIROpsDialect *dialect) {
+    fir::SequenceType::attachInterface<OpenACCMappableModel<fir::SequenceType>>(
+        *ctx);
+    fir::BoxType::attachInterface<OpenACCMappableModel<fir::BaseBoxType>>(*ctx);
+  });
+}
+
+} // namespace fir::acc
diff --git a/flang/test/Fir/OpenACC/openacc-mappable.fir b/flang/test/Fir/OpenACC/openacc-mappable.fir
new file mode 100644
index 00000000000000..438cb29b991c7d
--- /dev/null
+++ b/flang/test/Fir/OpenACC/openacc-mappable.fir
@@ -0,0 +1,25 @@
+// Use --mlir-disable-threading so that the diagnostic printing is serialized.
+// RUN: fir-opt %s -pass-pipeline='builtin.module(test-fir-openacc-interfaces)' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.endianness" = "little", "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"} {
+  func.func @_QPsub() {
+    %c2 = arith.constant 2 : index
+    %c10 = arith.constant 10 : index
+    %0 = fir.alloca !fir.array<10xf32> {bindc_name = "arr", uniq_name = "_QFsubEarr"}
+    %1 = fir.shape_shift %c2, %c10 : (index, index) -> !fir.shapeshift<1>
+    %2 = fir.declare %0(%1) {uniq_name = "_QFsubEarr"} : (!fir.ref<!fir.array<10xf32>>, !fir.shapeshift<1>) -> !fir.ref<!fir.array<10xf32>>
+    %3 = fir.embox %2(%1) : (!fir.ref<!fir.array<10xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<10xf32>>
+    %4 = fir.box_addr %3 : (!fir.box<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>>
+    %5 = acc.copyin var(%3 : !fir.box<!fir.array<10xf32>>) -> !fir.box<!fir.array<10xf32>> {name = "arr", structured = false}
+    %6 = acc.copyin varPtr(%4 : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr", structured = false}
+    acc.enter_data dataOperands(%5, %6 : !fir.box<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+    return
+  }
+}
+
+// CHECK: Visiting: %{{.*}} = acc.copyin var(%{{.*}} : !fir.box<!fir.array<10xf32>>) -> !fir.box<!fir.array<10xf32>> {name = "arr", structured = false}
+// CHECK: Mappable: !fir.box<!fir.array<10xf32>>
+// CHECK: Size: 40
+// CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr", structured = false}
+// CHECK: Mappable: !fir.array<10xf32>
+// CHECK: Size: 40
diff --git a/flang/test/lib/CMakeLists.txt b/flang/test/lib/CMakeLists.txt
index fc6ef10fab1f5a..96f4c9513b11a5 100644
--- a/flang/test/lib/CMakeLists.txt
+++ b/flang/test/lib/CMakeLists.txt
@@ -1 +1,2 @@
 add_subdirectory(Analysis)
+add_subdirectory(OpenACC)
diff --git a/flang/test/lib/OpenACC/CMakeLists.txt b/flang/test/lib/OpenACC/CMakeLists.txt
new file mode 100644
index 00000000000000..54a81373d253fa
--- /dev/null
+++ b/flang/test/lib/OpenACC/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_flang_library(FIRTestOpenACCInterfaces
+  TestOpenACCInterfaces.cpp
+
+  DEPENDS
+  FIRDialect
+  FIRBuilder
+  FIROpenACCSupport
+  FIRSupport
+  FIRTransforms
+  MLIROpenACCDialect
+
+  LINK_LIBS
+  FIRDialect
+  FIRBuilder
+  FIROpenACCSupport
+  FIRSupport
+  MLIRIR
+  MLIROpenACCDialect
+  MLIRSupport
+  MLIRFuncDialect
+)
diff --git a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
new file mode 100644
index 00000000000000..a01396748f4c2c
--- /dev/null
+++ b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
@@ -0,0 +1,85 @@
+//===- TestOpenACCInterfaces.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
+//
+//===--------------------------------...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/122495


More information about the flang-commits mailing list