[flang-commits] [flang] [flang][acc] Ensure fir.class is handled in type categorization (PR #146174)
Razvan Lupusoru via flang-commits
flang-commits at lists.llvm.org
Mon Jun 30 13:25:14 PDT 2025
https://github.com/razvanlupusoru updated https://github.com/llvm/llvm-project/pull/146174
>From fccfee43187fe1933a8feb16dc2626cc7c3d460a Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Fri, 27 Jun 2025 16:05:12 -0700
Subject: [PATCH 1/4] [flang][acc] Ensure fir.class is handled in type
categorization
fir.class is treated similarly as fir.box - but it has one key
distinction which is that it doesn't hold an element type. Thus
the categorization logic was mishandling this case for this reason
(and also the fact that it assumed that a base object is always a
fir.ref).
This PR improves this handling and adds appropriate test exercising
both a class and a class field to ensure categorization works.
---
.../OpenACC/FIROpenACCTypeInterfaces.cpp | 22 ++++++++++++++-----
.../OpenACC/openacc-type-categories-class.f90 | 18 +++++++++++++++
.../lib/OpenACC/TestOpenACCInterfaces.cpp | 9 ++++++++
3 files changed, 44 insertions(+), 5 deletions(-)
create mode 100644 flang/test/Fir/OpenACC/openacc-type-categories-class.f90
diff --git a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
index 673d7e86c7ba0..2702f7e8c185e 100644
--- a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
@@ -320,8 +320,13 @@ template <>
mlir::acc::VariableTypeCategory
OpenACCMappableModel<fir::BaseBoxType>::getTypeCategory(mlir::Type type,
mlir::Value var) const {
+ // Class-type does not behave like a normal box because it does not hold an
+ // element type. Thus special handle it here.
+ if (mlir::isa<fir::ClassType>(type))
+ return mlir::acc::VariableTypeCategory::composite;
mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
+ assert(eleTy && "expect to be able to unwrap the element type");
// If the type enclosed by the box is a mappable type, then have it
// provide the type category.
@@ -346,7 +351,7 @@ OpenACCMappableModel<fir::BaseBoxType>::getTypeCategory(mlir::Type type,
return mlir::acc::VariableTypeCategory::nonscalar;
}
-static mlir::TypedValue<mlir::acc::PointerLikeType>
+static mlir::Value
getBaseRef(mlir::TypedValue<mlir::acc::PointerLikeType> varPtr) {
// If there is no defining op - the unwrapped reference is the base one.
mlir::Operation *op = varPtr.getDefiningOp();
@@ -372,7 +377,7 @@ getBaseRef(mlir::TypedValue<mlir::acc::PointerLikeType> varPtr) {
})
.Default([&](mlir::Operation *) { return varPtr; });
- return mlir::cast<mlir::TypedValue<mlir::acc::PointerLikeType>>(baseRef);
+ return baseRef;
}
static mlir::acc::VariableTypeCategory
@@ -384,10 +389,17 @@ categorizePointee(mlir::Type pointer,
// value would both be represented as !fir.ref<f32>. We do not want to treat
// such a reference as a scalar. Thus unwrap interior pointer calculations.
auto baseRef = getBaseRef(varPtr);
- mlir::Type eleTy = baseRef.getType().getElementType();
- if (auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
- return mappableTy.getTypeCategory(varPtr);
+ if (auto mappableTy =
+ mlir::dyn_cast<mlir::acc::MappableType>(baseRef.getType()))
+ return mappableTy.getTypeCategory(baseRef);
+
+ // It must be a pointer-like type since it is not a MappableType.
+ auto ptrLikeTy = mlir::cast<mlir::acc::PointerLikeType>(baseRef.getType());
+ mlir::Type eleTy = ptrLikeTy.getElementType();
+
+ if (auto mappableEleTy = mlir::dyn_cast<mlir::acc::MappableType>(eleTy))
+ return mappableEleTy.getTypeCategory(varPtr);
if (isScalarLike(eleTy))
return mlir::acc::VariableTypeCategory::scalar;
diff --git a/flang/test/Fir/OpenACC/openacc-type-categories-class.f90 b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
new file mode 100644
index 0000000000000..0a38ab96a0315
--- /dev/null
+++ b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
@@ -0,0 +1,18 @@
+module mm
+ type, public :: polyty
+ real :: field
+ end type
+contains
+ subroutine init(this)
+ class(polyty), intent(inout) :: this
+ !$acc enter data copyin(this, this%field)
+ end subroutine
+end module
+
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | fir-opt -pass-pipeline='builtin.module(test-fir-openacc-interfaces)' --mlir-disable-threading 2>&1 | FileCheck %s
+! CHECK: Visiting: {{.*}} acc.copyin {{.*}} {name = "this", structured = false}
+! CHECK: Mappable: !fir.class<!fir.type<_QMmmTpolyty{field:f32}>>
+! CHECK: Type category: composite
+! CHECK: Visiting: {{.*}} acc.copyin {{.*}} {name = "this%field", structured = false}
+! CHECK: Pointer-like: !fir.ref<f32>
+! CHECK: Type category: composite
diff --git a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
index 90aabd7d40d44..11567d1c0c6a3 100644
--- a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
+++ b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
@@ -6,12 +6,16 @@
//
//===----------------------------------------------------------------------===//
+#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/LLVM.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/Support/DataLayout.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
using namespace mlir;
@@ -25,6 +29,11 @@ struct TestFIROpenACCInterfaces
StringRef getDescription() const final {
return "Test FIR implementation of the OpenACC interfaces.";
}
+ void getDependentDialects(::mlir::DialectRegistry ®istry) const override {
+ registry.insert<fir::FIROpsDialect, hlfir::hlfirDialect,
+ mlir::arith::ArithDialect, mlir::acc::OpenACCDialect,
+ mlir::DLTIDialect>();
+ }
void runOnOperation() override {
mlir::ModuleOp mod = getOperation();
auto datalayout =
>From a8b1627839b24e2042ac788e1c0b0bb54e758e8d Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Mon, 30 Jun 2025 11:44:04 -0700
Subject: [PATCH 2/4] Move runtest line to top of file
---
flang/test/Fir/OpenACC/openacc-type-categories-class.f90 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/flang/test/Fir/OpenACC/openacc-type-categories-class.f90 b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
index 0a38ab96a0315..f1bac4d6dfbcd 100644
--- a/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
+++ b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
@@ -1,3 +1,5 @@
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | fir-opt -pass-pipeline='builtin.module(test-fir-openacc-interfaces)' --mlir-disable-threading 2>&1 | FileCheck %s
+
module mm
type, public :: polyty
real :: field
@@ -9,7 +11,6 @@ subroutine init(this)
end subroutine
end module
-! RUN: bbc -fopenacc -emit-hlfir %s -o - | fir-opt -pass-pipeline='builtin.module(test-fir-openacc-interfaces)' --mlir-disable-threading 2>&1 | FileCheck %s
! CHECK: Visiting: {{.*}} acc.copyin {{.*}} {name = "this", structured = false}
! CHECK: Mappable: !fir.class<!fir.type<_QMmmTpolyty{field:f32}>>
! CHECK: Type category: composite
>From 3d64e5d525ec9edff8ea26673fde1b2b12fc4087 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Mon, 30 Jun 2025 13:21:54 -0700
Subject: [PATCH 3/4] Add better support for unlimited polymorphic and assumed
type
---
.../OpenACC/FIROpenACCTypeInterfaces.cpp | 17 ++++++++++--
.../OpenACC/openacc-type-categories-class.f90 | 27 +++++++++++++++++++
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
index 2702f7e8c185e..317a41a2129c3 100644
--- a/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/FIROpenACCTypeInterfaces.cpp
@@ -306,6 +306,10 @@ static bool isArrayLike(mlir::Type type) {
}
static bool isCompositeLike(mlir::Type type) {
+ // class(*) is not a composite type since it does not have a determined type.
+ if (fir::isUnlimitedPolymorphicType(type))
+ return false;
+
return mlir::isa<fir::RecordType, fir::ClassType, mlir::TupleType>(type);
}
@@ -322,8 +326,13 @@ OpenACCMappableModel<fir::BaseBoxType>::getTypeCategory(mlir::Type type,
mlir::Value var) const {
// Class-type does not behave like a normal box because it does not hold an
// element type. Thus special handle it here.
- if (mlir::isa<fir::ClassType>(type))
+ if (mlir::isa<fir::ClassType>(type)) {
+ // class(*) is not a composite type since it does not have a determined
+ // type.
+ if (fir::isUnlimitedPolymorphicType(type))
+ return mlir::acc::VariableTypeCategory::uncategorized;
return mlir::acc::VariableTypeCategory::composite;
+ }
mlir::Type eleTy = fir::dyn_cast_ptrOrBoxEleTy(type);
assert(eleTy && "expect to be able to unwrap the element type");
@@ -409,8 +418,12 @@ categorizePointee(mlir::Type pointer,
return mlir::acc::VariableTypeCategory::composite;
if (mlir::isa<fir::CharacterType, mlir::FunctionType>(eleTy))
return mlir::acc::VariableTypeCategory::nonscalar;
+ // Assumed-type (type(*))does not have a determined type that can be
+ // categorized.
+ if (mlir::isa<mlir::NoneType>(eleTy))
+ return mlir::acc::VariableTypeCategory::uncategorized;
// "pointers" - in the sense of raw address point-of-view, are considered
- // scalars. However
+ // scalars.
if (mlir::isa<fir::LLVMPointerType>(eleTy))
return mlir::acc::VariableTypeCategory::scalar;
diff --git a/flang/test/Fir/OpenACC/openacc-type-categories-class.f90 b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
index f1bac4d6dfbcd..58025bfa556a5 100644
--- a/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
+++ b/flang/test/Fir/OpenACC/openacc-type-categories-class.f90
@@ -9,6 +9,20 @@ subroutine init(this)
class(polyty), intent(inout) :: this
!$acc enter data copyin(this, this%field)
end subroutine
+ subroutine init_assumed_type(var)
+ type(*), intent(inout) :: var
+ !$acc enter data copyin(var)
+ end subroutine
+ subroutine init_unlimited(this)
+ class(*), intent(inout) :: this
+ !$acc enter data copyin(this)
+ select type(this)
+ type is(real)
+ !$acc enter data copyin(this)
+ class is(polyty)
+ !$acc enter data copyin(this, this%field)
+ end select
+ end subroutine
end module
! CHECK: Visiting: {{.*}} acc.copyin {{.*}} {name = "this", structured = false}
@@ -17,3 +31,16 @@ subroutine init(this)
! CHECK: Visiting: {{.*}} acc.copyin {{.*}} {name = "this%field", structured = false}
! CHECK: Pointer-like: !fir.ref<f32>
! CHECK: Type category: composite
+
+! For unlimited polymorphic entities and assumed types - they effectively have
+! no declared type. Thus the type categorizer cannot categorize it.
+! CHECK: Visiting: {{.*}} = acc.copyin {{.*}} {name = "var", structured = false}
+! CHECK: Pointer-like: !fir.ref<none>
+! CHECK: Type category: uncategorized
+! CHECK: Visiting: {{.*}} = acc.copyin {{.*}} {name = "this", structured = false}
+! CHECK: Mappable: !fir.class<none>
+! CHECK: Type category: uncategorized
+
+! TODO: After using select type - the appropriate type category should be
+! possible. Add the rest of the test once OpenACC lowering correctly handles
+! unlimited polymorhic.
>From 556ec643536b6ca9c23e350185729e892963e1f6 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Mon, 30 Jun 2025 13:25:03 -0700
Subject: [PATCH 4/4] Fix formatting
---
flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
index 11567d1c0c6a3..e72b96fe7cd10 100644
--- a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
+++ b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
@@ -15,7 +16,6 @@
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
#include "flang/Optimizer/Support/DataLayout.h"
-#include "mlir/Dialect/DLTI/DLTI.h"
using namespace mlir;
More information about the flang-commits
mailing list