[flang-commits] [flang] [flang][cuda] Fix allocation of descriptor for cray pointer (PR #103474)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 13 14:27:45 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Valentin Clement (バレンタイン クレメン) (clementval)
<details>
<summary>Changes</summary>
The cray pointee descriptor with device attribute was not allocated with cuf.alloc so it leads to error on deallocation with cuf.free.
---
Full diff: https://github.com/llvm/llvm-project/pull/103474.diff
5 Files Affected:
- (modified) flang/include/flang/Optimizer/Builder/FIRBuilder.h (+10-10)
- (modified) flang/lib/Lower/ConvertVariable.cpp (+4-1)
- (modified) flang/lib/Optimizer/Builder/CMakeLists.txt (+4)
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+18-12)
- (modified) flang/test/Lower/CUDA/cuda-data-attribute.cuf (+5)
``````````diff
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 17a9a20c9b439d..f7151f26f09cb3 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -214,20 +214,20 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
/// Create a temporary using `fir.alloca`. This function does not hoist.
/// It is the callers responsibility to set the insertion point if
/// hoisting is required.
- mlir::Value
- createTemporaryAlloc(mlir::Location loc, mlir::Type type,
- llvm::StringRef name, mlir::ValueRange lenParams = {},
- mlir::ValueRange shape = {},
- llvm::ArrayRef<mlir::NamedAttribute> attrs = {});
+ mlir::Value createTemporaryAlloc(
+ mlir::Location loc, mlir::Type type, llvm::StringRef name,
+ mlir::ValueRange lenParams = {}, mlir::ValueRange shape = {},
+ llvm::ArrayRef<mlir::NamedAttribute> attrs = {},
+ std::optional<Fortran::common::CUDADataAttr> cudaAttr = std::nullopt);
/// Create a temporary. A temp is allocated using `fir.alloca` and can be read
/// and written using `fir.load` and `fir.store`, resp. The temporary can be
/// given a name via a front-end `Symbol` or a `StringRef`.
- mlir::Value createTemporary(mlir::Location loc, mlir::Type type,
- llvm::StringRef name = {},
- mlir::ValueRange shape = {},
- mlir::ValueRange lenParams = {},
- llvm::ArrayRef<mlir::NamedAttribute> attrs = {});
+ mlir::Value createTemporary(
+ mlir::Location loc, mlir::Type type, llvm::StringRef name = {},
+ mlir::ValueRange shape = {}, mlir::ValueRange lenParams = {},
+ llvm::ArrayRef<mlir::NamedAttribute> attrs = {},
+ std::optional<Fortran::common::CUDADataAttr> cudaAttr = std::nullopt);
/// Create an unnamed and untracked temporary on the stack.
mlir::Value createTemporary(mlir::Location loc, mlir::Type type,
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index ffbbea238647ce..70fa32d621e2f1 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1698,7 +1698,10 @@ static void genDeclareSymbol(Fortran::lower::AbstractConverter &converter,
if (sym.test(Fortran::semantics::Symbol::Flag::CrayPointee)) {
mlir::Type ptrBoxType =
Fortran::lower::getCrayPointeeBoxType(base.getType());
- mlir::Value boxAlloc = builder.createTemporary(loc, ptrBoxType);
+ mlir::Value boxAlloc = builder.createTemporary(
+ loc, ptrBoxType,
+ /*name=*/{}, /*shape=*/{}, /*lenParams=*/{}, /*attrs=*/{},
+ Fortran::semantics::GetCUDADataAttr(&sym.GetUltimate()));
// Declare a local pointer variable.
auto newBase = builder.create<hlfir::DeclareOp>(
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index 8ffd0aa4cf42be..05164d41a4cb55 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -35,12 +35,16 @@ add_flang_library(FIRBuilder
TemporaryStorage.cpp
DEPENDS
+ CUFAttrs
+ CUFDialect
FIRDialect
HLFIRDialect
${dialect_libs}
${extension_libs}
LINK_LIBS
+ CUFAttrs
+ CUFDialect
FIRDialect
FIRDialectSupport
FIRSupport
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index d54715d3fa3f56..864e9d31e25cb9 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -14,6 +14,7 @@
#include "flang/Optimizer/Builder/Runtime/Assign.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/CUF/CUFOps.h"
#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -270,25 +271,30 @@ mlir::Block *fir::FirOpBuilder::getAllocaBlock() {
mlir::Value fir::FirOpBuilder::createTemporaryAlloc(
mlir::Location loc, mlir::Type type, llvm::StringRef name,
mlir::ValueRange lenParams, mlir::ValueRange shape,
- llvm::ArrayRef<mlir::NamedAttribute> attrs) {
+ llvm::ArrayRef<mlir::NamedAttribute> attrs,
+ std::optional<Fortran::common::CUDADataAttr> cudaAttr) {
assert(!mlir::isa<fir::ReferenceType>(type) && "cannot be a reference");
// If the alloca is inside an OpenMP Op which will be outlined then pin
// the alloca here.
const bool pinned =
getRegion().getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>();
- mlir::Value temp =
- create<fir::AllocaOp>(loc, type, /*unique_name=*/llvm::StringRef{}, name,
- pinned, lenParams, shape, attrs);
- return temp;
+ if (cudaAttr) {
+ cuf::DataAttributeAttr attr = cuf::getDataAttribute(getContext(), cudaAttr);
+ return create<cuf::AllocOp>(loc, type, /*unique_name=*/llvm::StringRef{},
+ name, attr, lenParams, shape, attrs);
+ } else {
+ return create<fir::AllocaOp>(loc, type, /*unique_name=*/llvm::StringRef{},
+ name, pinned, lenParams, shape, attrs);
+ }
}
/// Create a temporary variable on the stack. Anonymous temporaries have no
/// `name` value. Temporaries do not require a uniqued name.
-mlir::Value
-fir::FirOpBuilder::createTemporary(mlir::Location loc, mlir::Type type,
- llvm::StringRef name, mlir::ValueRange shape,
- mlir::ValueRange lenParams,
- llvm::ArrayRef<mlir::NamedAttribute> attrs) {
+mlir::Value fir::FirOpBuilder::createTemporary(
+ mlir::Location loc, mlir::Type type, llvm::StringRef name,
+ mlir::ValueRange shape, mlir::ValueRange lenParams,
+ llvm::ArrayRef<mlir::NamedAttribute> attrs,
+ std::optional<Fortran::common::CUDADataAttr> cudaAttr) {
llvm::SmallVector<mlir::Value> dynamicShape =
fir::factory::elideExtentsAlreadyInType(type, shape);
llvm::SmallVector<mlir::Value> dynamicLength =
@@ -300,8 +306,8 @@ fir::FirOpBuilder::createTemporary(mlir::Location loc, mlir::Type type,
setInsertionPointToStart(getAllocaBlock());
}
- mlir::Value ae =
- createTemporaryAlloc(loc, type, name, dynamicLength, dynamicShape, attrs);
+ mlir::Value ae = createTemporaryAlloc(loc, type, name, dynamicLength,
+ dynamicShape, attrs, cudaAttr);
if (hoistAlloc)
restoreInsertionPoint(insPt);
diff --git a/flang/test/Lower/CUDA/cuda-data-attribute.cuf b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
index 192ef044913b9e..805250691a3897 100644
--- a/flang/test/Lower/CUDA/cuda-data-attribute.cuf
+++ b/flang/test/Lower/CUDA/cuda-data-attribute.cuf
@@ -109,4 +109,9 @@ end subroutine
end module
+subroutine craypointer()
+ real, device :: x(*); pointer(px, x)
+end
+! CHECK-LABEL: func.func @_QPcraypointer()
+! CHECK: %{{.*}} = cuf.alloc !fir.box<!fir.ptr<!fir.array<?xf32>>> {data_attr = #cuf.cuda<device>} -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
``````````
</details>
https://github.com/llvm/llvm-project/pull/103474
More information about the flang-commits
mailing list