Skip to content

[Flang][OpenMP] Use internal linkage for OpenMP code-gen'ed helper functions #117911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 28, 2024

Conversation

mjklemm
Copy link
Contributor

@mjklemm mjklemm commented Nov 27, 2024

When compiling WORKSHARE construct in different compilation units, a linker error happened, when two equal WORKSHARE constructs with a copy operation have been compiled:

/usr/bin/ld: module2.o: in function `_workshare_copy_f64':
FIRModule:(.text+0x0): multiple definition of `_workshare_copy_f64'; module1.o:FIRModule:(.text+0x0): first defined here

Reason is that the generate copy function has the wrong linkage:

0000000000000000 T _workshare_copy_f64

while it should be

0000000000000000 t _workshare_copy_f64

@mjklemm mjklemm requested a review from ivanradanov November 27, 2024 18:03
@mjklemm mjklemm self-assigned this Nov 27, 2024
@mjklemm mjklemm requested a review from tblah November 27, 2024 18:03
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp labels Nov 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2024

@llvm/pr-subscribers-flang-fir-hlfir

@llvm/pr-subscribers-flang-openmp

Author: Michael Klemm (mjklemm)

Changes

When compiling WORKSHARE construct in different compilation units, a linker error happened, when two equal WORKSHARE constructs with a copy operation have been compiled:

/usr/bin/ld: module2.o: in function `_workshare_copy_f64':
FIRModule:(.text+0x0): multiple definition of `_workshare_copy_f64'; module1.o:FIRModule:(.text+0x0): first defined here

Reason is that the generate copy function has the wrong linkage:

0000000000000000 T _workshare_copy_f64

while it should be

0000000000000000 t _workshare_copy_f64

Full diff: https://github.com/llvm/llvm-project/pull/117911.diff

6 Files Affected:

  • (modified) flang/lib/Lower/OpenMP/ClauseProcessor.cpp (+1)
  • (modified) flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp (+2)
  • (modified) flang/test/Integration/OpenMP/copyprivate.f90 (+17-17)
  • (modified) flang/test/Lower/OpenMP/copyprivate.f90 (+1-1)
  • (modified) flang/test/Lower/OpenMP/copyprivate2.f90 (+4-2)
  • (modified) flang/test/Transforms/OpenMP/lower-workshare-alloca.mlir (+2-1)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 6baa22a44eafb1..ace21c1be551d2 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -744,6 +744,7 @@ createCopyFunc(mlir::Location loc, lower::AbstractConverter &converter,
   mlir::func::FuncOp funcOp =
       modBuilder.create<mlir::func::FuncOp>(loc, copyFuncName, funcType);
   funcOp.setVisibility(mlir::SymbolTable::Visibility::Private);
+  fir::factory::setInternalLinkage(funcOp);
   builder.createBlock(&funcOp.getRegion(), funcOp.getRegion().end(), argsTy,
                       {loc, loc});
   builder.setInsertionPointToStart(&funcOp.getRegion().back());
diff --git a/flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp b/flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp
index 6e130a96eb8dd3..27a57f73d4e976 100644
--- a/flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp
+++ b/flang/lib/Optimizer/OpenMP/LowerWorkshare.cpp
@@ -153,6 +153,7 @@ static mlir::func::FuncOp createCopyFunc(mlir::Location loc, mlir::Type varType,
 
   if (auto decl = module.lookupSymbol<mlir::func::FuncOp>(copyFuncName))
     return decl;
+
   // create function
   mlir::OpBuilder::InsertionGuard guard(builder);
   mlir::OpBuilder modBuilder(module.getBodyRegion());
@@ -161,6 +162,7 @@ static mlir::func::FuncOp createCopyFunc(mlir::Location loc, mlir::Type varType,
   mlir::func::FuncOp funcOp =
       modBuilder.create<mlir::func::FuncOp>(loc, copyFuncName, funcType);
   funcOp.setVisibility(mlir::SymbolTable::Visibility::Private);
+  fir::factory::setInternalLinkage(funcOp);
   builder.createBlock(&funcOp.getRegion(), funcOp.getRegion().end(), argsTy,
                       {loc, loc});
   builder.setInsertionPointToStart(&funcOp.getRegion().back());
diff --git a/flang/test/Integration/OpenMP/copyprivate.f90 b/flang/test/Integration/OpenMP/copyprivate.f90
index d32319a18c28bb..7c5889e85e5be0 100644
--- a/flang/test/Integration/OpenMP/copyprivate.f90
+++ b/flang/test/Integration/OpenMP/copyprivate.f90
@@ -8,24 +8,24 @@
 
 !RUN: %flang_fc1 -emit-llvm -fopenmp %s -o - | FileCheck %s
 
-!CHECK-DAG: define void @_copy_box_Uxi32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_10xi32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_i64(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_box_Uxi64(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_f32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_2x3xf32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_z32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_10xz32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_l32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_5xl32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_c8x8(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_10xc8x8(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_c16x5(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_rec__QFtest_typesTdt(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_box_heap_Uxi32(ptr %{{.*}}, ptr %{{.*}})
-!CHECK-DAG: define void @_copy_box_ptr_Uxc8x9(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_box_Uxi32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_10xi32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_i64(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_box_Uxi64(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_f32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_2x3xf32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_z32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_10xz32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_l32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_5xl32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_c8x8(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_10xc8x8(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_c16x5(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_rec__QFtest_typesTdt(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_box_heap_Uxi32(ptr %{{.*}}, ptr %{{.*}})
+!CHECK-DAG: define internal void @_copy_box_ptr_Uxc8x9(ptr %{{.*}}, ptr %{{.*}})
 
-!CHECK-LABEL: define void @_copy_i32(
+!CHECK-LABEL: define internal void @_copy_i32(
 !CHECK-SAME:                         ptr %[[DST:.*]], ptr %[[SRC:.*]]){{.*}} {
 !CHECK-NEXT:    %[[SRC_VAL:.*]] = load i32, ptr %[[SRC]]
 !CHECK-NEXT:    store i32 %[[SRC_VAL]], ptr %[[DST]]
diff --git a/flang/test/Lower/OpenMP/copyprivate.f90 b/flang/test/Lower/OpenMP/copyprivate.f90
index 3f72343be666a9..761e6190ed6efc 100644
--- a/flang/test/Lower/OpenMP/copyprivate.f90
+++ b/flang/test/Lower/OpenMP/copyprivate.f90
@@ -31,7 +31,7 @@
 !CHECK-DAG: func private @_copy_box_ptr_Uxc8x9(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,9>>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,9>>>>>)
 
 !CHECK-LABEL: func private @_copy_i32(
-!CHECK-SAME:                  %[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>) {
+!CHECK-SAME:                  %[[ARG0:.*]]: !fir.ref<i32>, %[[ARG1:.*]]: !fir.ref<i32>) attributes {llvm.linkage = #llvm.linkage<internal>} {
 !CHECK-NEXT:    %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_copy_i32_dst"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 !CHECK-NEXT:    %[[SRC:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_copy_i32_src"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 !CHECK-NEXT:    %[[SRC_VAL:.*]] = fir.load %[[SRC]]#0 : !fir.ref<i32>
diff --git a/flang/test/Lower/OpenMP/copyprivate2.f90 b/flang/test/Lower/OpenMP/copyprivate2.f90
index 848ebe39e45f46..3412ba2c63c4d0 100644
--- a/flang/test/Lower/OpenMP/copyprivate2.f90
+++ b/flang/test/Lower/OpenMP/copyprivate2.f90
@@ -3,7 +3,8 @@
 
 !CHECK-LABEL: func private @_copy_box_ptr_i32(
 !CHECK-SAME:                  %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>,
-!CHECK-SAME:                  %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>) {
+!CHECK-SAME:                  %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>)
+!CHECK-SAME:                  attributes {llvm.linkage = #llvm.linkage<internal>} {
 !CHECK-NEXT:    %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<pointer>,
 !CHECK-SAME:      uniq_name = "_copy_box_ptr_i32_dst"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) ->
 !CHECK-SAME:      (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
@@ -17,7 +18,8 @@
 
 !CHECK-LABEL: func private @_copy_box_heap_Uxi32(
 !CHECK-SAME:        %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>,
-!CHECK-SAME:        %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) {
+!CHECK-SAME:        %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
+!CHECK-SAME:        attributes {llvm.linkage = #llvm.linkage<internal>} {
 !CHECK-NEXT:    %[[DST:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<allocatable>,
 !CHECK-SAME:      uniq_name = "_copy_box_heap_Uxi32_dst"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) ->
 !CHECK-SAME:      (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
diff --git a/flang/test/Transforms/OpenMP/lower-workshare-alloca.mlir b/flang/test/Transforms/OpenMP/lower-workshare-alloca.mlir
index 12b0558d06ed58..82daa142042a30 100644
--- a/flang/test/Transforms/OpenMP/lower-workshare-alloca.mlir
+++ b/flang/test/Transforms/OpenMP/lower-workshare-alloca.mlir
@@ -22,7 +22,8 @@ func.func @wsfunc() {
 
 // CHECK-LABEL:   func.func private @_workshare_copy_i32(
 // CHECK-SAME:                                           %[[VAL_0:.*]]: !fir.ref<i32>,
-// CHECK-SAME:                                           %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK-SAME:                                           %[[VAL_1:.*]]: !fir.ref<i32>)
+// CHECK-SAME:                   attributes {llvm.linkage = #llvm.linkage<internal>} {
 // CHECK:           %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
 // CHECK:           fir.store %[[VAL_2]] to %[[VAL_0]] : !fir.ref<i32>
 // CHECK:           return

Copy link
Contributor

@NimishMishra NimishMishra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix

@@ -153,6 +153,7 @@ static mlir::func::FuncOp createCopyFunc(mlir::Location loc, mlir::Type varType,

if (auto decl = module.lookupSymbol<mlir::func::FuncOp>(copyFuncName))
return decl;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray newline?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really stray, but it felt like more readable. :-)

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

@mjklemm mjklemm force-pushed the omp-workshare-duplicate-symbols branch from 21aeefe to 645da71 Compare November 28, 2024 09:03
@mjklemm mjklemm merged commit 261a402 into llvm:main Nov 28, 2024
8 checks passed
@mjklemm mjklemm deleted the omp-workshare-duplicate-symbols branch November 28, 2024 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang:openmp flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants