[flang-commits] [flang] 95b0b86 - [Flang][OpenMP][MLIR] Add declare target attribute set and interface for the OpenMP dialect
Andrew Gozillon via flang-commits
flang-commits at lists.llvm.org
Mon May 22 03:41:44 PDT 2023
Author: Andrew Gozillon
Date: 2023-05-22T05:41:06-05:00
New Revision: 95b0b867b0d19919133693b8e75b170fd25a9cec
URL: https://github.com/llvm/llvm-project/commit/95b0b867b0d19919133693b8e75b170fd25a9cec
DIFF: https://github.com/llvm/llvm-project/commit/95b0b867b0d19919133693b8e75b170fd25a9cec.diff
LOG: [Flang][OpenMP][MLIR] Add declare target attribute set and interface for the OpenMP dialect
This attribute represents the OpenMP declare target directive, it marks a function
or global as declare target by being present but also contains information on
the device_type and capture clause (link or to). It being an attribute allows it to
mark existing constructs and be converted trivially on lowering from the OpenMP
dialect to MLIR using amendOperation.
An interface has been made for the declare target attribute, with several helper
methods for managing the attribute, this interface can be applied to MLIR
operations that are allowed to be marked as declare target (as an example, it
is by default applied to func.func, LLVMFunc, fir.GlobalOps and LLVMGlobalOps).
Reviewers: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D150328
Added:
flang/test/Fir/omp-declare-target-data.fir
Modified:
flang/include/flang/Optimizer/Dialect/FIRDialect.h
flang/lib/Optimizer/Dialect/FIRDialect.cpp
flang/lib/Optimizer/Dialect/FIROps.cpp
mlir/include/mlir/Dialect/OpenMP/OpenMPInterfaces.h
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
mlir/test/Dialect/OpenMP/attr.mlir
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Dialect/FIRDialect.h b/flang/include/flang/Optimizer/Dialect/FIRDialect.h
index baa447c1aa31b..e8bf9f0cf503b 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRDialect.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRDialect.h
@@ -47,6 +47,9 @@ class FIROpsDialect final : public mlir::Dialect {
void registerAttributes();
// Register the Types of this dialect.
void registerTypes();
+ // Register external interfaces on operations of
+ // this dialect.
+ void registerOpExternalInterfaces();
};
/// The FIR codegen dialect is a dialect containing a small set of transient
diff --git a/flang/lib/Optimizer/Dialect/FIRDialect.cpp b/flang/lib/Optimizer/Dialect/FIRDialect.cpp
index 6082417e111a5..c2377f112be84 100644
--- a/flang/lib/Optimizer/Dialect/FIRDialect.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRDialect.cpp
@@ -64,6 +64,7 @@ fir::FIROpsDialect::FIROpsDialect(mlir::MLIRContext *ctx)
#define GET_OP_LIST
#include "flang/Optimizer/Dialect/FIROps.cpp.inc"
>();
+ registerOpExternalInterfaces();
addInterfaces<FIRInlinerInterface>();
}
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 3e158183d0138..3f40b75d9485f 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -12,6 +12,7 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRAttr.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
@@ -19,6 +20,7 @@
#include "flang/Optimizer/Support/Utils.h"
#include "mlir/Dialect/CommonFolders.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinOps.h"
@@ -3758,6 +3760,17 @@ mlir::LogicalResult fir::DeclareOp::verify() {
return fortranVar.verifyDeclareLikeOpImpl(getMemref());
}
+//===----------------------------------------------------------------------===//
+// FIROpsDialect
+//===----------------------------------------------------------------------===//
+
+void fir::FIROpsDialect::registerOpExternalInterfaces() {
+ // Attach default declare target interfaces to operations which can be marked
+ // as declare target.
+ fir::GlobalOp::attachInterface<
+ mlir::omp::DeclareTargetDefaultModel<fir::GlobalOp>>(*getContext());
+}
+
// Tablegen operators
#define GET_OP_CLASSES
diff --git a/flang/test/Fir/omp-declare-target-data.fir b/flang/test/Fir/omp-declare-target-data.fir
new file mode 100644
index 0000000000000..295f8e1985228
--- /dev/null
+++ b/flang/test/Fir/omp-declare-target-data.fir
@@ -0,0 +1,78 @@
+// RUN: fir-opt --fir-to-llvm-ir %s | FileCheck %s
+
+module attributes {omp.is_device = #omp.isdevice<is_device = false>} {
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Earray_1d(dense<[1, 2, 3]> : tensor<3xi32>) {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : !llvm.array<3 x i32>
+ fir.global @_QMtest_0Earray_1d(dense<[1, 2, 3]> : tensor<3xi32>) {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<3xi32>
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Earray_2d() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : !llvm.array<2 x array<2 x i32>>
+ fir.global @_QMtest_0Earray_2d {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.array<2x2xi32> {
+ %0 = fir.undefined !fir.array<2x2xi32>
+ %c1_i32 = arith.constant 1 : i32
+ %1 = fir.insert_value %0, %c1_i32, [0 : index, 0 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32>
+ %c2_i32 = arith.constant 2 : i32
+ %2 = fir.insert_value %1, %c2_i32, [1 : index, 0 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32>
+ %c3_i32 = arith.constant 3 : i32
+ %3 = fir.insert_value %2, %c3_i32, [0 : index, 1 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32>
+ %c4_i32 = arith.constant 4 : i32
+ %4 = fir.insert_value %3, %c4_i32, [1 : index, 1 : index] : (!fir.array<2x2xi32>, i32) -> !fir.array<2x2xi32>
+ %c2 = arith.constant 2 : index
+ %c2_0 = arith.constant 2 : index
+ fir.has_value %4 : !fir.array<2x2xi32>
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_extended_link_1() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : f32
+ fir.global @_QMtest_0Edata_extended_link_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32 {
+ %cst = arith.constant 2.000000e+00 : f32
+ fir.has_value %cst : f32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_extended_link_2() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : f32
+ fir.global @_QMtest_0Edata_extended_link_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : f32 {
+ %cst = arith.constant 3.000000e+00 : f32
+ fir.has_value %cst : f32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_extended_to_1() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}} : f32
+ fir.global @_QMtest_0Edata_extended_to_1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : f32 {
+ %cst = arith.constant 2.000000e+00 : f32
+ fir.has_value %cst : f32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_extended_to_2() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}} : f32 {
+ fir.global @_QMtest_0Edata_extended_to_2 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : f32 {
+ %cst = arith.constant 3.000000e+00 : f32
+ fir.has_value %cst : f32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_int() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : i32
+ fir.global @_QMtest_0Edata_int {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32 {
+ %c10_i32 = arith.constant 10 : i32
+ fir.has_value %c10_i32 : i32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_int_clauseless() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}} : i32
+ fir.global @_QMtest_0Edata_int_clauseless {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : i32 {
+ %c1_i32 = arith.constant 1 : i32
+ fir.has_value %c1_i32 : i32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Edata_int_to() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}} : i32
+ fir.global @_QMtest_0Edata_int_to {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : i32 {
+ %c5_i32 = arith.constant 5 : i32
+ fir.has_value %c5_i32 : i32
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Ept1() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : !llvm.struct<(ptr<i32>, i64, i32, i8, i8, i8, i8)> {
+ fir.global @_QMtest_0Ept1 {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : !fir.box<!fir.ptr<i32>> {
+ %0 = fir.zero_bits !fir.ptr<i32>
+ %1 = fir.embox %0 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
+ fir.has_value %1 : !fir.box<!fir.ptr<i32>>
+ }
+
+ // CHECK: llvm.mlir.global external @_QMtest_0Ept2_tar() {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>{{.*}}} : i32
+ fir.global @_QMtest_0Ept2_tar {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} target : i32 {
+ %c5_i32 = arith.constant 5 : i32
+ fir.has_value %c5_i32 : i32
+ }
+}
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPInterfaces.h b/mlir/include/mlir/Dialect/OpenMP/OpenMPInterfaces.h
index 844201a03b30e..b3184db885216 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPInterfaces.h
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPInterfaces.h
@@ -30,6 +30,12 @@ namespace mlir::omp {
struct OffloadModuleDefaultModel
: public OffloadModuleInterface::ExternalModel<OffloadModuleDefaultModel,
mlir::ModuleOp> {};
+
+template <typename T>
+struct DeclareTargetDefaultModel
+ : public DeclareTargetInterface::ExternalModel<DeclareTargetDefaultModel<T>,
+ T> {};
+
} // namespace mlir::omp
#endif // MLIR_DIALECT_OPENMP_OPENMPINTERFACES_H_
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 02ccca8a3d7b0..75c1f1c26155e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -26,7 +26,7 @@ include "mlir/Dialect/OpenMP/OpenMPTypeInterfaces.td"
def OpenMP_Dialect : Dialect {
let name = "omp";
let cppNamespace = "::mlir::omp";
- let dependentDialects = ["::mlir::LLVM::LLVMDialect"];
+ let dependentDialects = ["::mlir::LLVM::LLVMDialect, ::mlir::func::FuncDialect"];
let useDefaultAttributePrinterParser = 1;
let usePropertiesForAttributes = 1;
}
@@ -97,6 +97,52 @@ def IntLikeType : AnyTypeOf<[AnyInteger, Index]>;
def OpenMP_PointerLikeType : TypeAlias<OpenMP_PointerLikeTypeInterface,
"OpenMP-compatible variable type">;
+//===----------------------------------------------------------------------===//
+// 2.12.7 Declare Target Directive
+//===----------------------------------------------------------------------===//
+
+def DeviceTypeAny : I32EnumAttrCase<"any", 0>;
+def DeviceTypeHost : I32EnumAttrCase<"host", 1>;
+def DeviceTypeNoHost : I32EnumAttrCase<"nohost", 2>;
+
+def DeclareTargetDeviceType : I32EnumAttr<
+ "DeclareTargetDeviceType",
+ "device_type clause",
+ [DeviceTypeAny, DeviceTypeHost, DeviceTypeNoHost]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::omp";
+}
+
+def DeclareTargetDeviceTypeAttr : EnumAttr<OpenMP_Dialect, DeclareTargetDeviceType,
+ "device_type"> {
+ let assemblyFormat = "`(` $value `)`";
+}
+
+def CaptureClauseLink : I32EnumAttrCase<"to", 0>;
+def CaptureClauseTo : I32EnumAttrCase<"link", 1>;
+
+def DeclareTargetCaptureClause : I32EnumAttr<
+ "DeclareTargetCaptureClause",
+ "capture clause",
+ [CaptureClauseLink, CaptureClauseTo]> {
+ let genSpecializedAttr = 0;
+ let cppNamespace = "::mlir::omp";
+}
+
+def DeclareTargetCaptureClauseAttr : EnumAttr<OpenMP_Dialect, DeclareTargetCaptureClause,
+ "capture_clause"> {
+ let assemblyFormat = "`(` $value `)`";
+}
+
+def DeclareTargetAttr : OpenMP_Attr<"DeclareTarget", "declaretarget"> {
+ let parameters = (ins
+ OptionalParameter<"DeclareTargetDeviceTypeAttr">:$device_type,
+ OptionalParameter<"DeclareTargetCaptureClauseAttr">:$capture_clause
+ );
+
+ let assemblyFormat = "`<` struct(params) `>`";
+}
+
//===----------------------------------------------------------------------===//
// 2.6 parallel Construct
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
index 15df11b08cc09..281f00981bda3 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
@@ -47,6 +47,74 @@ def ReductionClauseInterface : OpInterface<"ReductionClauseInterface"> {
];
}
+def DeclareTargetInterface : OpInterface<"DeclareTargetInterface"> {
+ let description = [{
+ OpenMP operations that support declare target have this interface.
+ For example, FuncOp's and llvm.GlobalOp/fir.GlobalOp's. This
+ interface allows simple manipulation and introspection of the
+ declare target attribute that can be applied to these operations.
+ }];
+
+ let cppNamespace = "::mlir::omp";
+
+ let methods = [
+ InterfaceMethod<
+ /*description=*/[{
+ Set the declare target attribute on the current operation with the
+ specified attribute arguments.
+ }],
+ /*retTy=*/"void",
+ /*methodName=*/"setDeclareTarget",
+ (ins "mlir::omp::DeclareTargetDeviceType":$deviceType,
+ "mlir::omp::DeclareTargetCaptureClause":$captureClause), [{}], [{
+ $_op->setAttr("omp.declare_target",
+ mlir::omp::DeclareTargetAttr::get(
+ $_op->getContext(),
+ mlir::omp::DeclareTargetDeviceTypeAttr::get(
+ $_op->getContext(), deviceType),
+ mlir::omp::DeclareTargetCaptureClauseAttr::get(
+ $_op->getContext(), captureClause)));
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Checks if the declare target attribute has been applied and exists on the
+ current operation. Returns true if it exists on it, otherwise returns
+ false.
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"isDeclareTarget",
+ (ins), [{}], [{
+ return $_op->hasAttr("omp.declare_target");
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Returns the DeclareTargetDeviceType segment of the DeclareTarget attribute if it
+ exists on the current operation. Otherwise it returns null.
+ }],
+ /*retTy=*/"mlir::omp::DeclareTargetDeviceType",
+ /*methodName=*/"getDeclareTargetDeviceType",
+ (ins), [{}], [{
+ if (mlir::Attribute dTar = $_op->getAttr("omp.declare_target"))
+ if (auto dAttr = dTar.dyn_cast_or_null<mlir::omp::DeclareTargetAttr>())
+ return dAttr.getDeviceType().getValue();
+ return {};
+ }]>,
+ InterfaceMethod<
+ /*description=*/[{
+ Returns the DeclareTargetCaptureClause segment of the DeclareTarget attribute if it
+ exists on the current operation. Otherwise it returns null.
+ }],
+ /*retTy=*/"mlir::omp::DeclareTargetCaptureClause",
+ /*methodName=*/"getDeclareTargetCaptureClause",
+ (ins), [{}], [{
+ if (mlir::Attribute dTar = $_op->getAttr("omp.declare_target"))
+ if (auto dAttr = dTar.dyn_cast_or_null<mlir::omp::DeclareTargetAttr>())
+ return dAttr.getCaptureClause().getValue();
+ return {};
+ }]>
+ ];
+}
+
def OffloadModuleInterface : OpInterface<"OffloadModuleInterface"> {
let description = [{
Operations that represent a module for offloading (host or device)
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 66cc653d6a19b..65cca0e494209 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/DialectImplementation.h"
@@ -71,8 +72,23 @@ void OpenMPDialect::initialize() {
MemRefType::attachInterface<PointerLikeModel<MemRefType>>(*getContext());
LLVM::LLVMPointerType::attachInterface<
PointerLikeModel<LLVM::LLVMPointerType>>(*getContext());
+
+ // Attach default offload module interface to module op to access
+ // offload functionality through
mlir::ModuleOp::attachInterface<mlir::omp::OffloadModuleDefaultModel>(
*getContext());
+
+ // Attach default declare target interfaces to operations which can be marked
+ // as declare target (Global Operations and Functions/Subroutines in dialects
+ // that Fortran (or other languages that lower to MLIR) translates too
+ mlir::LLVM::GlobalOp::attachInterface<
+ mlir::omp::DeclareTargetDefaultModel<mlir::LLVM::GlobalOp>>(
+ *getContext());
+ mlir::LLVM::LLVMFuncOp::attachInterface<
+ mlir::omp::DeclareTargetDefaultModel<mlir::LLVM::LLVMFuncOp>>(
+ *getContext());
+ mlir::func::FuncOp::attachInterface<
+ mlir::omp::DeclareTargetDefaultModel<mlir::func::FuncOp>>(*getContext());
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenMP/attr.mlir b/mlir/test/Dialect/OpenMP/attr.mlir
index 4c7a7d48ed1cf..01f3bfe115ff3 100644
--- a/mlir/test/Dialect/OpenMP/attr.mlir
+++ b/mlir/test/Dialect/OpenMP/attr.mlir
@@ -56,3 +56,83 @@ module attributes {omp.flags = #omp.flags<assume_no_thread_state = true, assume_
// CHECK: module attributes {omp.version = #omp.version<version = 51>} {
module attributes {omp.version = #omp.version<version = 51>} {}
+
+// ----
+
+// CHECK-LABEL: func @omp_decl_tar_host_to
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} {
+func.func @omp_decl_tar_host_to() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} {
+ return
+}
+
+// CHECK-LABEL: func @omp_decl_tar_host_link
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} {
+func.func @omp_decl_tar_host_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} {
+ return
+}
+
+// CHECK-LABEL: func @omp_decl_tar_nohost_to
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>} {
+func.func @omp_decl_tar_nohost_to() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>} {
+ return
+}
+
+// CHECK-LABEL: func @omp_decl_tar_nohost_link
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} {
+func.func @omp_decl_tar_nohost_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} {
+ return
+}
+
+// CHECK-LABEL: func @omp_decl_tar_any_to
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} {
+func.func @omp_decl_tar_any_to() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} {
+ return
+}
+
+// CHECK-LABEL: func @omp_decl_tar_any_link
+// CHECK-SAME: {{.*}} attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} {
+func.func @omp_decl_tar_any_link() -> () attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} {
+ return
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_host_to
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>}
+llvm.mlir.global external @omp_decl_tar_data_host_to() {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_host_link
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>}
+llvm.mlir.global external @omp_decl_tar_data_host_link() {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (link)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_nohost_to
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>}
+llvm.mlir.global external @omp_decl_tar_data_nohost_to() {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_nohost_link
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>}
+llvm.mlir.global external @omp_decl_tar_data_nohost_link() {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (link)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_any_to
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>}
+llvm.mlir.global external @omp_decl_tar_data_any_to() {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
+
+// CHECK-LABEL: global external @omp_decl_tar_data_any_link
+// CHECK-SAME: {{.*}} {{{.*}}omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>}
+llvm.mlir.global external @omp_decl_tar_data_any_link() {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (link)>} : i32 {
+ %0 = llvm.mlir.constant(1 : i32) : i32
+ llvm.return %0 : i32
+}
More information about the flang-commits
mailing list