[flang-commits] [flang] [mlir] [OpenMP][MLIR] OMPEarlyOutliningPass removal (PR #67319)
Akash Banerjee via flang-commits
flang-commits at lists.llvm.org
Mon Nov 6 05:20:01 PST 2023
https://github.com/TIFitis updated https://github.com/llvm/llvm-project/pull/67319
>From 77a35382d087a23727d3c8a546ccbd73f28de2ed Mon Sep 17 00:00:00 2001
From: Akash Banerjee <Akash.Banerjee at amd.com>
Date: Mon, 25 Sep 2023 12:31:30 +0100
Subject: [PATCH] [OpenMP][MLIR]OMPEarlyOutliningPass removal
This patch removes the OMPEarlyOutliningPass as it is no longer required. The implicit map operand capture has now been moved to the PFT lowering stage.
Depends on #67318.
---
.../flang/Optimizer/Transforms/Passes.h | 2 -
.../flang/Optimizer/Transforms/Passes.td | 12 -
flang/include/flang/Tools/CLOptions.inc | 4 +-
flang/lib/Optimizer/Transforms/CMakeLists.txt | 1 -
.../Transforms/OMPEarlyOutlining.cpp | 303 ------------------
.../OpenMP/FIR/omp-target-early-outlining.f90 | 89 -----
.../Lower/OpenMP/function-filtering-2.f90 | 2 -
.../test/Lower/OpenMP/function-filtering.f90 | 5 -
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 2 +
9 files changed, 3 insertions(+), 417 deletions(-)
delete mode 100644 flang/lib/Optimizer/Transforms/OMPEarlyOutlining.cpp
delete mode 100644 flang/test/Lower/OpenMP/FIR/omp-target-early-outlining.f90
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index 30d97be3800c191..92bc7246eca7005 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -75,8 +75,6 @@ std::unique_ptr<mlir::Pass>
createAlgebraicSimplificationPass(const mlir::GreedyRewriteConfig &config);
std::unique_ptr<mlir::Pass> createPolymorphicOpConversionPass();
-std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
-createOMPEarlyOutliningPass();
std::unique_ptr<mlir::Pass> createOMPFunctionFilteringPass();
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
createOMPMarkDeclareTargetPass();
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 6d211a535b53f70..6e23b87b7e276e9 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -318,18 +318,6 @@ def LoopVersioning : Pass<"loop-versioning", "mlir::func::FuncOp"> {
let dependentDialects = [ "fir::FIROpsDialect" ];
}
-def OMPEarlyOutliningPass
- : Pass<"omp-early-target-outlining", "mlir::ModuleOp"> {
- let summary = "Outlines all target ops into separate functions";
- let description = [{
- This pass outlines all omp.target operations into individual functions.
- It is invoked in the front end after the initial FIR has been constructed.
- This pass is only needed when compiling for the target device to prevent
- the optimizer to perform transforms across target region boundaries.
- }];
- let constructor = "::fir::createOMPEarlyOutliningPass()";
-}
-
def OMPMarkDeclareTargetPass
: Pass<"omp-mark-declare-target", "mlir::ModuleOp"> {
let summary = "Marks all functions called by an OpenMP declare target function as declare target";
diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index 2ed716382feb43f..c452c023b4a80ce 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -274,10 +274,8 @@ inline void createHLFIRToFIRPassPipeline(
inline void createOpenMPFIRPassPipeline(
mlir::PassManager &pm, bool isTargetDevice) {
pm.addPass(fir::createOMPMarkDeclareTargetPass());
- if (isTargetDevice) {
- pm.addPass(fir::createOMPEarlyOutliningPass());
+ if (isTargetDevice)
pm.addPass(fir::createOMPFunctionFilteringPass());
- }
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 98314fa7a2087fe..03b67104a93b575 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -17,7 +17,6 @@ add_flang_library(FIRTransforms
AddDebugFoundation.cpp
PolymorphicOpConversion.cpp
LoopVersioning.cpp
- OMPEarlyOutlining.cpp
OMPFunctionFiltering.cpp
OMPMarkDeclareTarget.cpp
VScaleAttr.cpp
diff --git a/flang/lib/Optimizer/Transforms/OMPEarlyOutlining.cpp b/flang/lib/Optimizer/Transforms/OMPEarlyOutlining.cpp
deleted file mode 100644
index 92fbdd0bbf5d4a1..000000000000000
--- a/flang/lib/Optimizer/Transforms/OMPEarlyOutlining.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-#include "flang/Optimizer/Dialect/FIRDialect.h"
-#include "flang/Optimizer/Dialect/FIROps.h"
-#include "flang/Optimizer/Dialect/FIRType.h"
-#include "flang/Optimizer/HLFIR/HLFIROps.h"
-#include "flang/Optimizer/Support/InternalNames.h"
-#include "flang/Optimizer/Transforms/Passes.h"
-#include "mlir/Dialect/Func/IR/FuncOps.h"
-#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
-#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
-#include "mlir/IR/BuiltinDialect.h"
-#include "mlir/IR/BuiltinOps.h"
-#include "mlir/IR/IRMapping.h"
-#include "mlir/IR/Operation.h"
-#include "mlir/IR/SymbolTable.h"
-#include "mlir/Pass/Pass.h"
-#include "mlir/Support/LLVM.h"
-#include "mlir/Transforms/RegionUtils.h"
-#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
-
-namespace fir {
-#define GEN_PASS_DEF_OMPEARLYOUTLININGPASS
-#include "flang/Optimizer/Transforms/Passes.h.inc"
-} // namespace fir
-
-namespace {
-class OMPEarlyOutliningPass
- : public fir::impl::OMPEarlyOutliningPassBase<OMPEarlyOutliningPass> {
-
- std::string getOutlinedFnName(llvm::StringRef parentName, unsigned count) {
- return std::string(parentName) + "_omp_outline_" + std::to_string(count);
- }
-
- // Given a value this function will iterate over an operators results
- // and return the relevant index for the result the value corresponds to.
- // There may be a simpler way to do this however.
- static unsigned getResultIndex(mlir::Value value, mlir::Operation *op) {
- for (unsigned i = 0; i < op->getNumResults(); ++i) {
- if (op->getResult(i) == value)
- return i;
- }
- return 0;
- }
-
- static bool isAddressOfGlobalDeclareTarget(mlir::Value value) {
- if (fir::AddrOfOp addressOfOp =
- mlir::dyn_cast_if_present<fir::AddrOfOp>(value.getDefiningOp()))
- if (fir::GlobalOp gOp = mlir::dyn_cast_if_present<fir::GlobalOp>(
- addressOfOp->getParentOfType<mlir::ModuleOp>().lookupSymbol(
- addressOfOp.getSymbol())))
- if (auto declareTargetGlobal =
- llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(
- gOp.getOperation()))
- if (declareTargetGlobal.isDeclareTarget())
- return true;
- return false;
- }
-
- // Currently used for cloning arguments that are nested. Should be
- // extendable where required, perhaps via operation
- // specialisation/overloading, if something needs specialised handling.
- // NOTE: Results in duplication of some values that would otherwise be
- // a single SSA value shared between operations, this is tidied up on
- // lowering to some extent.
- static mlir::Operation *
- cloneArgAndChildren(mlir::OpBuilder &builder, mlir::Operation *op,
- llvm::SetVector<mlir::Value> &inputs,
- mlir::Block::BlockArgListType &newInputs) {
- mlir::IRMapping valueMap;
- for (mlir::Value opValue : op->getOperands()) {
- if (opValue.getDefiningOp()) {
- unsigned resIdx = getResultIndex(opValue, opValue.getDefiningOp());
- valueMap.map(opValue,
- cloneArgAndChildren(builder, opValue.getDefiningOp(),
- inputs, newInputs)
- ->getResult(resIdx));
- } else {
- for (auto inArg : llvm::zip(inputs, newInputs)) {
- if (opValue == std::get<0>(inArg))
- valueMap.map(opValue, std::get<1>(inArg));
- }
- }
- }
-
- return builder.clone(*op, valueMap);
- }
-
- static void cloneMapOpVariables(mlir::OpBuilder &builder,
- mlir::IRMapping &valueMap,
- mlir::IRMapping &mapInfoMap,
- llvm::SetVector<mlir::Value> &inputs,
- mlir::Block::BlockArgListType &newInputs,
- mlir::Value varPtr) {
- if (fir::BoxAddrOp boxAddrOp =
- mlir::dyn_cast_if_present<fir::BoxAddrOp>(varPtr.getDefiningOp())) {
- mlir::Value newV =
- cloneArgAndChildren(builder, boxAddrOp, inputs, newInputs)
- ->getResult(0);
- mapInfoMap.map(varPtr, newV);
- valueMap.map(boxAddrOp, newV);
- return;
- }
-
- // Clone into the outlined function all hlfir.declare ops that define inputs
- // to the target region and set up remapping of its inputs and outputs.
- if (auto declareOp = mlir::dyn_cast_if_present<hlfir::DeclareOp>(
- varPtr.getDefiningOp())) {
- auto clone = llvm::cast<hlfir::DeclareOp>(
- cloneArgAndChildren(builder, declareOp, inputs, newInputs));
- mlir::Value newBase = clone.getBase();
- mlir::Value newOrigBase = clone.getOriginalBase();
- mapInfoMap.map(varPtr, newOrigBase);
- valueMap.map(declareOp.getBase(), newBase);
- valueMap.map(declareOp.getOriginalBase(), newOrigBase);
- return;
- }
-
- if (isAddressOfGlobalDeclareTarget(varPtr)) {
- fir::AddrOfOp addrOp =
- mlir::dyn_cast<fir::AddrOfOp>(varPtr.getDefiningOp());
- mlir::Value newV = builder.clone(*addrOp)->getResult(0);
- mapInfoMap.map(varPtr, newV);
- valueMap.map(addrOp, newV);
- return;
- }
-
- for (auto inArg : llvm::zip(inputs, newInputs)) {
- if (varPtr == std::get<0>(inArg))
- mapInfoMap.map(varPtr, std::get<1>(inArg));
- }
- }
-
- mlir::func::FuncOp outlineTargetOp(mlir::OpBuilder &builder,
- mlir::omp::TargetOp &targetOp,
- mlir::func::FuncOp &parentFunc,
- unsigned count) {
- // NOTE: once implicit captures are handled appropriately in the initial
- // PFT lowering if it is possible, we can remove the usage of
- // getUsedValuesDefinedAbove and instead just iterate over the target op's
- // operands (or just the map arguments) and perhaps refactor this function
- // a little.
- // Collect inputs
- llvm::SetVector<mlir::Value> inputs;
- mlir::Region &targetRegion = targetOp.getRegion();
- mlir::getUsedValuesDefinedAbove(targetRegion, inputs);
-
- // Collect all map info. Even non-used maps must be collected to avoid ICEs.
- for (mlir::Value oper : targetOp->getOperands()) {
- if (auto mapEntry =
- mlir::dyn_cast<mlir::omp::MapInfoOp>(oper.getDefiningOp())) {
- if (!inputs.contains(mapEntry.getVarPtr()))
- inputs.insert(mapEntry.getVarPtr());
- }
- }
-
- // Filter out declare-target and map entries which are specially handled
- // at the moment, so we do not wish these to end up as function arguments
- // which would just be more noise in the IR.
- llvm::SmallVector<mlir::Value> blockArgs;
- for (llvm::SetVector<mlir::Value>::iterator iter = inputs.begin(); iter != inputs.end();) {
- if (mlir::isa_and_nonnull<mlir::omp::MapInfoOp>(iter->getDefiningOp()) ||
- isAddressOfGlobalDeclareTarget(*iter)) {
- iter = inputs.erase(iter);
- } else if (auto declareOp = mlir::dyn_cast_if_present<hlfir::DeclareOp>(
- iter->getDefiningOp())) {
- // Gather hlfir.declare arguments to be added later, after the
- // hlfir.declare operation itself has been removed as an input.
- blockArgs.push_back(declareOp.getMemref());
- if (mlir::Value shape = declareOp.getShape())
- blockArgs.push_back(shape);
- for (mlir::Value typeParam : declareOp.getTypeparams())
- blockArgs.push_back(typeParam);
- iter = inputs.erase(iter);
- } else {
- ++iter;
- }
- }
-
- // Add function arguments to the list of inputs if they are used by an
- // hlfir.declare operation.
- for (mlir::Value arg : blockArgs) {
- if (!arg.getDefiningOp() && !inputs.contains(arg))
- inputs.insert(arg);
- }
-
- // Create new function and initialize
- mlir::FunctionType funcType = builder.getFunctionType(
- mlir::TypeRange(inputs.getArrayRef()), mlir::TypeRange());
- std::string parentName(parentFunc.getName());
- std::string funcName = getOutlinedFnName(parentName, count);
- mlir::Location loc = targetOp.getLoc();
- mlir::func::FuncOp newFunc =
- mlir::func::FuncOp::create(loc, funcName, funcType);
- mlir::Block *entryBlock = newFunc.addEntryBlock();
- builder.setInsertionPointToStart(entryBlock);
- mlir::Block::BlockArgListType newInputs = entryBlock->getArguments();
-
- // Set the declare target information, the outlined function
- // is always a host function.
- if (auto parentDTOp = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(
- parentFunc.getOperation()))
- if (auto newDTOp = llvm::dyn_cast<mlir::omp::DeclareTargetInterface>(
- newFunc.getOperation()))
- newDTOp.setDeclareTarget(mlir::omp::DeclareTargetDeviceType::host,
- parentDTOp.getDeclareTargetCaptureClause());
-
- // Set the early outlining interface parent name
- if (auto earlyOutlineOp =
- llvm::dyn_cast<mlir::omp::EarlyOutliningInterface>(
- newFunc.getOperation()))
- earlyOutlineOp.setParentName(parentName);
-
- // The value map for the newly generated Target Operation, we must
- // remap most of the input.
- mlir::IRMapping valueMap;
-
- // Special handling for map, declare target and regular map variables
- // are handled slightly differently for the moment, declare target has
- // its addressOfOp cloned over, whereas we skip it for the regular map
- // variables. We need knowledge of which global is linked to the map
- // operation for declare target, whereas we aren't bothered for the
- // regular map variables for the moment. We could treat both the same,
- // however, cloning across the minimum for the moment to avoid
- // optimisations breaking segments of the lowering seems prudent as this
- // was the original intent of the pass.
- for (mlir::Value oper : targetOp->getOperands()) {
- if (auto mapEntry =
- mlir::dyn_cast<mlir::omp::MapInfoOp>(oper.getDefiningOp())) {
- mlir::IRMapping mapInfoMap;
- for (mlir::Value bound : mapEntry.getBounds()) {
- if (auto mapEntryBound = mlir::dyn_cast<mlir::omp::DataBoundsOp>(
- bound.getDefiningOp())) {
- mapInfoMap.map(bound, cloneArgAndChildren(builder, mapEntryBound,
- inputs, newInputs)
- ->getResult(0));
- }
- }
-
- cloneMapOpVariables(builder, valueMap, mapInfoMap, inputs, newInputs,
- mapEntry.getVarPtr());
-
- if (mapEntry.getVarPtrPtr())
- cloneMapOpVariables(builder, valueMap, mapInfoMap, inputs, newInputs,
- mapEntry.getVarPtrPtr());
-
- valueMap.map(
- mapEntry,
- builder.clone(*mapEntry.getOperation(), mapInfoMap)->getResult(0));
- }
- }
-
- for (auto inArg : llvm::zip(inputs, newInputs))
- valueMap.map(std::get<0>(inArg), std::get<1>(inArg));
-
- // Clone the target op into the new function
- builder.clone(*(targetOp.getOperation()), valueMap);
-
- // Create return op
- builder.create<mlir::func::ReturnOp>(loc);
-
- return newFunc;
- }
-
- // Returns true if a target region was found in the function.
- bool outlineTargetOps(mlir::OpBuilder &builder,
- mlir::func::FuncOp &functionOp,
- mlir::ModuleOp &moduleOp,
- llvm::SmallVectorImpl<mlir::func::FuncOp> &newFuncs) {
- unsigned count = 0;
- for (auto TargetOp : functionOp.getOps<mlir::omp::TargetOp>()) {
- mlir::func::FuncOp outlinedFunc =
- outlineTargetOp(builder, TargetOp, functionOp, count);
- newFuncs.push_back(outlinedFunc);
- count++;
- }
- return count > 0;
- }
-
- void runOnOperation() override {
- mlir::ModuleOp moduleOp = getOperation();
- mlir::MLIRContext *context = &getContext();
- mlir::OpBuilder builder(context);
- llvm::SmallVector<mlir::func::FuncOp> newFuncs;
-
- for (auto functionOp :
- llvm::make_early_inc_range(moduleOp.getOps<mlir::func::FuncOp>())) {
- bool outlined = outlineTargetOps(builder, functionOp, moduleOp, newFuncs);
- if (outlined)
- functionOp.erase();
- }
-
- for (auto newFunc : newFuncs)
- moduleOp.push_back(newFunc);
- }
-};
-
-} // namespace
-
-namespace fir {
-std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
-createOMPEarlyOutliningPass() {
- return std::make_unique<OMPEarlyOutliningPass>();
-}
-} // namespace fir
diff --git a/flang/test/Lower/OpenMP/FIR/omp-target-early-outlining.f90 b/flang/test/Lower/OpenMP/FIR/omp-target-early-outlining.f90
deleted file mode 100644
index 14bf911b3e5410c..000000000000000
--- a/flang/test/Lower/OpenMP/FIR/omp-target-early-outlining.f90
+++ /dev/null
@@ -1,89 +0,0 @@
-!REQUIRES: amdgpu-registered-target
-
-!RUN: %flang_fc1 -triple amdgcn-amd-amdhsa -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
-!RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
-!RUN: bbc -emit-fir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
-!RUN: bbc -emit-fir -fopenmp -fopenmp-is-gpu -fopenmp-is-target-device %s -o - | FileCheck %s
-
-!CHECK: func.func @_QPtarget_function
-
-!CHECK: func.func @_QPwrite_index_omp_outline_0(%[[ARG0:.*]]: !fir.ref<i32>) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>, omp.outline_parent_name = "_QPwrite_index"} {
-!CHECK-NEXT: %[[map_info0:.*]] = omp.map_info var_ptr(%[[ARG0]]{{.*}}
-!CHECK-NEXT: omp.target map_entries(%[[map_info0]]{{.*}} {
-!CHECK: %[[CONSTANT_VALUE_10:.*]] = arith.constant 10 : i32
-!CHECK: fir.store %[[CONSTANT_VALUE_10]] to %[[ARG0]] : !fir.ref<i32>
-!CHECK: omp.terminator
-!CHECK-NEXT: }
-!CHECK-NEXT: return
-
-!CHECK: func.func @_QPwrite_index_omp_outline_1(%[[ARG1:.*]]: !fir.ref<i32>) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>, omp.outline_parent_name = "_QPwrite_index"} {
-!CHECK-NEXT: %[[map_info1:.*]] = omp.map_info var_ptr(%[[ARG1]]{{.*}}
-!CHECK-NEXT: omp.target map_entries(%[[map_info1]]{{.*}} {
-!CHECK: %[[CONSTANT_VALUE_20:.*]] = arith.constant 20 : i32
-!CHECK: fir.store %[[CONSTANT_VALUE_20]] to %[[ARG1]] : !fir.ref<i32>
-!CHECK: omp.terminator
-!CHECK-NEXT: }
-!CHECK-NEXT: return
-
-
-SUBROUTINE WRITE_INDEX(INT_ARRAY)
- INTEGER :: INT_ARRAY(*)
- INTEGER :: NEW_LEN
-!$omp target map(from:new_len)
- NEW_LEN = 10
-!$omp end target
-!$omp target map(from:new_len)
- NEW_LEN = 20
-!$omp end target
- do INDEX_ = 1, NEW_LEN
- INT_ARRAY(INDEX_) = INDEX_
- end do
-end subroutine WRITE_INDEX
-
-SUBROUTINE TARGET_FUNCTION()
-!$omp declare target
-END
-
-!CHECK: func.func @_QParray_bounds_omp_outline_0(%[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<!fir.array<10xi32>>) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>, omp.outline_parent_name = "_QParray_bounds"} {
-!CHECK: %[[C1:.*]] = arith.constant 1 : index
-!CHECK: %[[C4:.*]] = arith.constant 4 : index
-!CHECK: %[[C1_0:.*]] = arith.constant 1 : index
-!CHECK: %[[C1_1:.*]] = arith.constant 1 : index
-!CHECK: %[[BOUNDS:.*]] = omp.bounds lower_bound(%[[C1]] : index) upper_bound(%[[C4]] : index) stride(%[[C1_1]] : index) start_idx(%[[C1_1]] : index)
-!CHECK: %[[ENTRY:.*]] = omp.map_info var_ptr(%[[ARG1]] : !fir.ref<!fir.array<10xi32>>, !fir.array<10xi32>) map_clauses(tofrom) capture(ByRef) bounds(%[[BOUNDS]]) -> !fir.ref<!fir.array<10xi32>> {name = "sp_write(2:5)"}
-!CHECK: omp.target map_entries(%[[ENTRY]] : !fir.ref<!fir.array<10xi32>>) {
-!CHECK: %c2_i32 = arith.constant 2 : i32
-!CHECK: %2 = fir.convert %c2_i32 : (i32) -> index
-!CHECK: %c5_i32 = arith.constant 5 : i32
-!CHECK: %3 = fir.convert %c5_i32 : (i32) -> index
-!CHECK: %c1_2 = arith.constant 1 : index
-!CHECK: %4 = fir.convert %2 : (index) -> i32
-!CHECK: %5:2 = fir.do_loop %arg2 = %2 to %3 step %c1_2 iter_args(%arg3 = %4) -> (index, i32) {
-!CHECK: fir.store %arg3 to %[[ARG0]] : !fir.ref<i32>
-!CHECK: %6 = fir.load %[[ARG0]] : !fir.ref<i32>
-!CHECK: %7 = fir.load %[[ARG0]] : !fir.ref<i32>
-!CHECK: %8 = fir.convert %7 : (i32) -> i64
-!CHECK: %c1_i64 = arith.constant 1 : i64
-!CHECK: %9 = arith.subi %8, %c1_i64 : i64
-!CHECK: %10 = fir.coordinate_of %[[ARG1]], %9 : (!fir.ref<!fir.array<10xi32>>, i64) -> !fir.ref<i32>
-!CHECK: fir.store %6 to %10 : !fir.ref<i32>
-!CHECK: %11 = arith.addi %arg2, %c1_2 : index
-!CHECK: %12 = fir.convert %c1_2 : (index) -> i32
-!CHECK: %13 = fir.load %[[ARG0]] : !fir.ref<i32>
-!CHECK: %14 = arith.addi %13, %12 : i32
-!CHECK: fir.result %11, %14 : index, i32
-!CHECK: }
-!CHECK: fir.store %5#1 to %[[ARG0]] : !fir.ref<i32>
-!CHECK: omp.terminator
-!CHECK: }
-!CHECK:return
-!CHECK:}
-
-SUBROUTINE ARRAY_BOUNDS()
- INTEGER :: sp_write(10) = (/0,0,0,0,0,0,0,0,0,0/)
-!$omp target map(tofrom:sp_write(2:5))
- do i = 2, 5
- sp_write(i) = i
- end do
-!$omp end target
-end subroutine ARRAY_BOUNDS
diff --git a/flang/test/Lower/OpenMP/function-filtering-2.f90 b/flang/test/Lower/OpenMP/function-filtering-2.f90
index 8219be5ad1e40ca..17cd0d44c01b4bc 100644
--- a/flang/test/Lower/OpenMP/function-filtering-2.f90
+++ b/flang/test/Lower/OpenMP/function-filtering-2.f90
@@ -26,9 +26,7 @@ subroutine no_declaretarget()
end subroutine no_declaretarget
! MLIR-HOST: func.func @{{.*}}main(
-! MLIR-HOST-NOT: func.func @{{.*}}main_omp_outline{{.*}}()
! MLIR-DEVICE-NOT: func.func @{{.*}}main(
-! MLIR-DEVICE: func.func @{{.*}}main_omp_outline{{.*}}() attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>, omp.outline_parent_name = "_QQmain"}
! MLIR-ALL: return
! LLVM-HOST: define {{.*}} @{{.*}}main{{.*}}(
diff --git a/flang/test/Lower/OpenMP/function-filtering.f90 b/flang/test/Lower/OpenMP/function-filtering.f90
index 3de14aa4709fc4c..e550348e50692c5 100644
--- a/flang/test/Lower/OpenMP/function-filtering.f90
+++ b/flang/test/Lower/OpenMP/function-filtering.f90
@@ -34,14 +34,9 @@ end function host_fn
! MLIR-HOST: func.func @{{.*}}target_subr(
! MLIR-HOST: return
-! MLIR-HOST-NOT: func.func @{{.*}}target_subr_omp_outline_0(
-! MLIR-DEVICE-NOT: func.func @{{.*}}target_subr(
-! MLIR-DEVICE: func.func @{{.*}}target_subr_omp_outline_0(
! MLIR-DEVICE: return
-! LLVM-ALL-NOT: define {{.*}} @{{.*}}target_subr_omp_outline_0{{.*}}(
! LLVM-HOST: define {{.*}} @{{.*}}target_subr{{.*}}(
-! LLVM-DEVICE-NOT: {{.*}} @{{.*}}target_subr{{.*}}(
! LLVM-ALL: define {{.*}} @__omp_offloading_{{.*}}_{{.*}}_target_subr__{{.*}}(
subroutine target_subr(x)
integer, intent(out) :: x
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 1daf60b8659bb66..422bbded2cbfc13 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -2459,6 +2459,8 @@ convertDeclareTargetAttr(Operation *op, mlir::omp::DeclareTargetAttr attribute,
if (declareType == omp::DeclareTargetDeviceType::host) {
llvm::Function *llvmFunc =
moduleTranslation.lookupFunction(funcOp.getName());
+ llvmFunc->replaceAllUsesWith(
+ llvm::UndefValue::get(llvmFunc->getType()));
llvmFunc->dropAllReferences();
llvmFunc->eraseFromParent();
}
More information about the flang-commits
mailing list