[flang-commits] [flang] [openacc][flang] full support to handle allocatable/pointer runtime declare-action calls in ACCDeclareActionConversion (PR #188055)

Susan Tan ス-ザン タン via flang-commits flang-commits at lists.llvm.org
Mon Mar 23 10:51:01 PDT 2026


https://github.com/SusanTan updated https://github.com/llvm/llvm-project/pull/188055

>From e8f2178499565a3f7270555902337e5cd1f4f42a Mon Sep 17 00:00:00 2001
From: Susan Tan <zujunt at nvidia.com>
Date: Mon, 23 Mar 2026 08:33:07 -0700
Subject: [PATCH 1/3] complete the set of runtime function calls

---
 .../Transforms/ACCDeclareActionConversion.cpp | 48 ++++++++++++++-----
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
index 45fff88036b66..af65abd6533f5 100644
--- a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
+++ b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
@@ -64,6 +64,7 @@
 #include "mlir/IR/Operation.h"
 #include "mlir/IR/Value.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/Support/Debug.h"
 
@@ -81,10 +82,35 @@ using namespace mlir;
 namespace {
 
 // Fortran runtime symbol names for pointer allocate/deallocate.
-static constexpr llvm::StringRef pointerAllocateName =
+static constexpr llvm::StringLiteral pointerAllocateName =
     RTNAME_STRING(PointerAllocate);
-static constexpr llvm::StringRef pointerDeallocateName =
+static constexpr llvm::StringLiteral pointerAllocateSourceName =
+    RTNAME_STRING(PointerAllocateSource);
+static constexpr llvm::StringLiteral pointerDeallocateName =
     RTNAME_STRING(PointerDeallocate);
+static constexpr llvm::StringLiteral pointerDeallocatePolymorphicName =
+    RTNAME_STRING(PointerDeallocatePolymorphic);
+static constexpr llvm::StringLiteral allocatableAllocateName =
+    RTNAME_STRING(AllocatableAllocate);
+static constexpr llvm::StringLiteral allocatableAllocateSourceName =
+    RTNAME_STRING(AllocatableAllocateSource);
+static constexpr llvm::StringLiteral allocatableDeallocateName =
+    RTNAME_STRING(AllocatableDeallocate);
+static constexpr llvm::StringLiteral allocatableDeallocatePolymorphicName =
+    RTNAME_STRING(AllocatableDeallocatePolymorphic);
+
+static bool isSupportedDeclareActionRuntime(llvm::StringRef funcName) {
+  return llvm::StringSwitch<bool>(funcName)
+      .Case(pointerAllocateName, true)
+      .Case(pointerAllocateSourceName, true)
+      .Case(pointerDeallocateName, true)
+      .Case(pointerDeallocatePolymorphicName, true)
+      .Case(allocatableAllocateName, true)
+      .Case(allocatableAllocateSourceName, true)
+      .Case(allocatableDeallocateName, true)
+      .Case(allocatableDeallocatePolymorphicName, true)
+      .Default(false);
+}
 
 class ACCDeclareActionConversion
     : public fir::acc::impl::ACCDeclareActionConversionBase<
@@ -152,16 +178,16 @@ class ACCDeclareActionConversion
                       if (auto callee = call.getCalleeAttr()) {
                         StringRef funcName =
                             callee.getLeafReference().getValue();
-                        if (funcName == pointerAllocateName ||
-                            funcName == pointerDeallocateName) {
-                          auto args = call.getArgs();
-                          if (args.empty())
-                            return {};
-                          Value boxRef = args[0];
-                          if (!fir::isBoxAddress(boxRef.getType()))
-                            return {};
-                          return boxRef;
+                        if (!isSupportedDeclareActionRuntime(funcName)) {
+                          return {};
                         }
+                        auto args = call.getArgs();
+                        if (args.empty())
+                          return {};
+                        Value boxRef = args[0];
+                        if (!fir::isBoxAddress(boxRef.getType()))
+                          return {};
+                        return boxRef;
                       }
                       return {};
                     })

>From 5100e05542eb490cecb78c2f1ca8aa8e17de81ce Mon Sep 17 00:00:00 2001
From: Susan Tan <zujunt at nvidia.com>
Date: Mon, 23 Mar 2026 08:53:11 -0700
Subject: [PATCH 2/3] add test

---
 .../Fir/OpenACC/declare-action-conversion.fir | 74 +++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/flang/test/Fir/OpenACC/declare-action-conversion.fir b/flang/test/Fir/OpenACC/declare-action-conversion.fir
index b7f4ce9648ca9..fe54dae0f5fb3 100644
--- a/flang/test/Fir/OpenACC/declare-action-conversion.fir
+++ b/flang/test/Fir/OpenACC/declare-action-conversion.fir
@@ -97,3 +97,77 @@ module {
 // CHECK: fir.store
 // CHECK: fir.call @_QMmmFsubEarr_acc_declare_update_desc_post_alloc(%[[DECLARE]])
 }
+
+// -----
+
+// Test declare_action on additional runtime calls supported by the pass.
+module {
+  func.func private @_QFdeclareAp_acc_declare_post_alloc_source(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) {
+    return
+  }
+  func.func private @_QFdeclareAp_acc_declare_post_dealloc_poly(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) {
+    return
+  }
+  func.func private @_QFdeclareAa_acc_declare_post_alloc(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+    return
+  }
+  func.func private @_QFdeclareAa_acc_declare_post_alloc_source(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+    return
+  }
+  func.func private @_QFdeclareAa_acc_declare_post_dealloc(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+    return
+  }
+  func.func private @_QFdeclareAa_acc_declare_post_dealloc_poly(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+    return
+  }
+
+  func.func @_QPsupported_runtime_calls() {
+    %pbox = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {uniq_name = "_QFdeclareEap"}
+    %pdecl = fir.declare %pbox {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdeclareEap"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+    %pcvt = fir.convert %pdecl : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+
+    %abox = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {uniq_name = "_QFdeclareEaa"}
+    %adecl = fir.declare %abox {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFdeclareEaa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+    %acvt = fir.convert %adecl : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+
+    %f = arith.constant false
+    %absent = fir.absent !fir.box<none>
+    %s_i8 = fir.zero_bits !fir.ref<i8>
+    %none_ref = fir.zero_bits !fir.ref<none>
+    %c4_i32 = arith.constant 4 : i32
+
+    fir.call @_FortranAPointerAllocateSource(%pcvt, %absent, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAp_acc_declare_post_alloc_source>} : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+    fir.call @_FortranAPointerDeallocatePolymorphic(%pcvt, %none_ref, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAp_acc_declare_post_dealloc_poly>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+
+    fir.call @_FortranAAllocatableAllocate(%acvt, %none_ref, %f, %absent, %s_i8, %c4_i32, %none_ref) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAa_acc_declare_post_alloc>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32, !fir.ref<none>) -> i32
+    fir.call @_FortranAAllocatableAllocateSource(%acvt, %absent, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postAlloc = @_QFdeclareAa_acc_declare_post_alloc_source>} : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+    fir.call @_FortranAAllocatableDeallocate(%acvt, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAa_acc_declare_post_dealloc>} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+    fir.call @_FortranAAllocatableDeallocatePolymorphic(%acvt, %none_ref, %f, %absent, %s_i8, %c4_i32) {acc.declare_action = #acc.declare_action<postDealloc = @_QFdeclareAa_acc_declare_post_dealloc_poly>} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+    return
+  }
+
+// CHECK-LABEL: func.func @_QPsupported_runtime_calls
+// CHECK: %[[PDECL:.*]] = fir.declare %{{.*}} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: %[[PCVT:.*]] = fir.convert %[[PDECL]] : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[ADECL:.*]] = fir.declare %{{.*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[ACVT:.*]] = fir.convert %[[ADECL]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: fir.call @_FortranAPointerAllocateSource(%[[PCVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAp_acc_declare_post_alloc_source(%[[PDECL]])
+// CHECK: fir.call @_FortranAPointerDeallocatePolymorphic(%[[PCVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAp_acc_declare_post_dealloc_poly(%[[PDECL]])
+// CHECK: fir.call @_FortranAAllocatableAllocate(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_alloc(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableAllocateSource(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_alloc_source(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableDeallocate(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_dealloc(%[[ADECL]])
+// CHECK: fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[ACVT]],
+// CHECK-NEXT: fir.call @_QFdeclareAa_acc_declare_post_dealloc_poly(%[[ADECL]])
+
+  func.func private @_FortranAPointerAllocateSource(!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+  func.func private @_FortranAPointerDeallocatePolymorphic(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+  func.func private @_FortranAAllocatableAllocate(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32, !fir.ref<none>) -> i32
+  func.func private @_FortranAAllocatableAllocateSource(!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+  func.func private @_FortranAAllocatableDeallocate(!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+  func.func private @_FortranAAllocatableDeallocatePolymorphic(!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+}

>From 79af79ebeb7a95db94d7dba954f44686431fd5db Mon Sep 17 00:00:00 2001
From: Susan Tan <zujunt at nvidia.com>
Date: Mon, 23 Mar 2026 08:58:25 -0700
Subject: [PATCH 3/3] remove brackets

---
 .../OpenACC/Transforms/ACCDeclareActionConversion.cpp          | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
index af65abd6533f5..ad233d0359e70 100644
--- a/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
+++ b/flang/lib/Optimizer/OpenACC/Transforms/ACCDeclareActionConversion.cpp
@@ -178,9 +178,8 @@ class ACCDeclareActionConversion
                       if (auto callee = call.getCalleeAttr()) {
                         StringRef funcName =
                             callee.getLeafReference().getValue();
-                        if (!isSupportedDeclareActionRuntime(funcName)) {
+                        if (!isSupportedDeclareActionRuntime(funcName))
                           return {};
-                        }
                         auto args = call.getArgs();
                         if (args.empty())
                           return {};



More information about the flang-commits mailing list