[flang-commits] [flang] [flang][cuda] Add extra constructor option to CUFAddConstructor (PR #225181)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Tue Sep 22 12:49:15 PDT 2026


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/225181

>From df83bcb25ceb2c32ec8a37658d96eb93cffa944a Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 21 Sep 2026 12:58:56 -0700
Subject: [PATCH 1/4] [flang][cuda] Add extra constructor option to
 CUFAddConstructor

---
 .../flang/Optimizer/Transforms/Passes.h       |  1 +
 .../flang/Optimizer/Transforms/Passes.td      |  7 ++-
 .../Transforms/CUDA/CUFAddConstructor.cpp     | 60 ++++++++++++++++---
 .../test/Fir/CUDA/cuda-constructor-extra.fir  | 36 +++++++++++
 4 files changed, 96 insertions(+), 8 deletions(-)
 create mode 100644 flang/test/Fir/CUDA/cuda-constructor-extra.fir

diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index 83aef1e8fdb550..5271d17514ddcf 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -14,6 +14,7 @@
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassRegistry.h"
 #include <memory>
+#include <utility>
 
 namespace mlir {
 class IRMapping;
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 653f4907157075..0bb2aacc61d756 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -634,7 +634,12 @@ def CUFAddConstructor : Pass<"cuf-add-constructor", "mlir::ModuleOp"> {
     Option<"emitCudaCompiled", "emit-cuda-compiled", "bool",
            /*default=*/"false",
            "Declare an undefined cuda_compiled symbol so linking without the "
-           "CUDA Fortran runtime fails with a clear diagnostic.">
+           "CUDA Fortran runtime fails with a clear diagnostic.">,
+    ListOption<"extraConstructors", "extra-constructors",
+               "std::pair<std::string, bool>",
+               "Constructors to add to llvm.mlir.global_ctors. Entries use "
+               "<name>:<if-main>, where if-main is true to add the function "
+               "only when the module contains the Fortran program entry.">
   ];
 }
 
diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
index 4f6613bc8017f4..b00f05b9fd3a8d 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
@@ -28,6 +28,46 @@
 #include "mlir/IR/Value.h"
 #include "mlir/Pass/Pass.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <string>
+#include <utility>
+
+namespace llvm::cl {
+template <>
+class parser<std::pair<std::string, bool>>
+    : public basic_parser<std::pair<std::string, bool>> {
+public:
+  parser(Option &option) : basic_parser(option) {}
+
+  bool parse(Option &option, StringRef argName, StringRef arg,
+             std::pair<std::string, bool> &value) {
+    auto [name, flagStr] = arg.rsplit(':');
+    if (name.empty() || flagStr.empty())
+      return option.error("expected <name>:<bool>", argName);
+
+    bool ifMain = false;
+    if (flagStr.equals_insensitive("true") || flagStr == "1")
+      ifMain = true;
+    else if (flagStr.equals_insensitive("false") || flagStr == "0")
+      ifMain = false;
+    else
+      return option.error("invalid boolean in extra constructor mapping",
+                          argName);
+
+    value = {name.str(), ifMain};
+    return false;
+  }
+
+  StringRef getValueName() const override { return "name:bool"; }
+
+  static void print(raw_ostream &os,
+                    const std::pair<std::string, bool> &value) {
+    os << value.first << ':' << (value.second ? "true" : "false");
+  }
+};
+} // namespace llvm::cl
 
 namespace fir {
 #define GEN_PASS_DEF_CUFADDCONSTRUCTOR
@@ -321,10 +361,10 @@ struct CUFAddConstructor
     // Create the constructor function that call CUFRegisterAllocator.
     builder.setInsertionPointToEnd(mod.getBody());
     mlir::LLVM::GlobalOp cudaCompiledGlobal;
-    // Only the program unit needs the link-time CUDA Fortran runtime check.
-    bool emitCudaCompiledMarker =
-        emitCudaCompiled &&
+    bool hasProgramEntry =
         symTab.lookup<mlir::func::FuncOp>(fir::NameUniquer::doProgramEntry());
+    // Only the program unit needs the link-time CUDA Fortran runtime check.
+    bool emitCudaCompiledMarker = emitCudaCompiled && hasProgramEntry;
     if (emitCudaCompiledMarker) {
       // Undefined sentinel: objects compiled as CUDA Fortran reference this
       // symbol so linking without the CUDA Fortran runtime produces
@@ -497,12 +537,18 @@ struct CUFAddConstructor
     // created and adds new functions.
     builder.setInsertionPointToEnd(mod.getBody());
     llvm::SmallVector<mlir::Attribute> funcs;
-    funcs.push_back(
-        mlir::FlatSymbolRefAttr::get(mod.getContext(), func.getSymName()));
     llvm::SmallVector<int> priorities;
     llvm::SmallVector<mlir::Attribute> data;
-    priorities.push_back(priority);
-    data.push_back(mlir::LLVM::ZeroAttr::get(mod.getContext()));
+    auto addCtor = [&](llvm::StringRef name) {
+      funcs.push_back(mlir::FlatSymbolRefAttr::get(mod.getContext(), name));
+      priorities.push_back(priority);
+      data.push_back(mlir::LLVM::ZeroAttr::get(mod.getContext()));
+    };
+    addCtor(func.getSymName());
+    for (const auto &[funcName, ifMain] : extraConstructors) {
+      if (!ifMain || hasProgramEntry)
+        addCtor(funcName);
+    }
     mlir::LLVM::GlobalCtorsOp::create(
         builder, mod.getLoc(), builder.getArrayAttr(funcs),
         builder.getI32ArrayAttr(priorities), builder.getArrayAttr(data));
diff --git a/flang/test/Fir/CUDA/cuda-constructor-extra.fir b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
new file mode 100644
index 00000000000000..47c0d5b041ee08
--- /dev/null
+++ b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
@@ -0,0 +1,36 @@
+// RUN: fir-opt --split-input-file --cuf-add-constructor="extra-constructors=foo:false,bar:true" %s | FileCheck %s
+
+// extra-constructors is a list of <name>:<if-main> pairs. if-main=false
+// always appends the function to llvm.mlir.global_ctors; if-main=true
+// appends it only when the module contains the Fortran program entry
+// (_QQmain). Each extra ctor reuses the same priority and #llvm.zero
+// data as the CUDA Fortran constructor.
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"} {
+  llvm.func @foo() {
+    llvm.return
+  }
+  llvm.func @bar() {
+    llvm.return
+  }
+}
+
+// CHECK: llvm.func internal @__cudaFortranConstructor()
+// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor, @foo], priorities = [0 : i32, 0 : i32], data = [#llvm.zero, #llvm.zero]
+
+// -----
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"} {
+  func.func @_QQmain() {
+    return
+  }
+  llvm.func @foo() {
+    llvm.return
+  }
+  llvm.func @bar() {
+    llvm.return
+  }
+}
+
+// CHECK: llvm.func internal @__cudaFortranConstructor()
+// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor, @foo, @bar], priorities = [0 : i32, 0 : i32, 0 : i32], data = [#llvm.zero, #llvm.zero, #llvm.zero]

>From 112c61ef782cf2e0d91a9962b16d0f2ded6a40e8 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 21 Sep 2026 13:35:02 -0700
Subject: [PATCH 2/4] Switch to call in ctor

---
 .../flang/Optimizer/Transforms/Passes.td      |  7 ++-
 .../Transforms/CUDA/CUFAddConstructor.cpp     | 32 +++++++----
 .../test/Fir/CUDA/cuda-constructor-extra.fir  | 55 ++++++++++++-------
 3 files changed, 60 insertions(+), 34 deletions(-)

diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 0bb2aacc61d756..9ed9f43f7f0441 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -637,9 +637,10 @@ def CUFAddConstructor : Pass<"cuf-add-constructor", "mlir::ModuleOp"> {
            "CUDA Fortran runtime fails with a clear diagnostic.">,
     ListOption<"extraConstructors", "extra-constructors",
                "std::pair<std::string, bool>",
-               "Constructors to add to llvm.mlir.global_ctors. Entries use "
-               "<name>:<if-main>, where if-main is true to add the function "
-               "only when the module contains the Fortran program entry.">
+               "Extra functions to declare and call from the CUDA Fortran "
+               "constructor. Entries use <name>:<if-main>, where if-main is "
+               "true to call the function only when the module contains the "
+               "Fortran program entry.">
   ];
 }
 
diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
index b00f05b9fd3a8d..dc1b1fc3dfc201 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
@@ -530,6 +530,24 @@ struct CUFAddConstructor
       mlir::LLVM::LoadOp::create(builder, loc, mlir::IntegerType::get(ctx, 8),
                                  addr, /*alignment=*/0, /*isVolatile=*/true);
     }
+
+    // The extra constructors are defined in a runtime library, so they are
+    // only declared here and called from the constructor: an entry in
+    // llvm.mlir.global_ctors requires a function with a definition.
+    for (const auto &[funcName, onlyWithProgramEntry] : extraConstructors) {
+      if (onlyWithProgramEntry && !hasProgramEntry)
+        continue;
+      if (!mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(funcName)) {
+        mlir::OpBuilder::InsertionGuard guard(builder);
+        builder.setInsertionPointToEnd(mod.getBody());
+        auto extraFuncOp =
+            mlir::LLVM::LLVMFuncOp::create(builder, loc, funcName, funcTy);
+        extraFuncOp.setVisibility(mlir::SymbolTable::Visibility::Private);
+      }
+      mlir::LLVM::CallOp::create(builder, loc, funcTy,
+                                 mlir::SymbolRefAttr::get(ctx, funcName));
+    }
+
     mlir::LLVM::ReturnOp::create(builder, loc, mlir::ValueRange{});
 
     // Create the llvm.global_ctor with the function.
@@ -537,18 +555,12 @@ struct CUFAddConstructor
     // created and adds new functions.
     builder.setInsertionPointToEnd(mod.getBody());
     llvm::SmallVector<mlir::Attribute> funcs;
+    funcs.push_back(
+        mlir::FlatSymbolRefAttr::get(mod.getContext(), func.getSymName()));
     llvm::SmallVector<int> priorities;
     llvm::SmallVector<mlir::Attribute> data;
-    auto addCtor = [&](llvm::StringRef name) {
-      funcs.push_back(mlir::FlatSymbolRefAttr::get(mod.getContext(), name));
-      priorities.push_back(priority);
-      data.push_back(mlir::LLVM::ZeroAttr::get(mod.getContext()));
-    };
-    addCtor(func.getSymName());
-    for (const auto &[funcName, ifMain] : extraConstructors) {
-      if (!ifMain || hasProgramEntry)
-        addCtor(funcName);
-    }
+    priorities.push_back(priority);
+    data.push_back(mlir::LLVM::ZeroAttr::get(mod.getContext()));
     mlir::LLVM::GlobalCtorsOp::create(
         builder, mod.getLoc(), builder.getArrayAttr(funcs),
         builder.getI32ArrayAttr(priorities), builder.getArrayAttr(data));
diff --git a/flang/test/Fir/CUDA/cuda-constructor-extra.fir b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
index 47c0d5b041ee08..219be56a0b13bf 100644
--- a/flang/test/Fir/CUDA/cuda-constructor-extra.fir
+++ b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
@@ -1,22 +1,20 @@
 // RUN: fir-opt --split-input-file --cuf-add-constructor="extra-constructors=foo:false,bar:true" %s | FileCheck %s
 
-// extra-constructors is a list of <name>:<if-main> pairs. if-main=false
-// always appends the function to llvm.mlir.global_ctors; if-main=true
-// appends it only when the module contains the Fortran program entry
-// (_QQmain). Each extra ctor reuses the same priority and #llvm.zero
-// data as the CUDA Fortran constructor.
+// extra-constructors is a list of <name>:<if-main> pairs. The functions are
+// declared and called from __cudaFortranConstructor, since they are defined
+// in a runtime library. if-main=false always calls the function; if-main=true
+// calls it only when the module contains the Fortran program entry (_QQmain).
 
 module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"} {
-  llvm.func @foo() {
-    llvm.return
-  }
-  llvm.func @bar() {
-    llvm.return
-  }
 }
 
-// CHECK: llvm.func internal @__cudaFortranConstructor()
-// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor, @foo], priorities = [0 : i32, 0 : i32], data = [#llvm.zero, #llvm.zero]
+// CHECK: llvm.func internal @__cudaFortranConstructor() {
+// CHECK:   llvm.call @foo() : () -> ()
+// CHECK-NOT: llvm.call @bar()
+// CHECK:   llvm.return
+// CHECK: }
+// CHECK: llvm.func @foo() attributes {sym_visibility = "private"}
+// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor], priorities = [0 : i32], data = [#llvm.zero]
 
 // -----
 
@@ -24,13 +22,28 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<
   func.func @_QQmain() {
     return
   }
-  llvm.func @foo() {
-    llvm.return
-  }
-  llvm.func @bar() {
-    llvm.return
-  }
 }
 
-// CHECK: llvm.func internal @__cudaFortranConstructor()
-// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor, @foo, @bar], priorities = [0 : i32, 0 : i32, 0 : i32], data = [#llvm.zero, #llvm.zero, #llvm.zero]
+// CHECK: llvm.func internal @__cudaFortranConstructor() {
+// CHECK:   llvm.call @foo() : () -> ()
+// CHECK:   llvm.call @bar() : () -> ()
+// CHECK:   llvm.return
+// CHECK: }
+// CHECK-DAG: llvm.func @foo() attributes {sym_visibility = "private"}
+// CHECK-DAG: llvm.func @bar() attributes {sym_visibility = "private"}
+// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor], priorities = [0 : i32], data = [#llvm.zero]
+
+// -----
+
+// An existing declaration is reused rather than declared a second time.
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"} {
+  llvm.func @foo()
+}
+
+// CHECK: llvm.func @foo()
+// CHECK-NOT: llvm.func @foo()
+// CHECK: llvm.func internal @__cudaFortranConstructor() {
+// CHECK:   llvm.call @foo() : () -> ()
+// CHECK:   llvm.return
+// CHECK: }

>From 1f5ae505a51efd4db655b2a3c947045c7e8af564 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 21 Sep 2026 20:06:44 -0700
Subject: [PATCH 3/4] Address comments

---
 flang/include/flang/Optimizer/Transforms/Passes.td    | 11 +++++++----
 .../Optimizer/Transforms/CUDA/CUFAddConstructor.cpp   | 11 +++++++----
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 9ed9f43f7f0441..619f44e53bac5f 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -636,11 +636,14 @@ def CUFAddConstructor : Pass<"cuf-add-constructor", "mlir::ModuleOp"> {
            "Declare an undefined cuda_compiled symbol so linking without the "
            "CUDA Fortran runtime fails with a clear diagnostic.">,
     ListOption<"extraConstructors", "extra-constructors",
-               "std::pair<std::string, bool>",
+               "std::string",
                "Extra functions to declare and call from the CUDA Fortran "
-               "constructor. Entries use <name>:<if-main>, where if-main is "
-               "true to call the function only when the module contains the "
-               "Fortran program entry.">
+               "constructor.">,
+   ListOption<"entryOnlyConstructors", "entry-only-constructors",
+               "std::string",
+               "Extra functions to declare and call from the CUDA Fortran "
+               "constructor only if the entry function is present.">
+
   ];
 }
 
diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
index dc1b1fc3dfc201..302e59ded5947a 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
@@ -534,18 +534,21 @@ struct CUFAddConstructor
     // The extra constructors are defined in a runtime library, so they are
     // only declared here and called from the constructor: an entry in
     // llvm.mlir.global_ctors requires a function with a definition.
-    for (const auto &[funcName, onlyWithProgramEntry] : extraConstructors) {
-      if (onlyWithProgramEntry && !hasProgramEntry)
-        continue;
+    auto addExtraConstructor = [&](const std::string &funcName) {
       if (!mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(funcName)) {
         mlir::OpBuilder::InsertionGuard guard(builder);
         builder.setInsertionPointToEnd(mod.getBody());
         auto extraFuncOp =
             mlir::LLVM::LLVMFuncOp::create(builder, loc, funcName, funcTy);
-        extraFuncOp.setVisibility(mlir::SymbolTable::Visibility::Private);
       }
       mlir::LLVM::CallOp::create(builder, loc, funcTy,
                                  mlir::SymbolRefAttr::get(ctx, funcName));
+    };
+    for (const auto &funcName : extraConstructors)
+      addExtraConstructor(funcName);
+    for (const auto &funcName : entryOnlyConstructors) {
+      if (hasProgramEntry)
+        addExtraConstructor(funcName);
     }
 
     mlir::LLVM::ReturnOp::create(builder, loc, mlir::ValueRange{});

>From b2819d1ad1006f17dd21c02cc2ca8a7ad8330c3f Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Tue, 22 Sep 2026 12:48:38 -0700
Subject: [PATCH 4/4] Fix test

---
 flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp | 3 +--
 flang/test/Fir/CUDA/cuda-constructor-extra.fir            | 8 ++++----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
index 302e59ded5947a..6d60868c570446 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
@@ -538,8 +538,7 @@ struct CUFAddConstructor
       if (!mod.lookupSymbol<mlir::LLVM::LLVMFuncOp>(funcName)) {
         mlir::OpBuilder::InsertionGuard guard(builder);
         builder.setInsertionPointToEnd(mod.getBody());
-        auto extraFuncOp =
-            mlir::LLVM::LLVMFuncOp::create(builder, loc, funcName, funcTy);
+        mlir::LLVM::LLVMFuncOp::create(builder, loc, funcName, funcTy);
       }
       mlir::LLVM::CallOp::create(builder, loc, funcTy,
                                  mlir::SymbolRefAttr::get(ctx, funcName));
diff --git a/flang/test/Fir/CUDA/cuda-constructor-extra.fir b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
index 219be56a0b13bf..e69d145163f411 100644
--- a/flang/test/Fir/CUDA/cuda-constructor-extra.fir
+++ b/flang/test/Fir/CUDA/cuda-constructor-extra.fir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --cuf-add-constructor="extra-constructors=foo:false,bar:true" %s | FileCheck %s
+// RUN: fir-opt --split-input-file --cuf-add-constructor="extra-constructors=foo entry-only-constructors=bar" %s | FileCheck %s
 
 // extra-constructors is a list of <name>:<if-main> pairs. The functions are
 // declared and called from __cudaFortranConstructor, since they are defined
@@ -13,7 +13,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<
 // CHECK-NOT: llvm.call @bar()
 // CHECK:   llvm.return
 // CHECK: }
-// CHECK: llvm.func @foo() attributes {sym_visibility = "private"}
+// CHECK: llvm.func @foo()
 // CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor], priorities = [0 : i32], data = [#llvm.zero]
 
 // -----
@@ -29,8 +29,8 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<
 // CHECK:   llvm.call @bar() : () -> ()
 // CHECK:   llvm.return
 // CHECK: }
-// CHECK-DAG: llvm.func @foo() attributes {sym_visibility = "private"}
-// CHECK-DAG: llvm.func @bar() attributes {sym_visibility = "private"}
+// CHECK-DAG: llvm.func @foo()
+// CHECK-DAG: llvm.func @bar()
 // CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor], priorities = [0 : i32], data = [#llvm.zero]
 
 // -----



More information about the flang-commits mailing list