Skip to content

[flang] Change uniqueCGIdent separator from . to X #71338

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 3 commits into from
Nov 8, 2023

Conversation

fabianmcg
Copy link
Contributor

@fabianmcg fabianmcg commented Nov 5, 2023

Change the separator in the uniqueCGIdent method to X. This change is required to enable OpenMP offloading for the NVPTX target, as dots are not valid identifiers in PTX and uniqueCGIdent is used to mangle some literals. A follow up patch will add support for the NVPTX target.

Change the separator in the `uniqueCGIdent` method to `_`. This change is required
to enable OpenMP offloading for the NVPTX target, as dots are not valid identifiers
in PTX and `uniqueCGIdent` is used to mangle some literals. A follow up patch will
add support for the NVPTX target.
@llvmbot llvmbot added flang:driver flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp labels Nov 5, 2023
@llvmbot
Copy link
Member

llvmbot commented Nov 5, 2023

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-driver

Author: Fabian Mora (fabianmcg)

Changes

Change the separator in the uniqueCGIdent method to _. This change is required to enable OpenMP offloading for the NVPTX target, as dots are not valid identifiers in PTX and uniqueCGIdent is used to mangle some literals. A follow up patch will add support for the NVPTX target.


Patch is 168.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71338.diff

55 Files Affected:

  • (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+2-2)
  • (modified) flang/test/Driver/compiler_options.f90 (+1-1)
  • (modified) flang/test/Fir/array-value-copy-4.fir (+1-1)
  • (modified) flang/test/Fir/boxproc.fir (+7-7)
  • (modified) flang/test/Fir/polymorphic.fir (+2-2)
  • (modified) flang/test/Fir/target-rewrite-integer.fir (+2-2)
  • (modified) flang/test/Fir/target-rewrite-selective.fir (+2-2)
  • (modified) flang/test/Fir/tbaa-codegen2.fir (+2-2)
  • (modified) flang/test/Fir/tbaa.fir (+4-4)
  • (modified) flang/test/HLFIR/assign-codegen.fir (+1-1)
  • (modified) flang/test/HLFIR/boxchar_emboxing.f90 (+4-4)
  • (modified) flang/test/HLFIR/bufferize-destroy-for-derived.fir (+2-2)
  • (modified) flang/test/HLFIR/bufferize01.fir (+3-3)
  • (modified) flang/test/HLFIR/copy-in-out-codegen.fir (+1-1)
  • (modified) flang/test/HLFIR/elemental-codegen.fir (+1-1)
  • (modified) flang/test/HLFIR/get_length_codegen.fir (+3-3)
  • (modified) flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/assignment-intrinsics.f90 (+1-1)
  • (modified) flang/test/Lower/HLFIR/constant-character.f90 (+4-4)
  • (modified) flang/test/Lower/HLFIR/convert-mbox-to-value.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/structure-constructor.f90 (+20-20)
  • (modified) flang/test/Lower/HLFIR/user-defined-assignment.f90 (+2-2)
  • (modified) flang/test/Lower/HLFIR/vector-subscript-lhs.f90 (+1-1)
  • (modified) flang/test/Lower/Intrinsics/get_environment_variable.f90 (+4-4)
  • (modified) flang/test/Lower/Intrinsics/transfer.f90 (+4-4)
  • (modified) flang/test/Lower/Intrinsics/verify.f90 (+1-1)
  • (modified) flang/test/Lower/OpenMP/FIR/parallel-lastprivate-clause-scalar.f90 (+1-1)
  • (modified) flang/test/Lower/OpenMP/parallel-lastprivate-clause-scalar.f90 (+1-1)
  • (modified) flang/test/Lower/allocatable-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/allocatable-polymorphic.f90 (+7-7)
  • (modified) flang/test/Lower/array-character.f90 (+2-2)
  • (modified) flang/test/Lower/array-derived-assignments.f90 (+1-1)
  • (modified) flang/test/Lower/array-expression-slice-1.f90 (+20-20)
  • (modified) flang/test/Lower/array-expression.f90 (+2-2)
  • (modified) flang/test/Lower/call-implicit.f90 (+1-1)
  • (modified) flang/test/Lower/character-assignment.f90 (+1-1)
  • (modified) flang/test/Lower/character-substrings.f90 (+3-3)
  • (modified) flang/test/Lower/components.f90 (+1-1)
  • (modified) flang/test/Lower/entry-statement.f90 (+6-6)
  • (modified) flang/test/Lower/forall/forall-allocatable-2.f90 (+1-1)
  • (modified) flang/test/Lower/global-format-strings.f90 (+1-1)
  • (modified) flang/test/Lower/host-associated.f90 (+3-3)
  • (modified) flang/test/Lower/io-char-array.f90 (+1-1)
  • (modified) flang/test/Lower/io-item-list.f90 (+2-2)
  • (modified) flang/test/Lower/io-write.f90 (+1-1)
  • (modified) flang/test/Lower/namelist.f90 (+3-3)
  • (modified) flang/test/Lower/optional-value-caller.f90 (+2-2)
  • (modified) flang/test/Lower/pointer-references.f90 (+1-1)
  • (modified) flang/test/Lower/polymorphic.f90 (+1-1)
  • (modified) flang/test/Lower/read-write-buffer.f90 (+2-2)
  • (modified) flang/test/Lower/select-type-2.fir (+2-2)
  • (modified) flang/test/Lower/statement-function.f90 (+1-1)
  • (modified) flang/test/Lower/transformational-intrinsics.f90 (+1-1)
  • (modified) flang/test/Transforms/simplifyintrinsics.fir (+69-69)
  • (modified) flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp (+5-5)
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index 9010553e70f0e16..88b05079a8149d8 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -966,13 +966,13 @@ std::string fir::factory::uniqueCGIdent(llvm::StringRef prefix,
     llvm::SmallString<32> str;
     llvm::MD5::stringifyResult(result, str);
     std::string hashName = prefix.str();
-    hashName.append(".").append(str.c_str());
+    hashName.append("_").append(str.c_str());
     return fir::NameUniquer::doGenerated(hashName);
   }
   // "Short" identifiers use a reversible hex string
   std::string nm = prefix.str();
   return fir::NameUniquer::doGenerated(
-      nm.append(".").append(llvm::toHex(name)));
+      nm.append("_").append(llvm::toHex(name)));
 }
 
 mlir::Value fir::factory::locationToFilename(fir::FirOpBuilder &builder,
diff --git a/flang/test/Driver/compiler_options.f90 b/flang/test/Driver/compiler_options.f90
index c329a5033884bcf..e6dda75bee99363 100644
--- a/flang/test/Driver/compiler_options.f90
+++ b/flang/test/Driver/compiler_options.f90
@@ -1,6 +1,6 @@
 ! RUN: %flang -S -emit-llvm -o - %s | FileCheck %s
 ! Test communication of COMPILER_OPTIONS from flang-new to flang-new -fc1.
-! CHECK: [[OPTSVAR:@_QQcl\.[0-9a-f]+]] = {{[a-z]+}} constant [[[OPTSLEN:[0-9]+]] x i8] c"{{.*}}flang-new{{(\.exe)?}} -S -emit-llvm -o - {{.*}}compiler_options.f90"
+! CHECK: [[OPTSVAR:@_QQcl_[0-9a-f]+]] = {{[a-z]+}} constant [[[OPTSLEN:[0-9]+]] x i8] c"{{.*}}flang-new{{(\.exe)?}} -S -emit-llvm -o - {{.*}}compiler_options.f90"
 program main
     use ISO_FORTRAN_ENV, only: compiler_options
     implicit none
diff --git a/flang/test/Fir/array-value-copy-4.fir b/flang/test/Fir/array-value-copy-4.fir
index bf9ddc37dd5c29e..8af07a495b12049 100644
--- a/flang/test/Fir/array-value-copy-4.fir
+++ b/flang/test/Fir/array-value-copy-4.fir
@@ -38,7 +38,7 @@ func.func @_QMmodPsub1(%arg0: !fir.box<!fir.array<?x!fir.type<_QMmodTrec1{dat:!f
     %20 = fir.embox %19 : (!fir.ref<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
     %21 = fir.embox %18 : (!fir.ref<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
     fir.store %20 to %0 : !fir.ref<!fir.box<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>>
-    %22 = fir.address_of(@_QQcl.2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
+    %22 = fir.address_of(@_QQcl_2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
     %c9_i32 = arith.constant 9 : i32
     %23 = fir.convert %0 : (!fir.ref<!fir.box<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>>) -> !fir.ref<!fir.box<none>>
     %24 = fir.convert %21 : (!fir.box<!fir.type<_QMmodTrec1{dat:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.box<none>
diff --git a/flang/test/Fir/boxproc.fir b/flang/test/Fir/boxproc.fir
index 399aac6b7d0ac2f..b6cc9445ea60d48 100644
--- a/flang/test/Fir/boxproc.fir
+++ b/flang/test/Fir/boxproc.fir
@@ -33,7 +33,7 @@ func.func @_QPtest_proc_dummy() {
   %3 = fir.address_of(@_QFtest_proc_dummyPtest_proc_dummy_a) : (!fir.ref<i32>, !fir.ref<tuple<!fir.ref<i32>>>) -> ()
   %4 = fir.emboxproc %3, %1 : ((!fir.ref<i32>, !fir.ref<tuple<!fir.ref<i32>>>) -> (), !fir.ref<tuple<!fir.ref<i32>>>) -> !fir.boxproc<() -> ()>
   fir.call @_QPtest_proc_dummy_other(%4) : (!fir.boxproc<() -> ()>) -> ()
-  %5 = fir.address_of(@_QQcl.2E2F682E66393000) : !fir.ref<!fir.char<1,8>>
+  %5 = fir.address_of(@_QQcl_2E2F682E66393000) : !fir.ref<!fir.char<1,8>>
   %6 = fir.convert %5 : (!fir.ref<!fir.char<1,8>>) -> !fir.ref<i8>
   %7 = fir.call @_FortranAioBeginExternalListOutput(%c-1_i32, %6, %c5_i32) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
   %8 = fir.load %0 : !fir.ref<i32>
@@ -163,7 +163,7 @@ func.func @_QPtest_proc_dummy_char() {
   %4 = fir.convert %1 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,?>>
   %5 = fir.emboxchar %4, %c10 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
   fir.store %5 to %3 : !fir.ref<!fir.boxchar<1>>
-  %6 = fir.address_of(@_QQcl.486920746865726521) : !fir.ref<!fir.char<1,9>>
+  %6 = fir.address_of(@_QQcl_486920746865726521) : !fir.ref<!fir.char<1,9>>
   %7 = fir.convert %c9 : (index) -> i64
   %8 = fir.convert %1 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<i8>
   %9 = fir.convert %6 : (!fir.ref<!fir.char<1,9>>) -> !fir.ref<i8>
@@ -182,7 +182,7 @@ func.func @_QPtest_proc_dummy_char() {
   %18 = arith.subi %13, %c1 : index
   cf.br ^bb1(%17, %18 : index, index)
 ^bb3:  // pred: ^bb1
-  %19 = fir.address_of(@_QQcl.2E2F682E66393000) : !fir.ref<!fir.char<1,8>>
+  %19 = fir.address_of(@_QQcl_2E2F682E66393000) : !fir.ref<!fir.char<1,8>>
   %20 = fir.convert %19 : (!fir.ref<!fir.char<1,8>>) -> !fir.ref<i8>
   %21 = fir.call @_FortranAioBeginExternalListOutput(%c-1_i32, %20, %c6_i32) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
   %22 = fir.address_of(@_QFtest_proc_dummy_charPgen_message) : (!fir.ref<!fir.char<1,10>>, index, !fir.ref<tuple<!fir.boxchar<1>>>) -> !fir.boxchar<1>
@@ -242,7 +242,7 @@ func.func @_QPget_message(%arg0: !fir.ref<!fir.char<1,40>>, %arg1: index, %arg2:
   %c32_i8 = arith.constant 32 : i8
   %c0 = arith.constant 0 : index
   %0 = fir.convert %arg0 : (!fir.ref<!fir.char<1,40>>) -> !fir.ref<!fir.char<1,?>>
-  %1 = fir.address_of(@_QQcl.6D6573736167652069733A20) : !fir.ref<!fir.char<1,12>>
+  %1 = fir.address_of(@_QQcl_6D6573736167652069733A20) : !fir.ref<!fir.char<1,12>>
   %2 = fir.extract_value %arg2, [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
   %3 = fir.box_addr %2 : (!fir.boxproc<() -> ()>) -> (() -> ())
   %4 = fir.extract_value %arg2, [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> i64
@@ -297,18 +297,18 @@ func.func @_QPget_message(%arg0: !fir.ref<!fir.char<1,40>>, %arg1: index, %arg2:
   %40 = fir.emboxchar %0, %c40 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
   return %40 : !fir.boxchar<1>
 }
-fir.global linkonce @_QQcl.486920746865726521 constant : !fir.char<1,9> {
+fir.global linkonce @_QQcl_486920746865726521 constant : !fir.char<1,9> {
   %0 = fir.string_lit "Hi there!"(9) : !fir.char<1,9>
   fir.has_value %0 : !fir.char<1,9>
 }
 func.func private @llvm.memmove.p0.p0.i64(!fir.ref<i8>, !fir.ref<i8>, i64, i1)
-fir.global linkonce @_QQcl.2E2F682E66393000 constant : !fir.char<1,8> {
+fir.global linkonce @_QQcl_2E2F682E66393000 constant : !fir.char<1,8> {
   %0 = fir.string_lit "./h.f90\00"(8) : !fir.char<1,8>
   fir.has_value %0 : !fir.char<1,8>
 }
 func.func private @llvm.stacksave.p0() -> !fir.ref<i8>
 func.func private @llvm.stackrestore.p0(!fir.ref<i8>)
-fir.global linkonce @_QQcl.6D6573736167652069733A20 constant : !fir.char<1,12> {
+fir.global linkonce @_QQcl_6D6573736167652069733A20 constant : !fir.char<1,12> {
   %0 = fir.string_lit "message is: "(12) : !fir.char<1,12>
   fir.has_value %0 : !fir.char<1,12>
 }
diff --git a/flang/test/Fir/polymorphic.fir b/flang/test/Fir/polymorphic.fir
index 27333afabf849bf..5d1b7cb15a0d483 100644
--- a/flang/test/Fir/polymorphic.fir
+++ b/flang/test/Fir/polymorphic.fir
@@ -25,7 +25,7 @@ func.func @_QMpolymorphic_testPtest_allocate_unlimited_polymorphic_non_derived()
 func.func @_QMpolymorphic_testPtest_rebox() {
   %0 = fir.address_of(@_QFEx) : !fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>
   %c-1_i32 = arith.constant -1 : i32
-  %9 = fir.address_of(@_QQcl.2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
+  %9 = fir.address_of(@_QQcl_2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
   %10 = fir.convert %9 : (!fir.ref<!fir.char<1,12>>) -> !fir.ref<i8>
   %c8_i32 = arith.constant 8 : i32
   %11 = fir.call @_FortranAioBeginExternalListOutput(%c-1_i32, %10, %c8_i32) fastmath<contract> : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
@@ -119,7 +119,7 @@ fir.global internal @_QFEy target : !fir.array<1xi32> {
 func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref<i8>, i32) -> !fir.ref<i8> attributes {fir.io, fir.runtime}
 func.func private @_FortranAioOutputDescriptor(!fir.ref<i8>, !fir.box<none>) -> i1 attributes {fir.io, fir.runtime}
 func.func private @_FortranAioEndIoStatement(!fir.ref<i8>) -> i32 attributes {fir.io, fir.runtime}
-fir.global linkonce @_QQcl.2E2F64756D6D792E66393000 constant : !fir.char<1,12> {
+fir.global linkonce @_QQcl_2E2F64756D6D792E66393000 constant : !fir.char<1,12> {
   %0 = fir.string_lit "./dummy.f90\00"(12) : !fir.char<1,12>
   fir.has_value %0 : !fir.char<1,12>
 }
diff --git a/flang/test/Fir/target-rewrite-integer.fir b/flang/test/Fir/target-rewrite-integer.fir
index ad64ca80b47335b..9708e80375fc78b 100644
--- a/flang/test/Fir/target-rewrite-integer.fir
+++ b/flang/test/Fir/target-rewrite-integer.fir
@@ -23,7 +23,7 @@
 func.func @_QPtest_i1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "x"}) {
   %c3_i32 = arith.constant 3 : i32
   %c-1_i32 = arith.constant -1 : i32
-  %0 = fir.address_of(@_QQcl.2E2F746573742E66393000) : !fir.ref<!fir.char<1,11>>
+  %0 = fir.address_of(@_QQcl_2E2F746573742E66393000) : !fir.ref<!fir.char<1,11>>
   %1 = fir.convert %0 : (!fir.ref<!fir.char<1,11>>) -> !fir.ref<i8>
   %2 = fir.call @_FortranAioBeginExternalListOutput(%c-1_i32, %1, %c3_i32) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
   %3 = fir.load %arg0 : !fir.ref<!fir.logical<4>>
@@ -33,7 +33,7 @@ func.func @_QPtest_i1(%arg0: !fir.ref<!fir.logical<4>> {fir.bindc_name = "x"}) {
   return
 }
 func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref<i8>, i32) -> !fir.ref<i8> attributes {fir.io, fir.runtime}
-fir.global linkonce @_QQcl.2E2F746573742E66393000 constant : !fir.char<1,11> {
+fir.global linkonce @_QQcl_2E2F746573742E66393000 constant : !fir.char<1,11> {
   %0 = fir.string_lit "./test.f90\00"(11) : !fir.char<1,11>
   fir.has_value %0 : !fir.char<1,11>
 }
diff --git a/flang/test/Fir/target-rewrite-selective.fir b/flang/test/Fir/target-rewrite-selective.fir
index 4b54235d2d488b5..7a2938ecb3651be 100644
--- a/flang/test/Fir/target-rewrite-selective.fir
+++ b/flang/test/Fir/target-rewrite-selective.fir
@@ -41,7 +41,7 @@ module {
     fir.store %arg0 to %1 : !fir.ref<!fir.complex<4>>
     %2 = fir.alloca !fir.char<1,10> {bindc_name = "r", uniq_name = "_QFtestEr"}
     %3 = fir.alloca !fir.complex<4> {bindc_name = "test", uniq_name = "_QFtestEtest"}
-    %4 = fir.address_of(@_QQcl.) : !fir.ref<!fir.char<1,0>>
+    %4 = fir.address_of(@_QQcl_) : !fir.ref<!fir.char<1,0>>
     %5 = fir.convert %4 : (!fir.ref<!fir.char<1,0>>) -> !fir.ref<!fir.char<1,?>>
     %6 = fir.emboxchar %5, %c0 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
     %7 = fir.load %1 : !fir.ref<!fir.complex<4>>
@@ -59,7 +59,7 @@ module {
     return %15 : !fir.complex<4>
   }
   func.func private @_QPtest1(!fir.boxchar<1>, !fir.complex<4>) -> !fir.complex<4>
-  fir.global linkonce @_QQcl. constant : !fir.char<1,0> {
+  fir.global linkonce @_QQcl_ constant : !fir.char<1,0> {
     %0 = fir.string_lit ""(0) : !fir.char<1,0>
     fir.has_value %0 : !fir.char<1,0>
   }
diff --git a/flang/test/Fir/tbaa-codegen2.fir b/flang/test/Fir/tbaa-codegen2.fir
index f79a6108fb41e80..acf2a7b2d0fc408 100644
--- a/flang/test/Fir/tbaa-codegen2.fir
+++ b/flang/test/Fir/tbaa-codegen2.fir
@@ -39,7 +39,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
       fir.store %18 to %19 : !fir.ref<i32>
     }
     fir.store %2 to %0 : !fir.ref<!fir.box<!fir.array<?xi32>>>
-    %8 = fir.address_of(@_QQcl.2F746D702F73696D706C652E66393000) : !fir.ref<!fir.char<1,16>>
+    %8 = fir.address_of(@_QQcl_2F746D702F73696D706C652E66393000) : !fir.ref<!fir.char<1,16>>
     %9 = fir.convert %0 : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<none>>
     %10 = fir.convert %7 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
     %11 = fir.convert %8 : (!fir.ref<!fir.char<1,16>>) -> !fir.ref<i8>
@@ -54,7 +54,7 @@ module attributes {fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.targ
     return
   }
   func.func private @_FortranAAssign(!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none attributes {fir.runtime}
-  fir.global linkonce @_QQcl.2F746D702F73696D706C652E66393000 constant : !fir.char<1,16> {
+  fir.global linkonce @_QQcl_2F746D702F73696D706C652E66393000 constant : !fir.char<1,16> {
     %0 = fir.string_lit "/tmp/simple.f90\00"(16) : !fir.char<1,16>
     fir.has_value %0 : !fir.char<1,16>
   }
diff --git a/flang/test/Fir/tbaa.fir b/flang/test/Fir/tbaa.fir
index f8a7a6134ed112c..f54564cb7cce589 100644
--- a/flang/test/Fir/tbaa.fir
+++ b/flang/test/Fir/tbaa.fir
@@ -91,7 +91,7 @@ module {
     %c8_i32 = arith.constant 8 : i32
     %c-1_i32 = arith.constant -1 : i32
     %0 = fir.address_of(@_QFEx) : !fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>
-    %1 = fir.address_of(@_QQcl.2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
+    %1 = fir.address_of(@_QQcl_2E2F64756D6D792E66393000) : !fir.ref<!fir.char<1,12>>
     %2 = fir.convert %1 : (!fir.ref<!fir.char<1,12>>) -> !fir.ref<i8>
     %3 = fir.call @_FortranAioBeginExternalListOutput(%c-1_i32, %2, %c8_i32) fastmath<contract> : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
     %4 = fir.load %0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>
@@ -105,7 +105,7 @@ module {
   func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref<i8>, i32) -> !fir.ref<i8> attributes {fir.io, fir.runtime}
   func.func private @_FortranAioOutputDescriptor(!fir.ref<i8>, !fir.box<none>) -> i1 attributes {fir.io, fir.runtime}
   func.func private @_FortranAioEndIoStatement(!fir.ref<i8>) -> i32 attributes {fir.io, fir.runtime}
-  fir.global linkonce @_QQcl.2E2F64756D6D792E66393000 constant : !fir.char<1,12> {
+  fir.global linkonce @_QQcl_2E2F64756D6D792E66393000 constant : !fir.char<1,12> {
     %0 = fir.string_lit "./dummy.f90\00"(12) : !fir.char<1,12>
     fir.has_value %0 : !fir.char<1,12>
   }
@@ -131,7 +131,7 @@ module {
 // CHECK:           %[[VAL_5:.*]] = llvm.mlir.constant(8 : i32) : i32
 // CHECK:           %[[VAL_6:.*]] = llvm.mlir.constant(-1 : i32) : i32
 // CHECK:           %[[VAL_7:.*]] = llvm.mlir.addressof @_QFEx : !llvm.ptr
-// CHECK:           %[[VAL_8:.*]] = llvm.mlir.addressof @_QQcl.2E2F64756D6D792E66393000 : !llvm.ptr
+// CHECK:           %[[VAL_8:.*]] = llvm.mlir.addressof @_QQcl_2E2F64756D6D792E66393000 : !llvm.ptr
 // CHECK:           %[[VAL_10:.*]] = llvm.call @_FortranAioBeginExternalListOutput(%[[VAL_6]], %[[VAL_8]], %[[VAL_5]]) {fastmathFlags = #llvm.fastmath<contract>} : (i32, !llvm.ptr, i32) -> !llvm.ptr
 // CHECK:           %[[VAL_11:.*]] = llvm.load %[[VAL_7]] {tbaa = [#[[$BOXT]]]} : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>
 // CHECK:           llvm.store %[[VAL_11]], %[[VAL_3]] {tbaa = [#[[$BOXT]]]} : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr, array<1 x i64>)>, !llvm.ptr
@@ -192,7 +192,7 @@ module {
 // CHECK:         llvm.func @_FortranAioOutputDescriptor(!llvm.ptr, !llvm.ptr) -> i1 attributes {fir.io, fir.runtime, sym_visibility = "private"}
 // CHECK:         llvm.func @_FortranAioEndIoStatement(!llvm.ptr) -> i32 attributes {fir.io, fir.runtime, sym_visibility = "private"}
 
-// CHECK-LABEL:   llvm.mlir.global linkonce constant @_QQcl.2E2F64756D6D792E66393000() comdat(@__llvm_comdat::@_QQcl.2E2F64756D6D792E66393000) {addr_space = 0 : i32} : !llvm.array<12 x i8> {
+// CHECK-LABEL:   llvm.mlir.global linkonce constant @_QQcl_2E2F64756D6D792E66393000() comdat(@__llvm_comdat::@_QQcl_2E2F64756D6D792E66393000) {addr_space = 0 : i32} : !llvm.array<12 x i8> {
 // CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant("./dummy.f90\00") : !llvm.array<12 x i8>
 // CHECK:           llvm.return %[[VAL_0]] : !llvm.array<12 x i8>
 // CHECK:         }
diff --git a/flang/test/HLFIR/assign-codegen.fir b/flang/test/HLFIR/assign-codegen.fir
index 2211676eac58015..a4b34d8e3498b29 100644
--- a/flang/test/HLFIR/assign-codegen.fir
+++ b/flang/test/HLFIR/assign-codegen.fir
@@ -417,7 +417,7 @@ func.func @test_upoly_expr_assignment(%arg0: !fir.class<!fir.array<?xnone>> {fir
 // CHECK:             %[[VAL_21:.*]] = fir.array_coor %[[VAL_8]](%[[VAL_20]]) %[[VAL_17]] : (!fir.class<!fir.heap<!fir.array<?xnone>>>, !fir.shift<1>, index) -> !fir.ref<none>
 // CHECK:             %[[VAL_22:.*]] = fir.embox %[[VAL_21]] source_box %[[VAL_8]] : (!fir.ref<none>, !fir.class<!fir.heap<!fir.array<?xnone>>>) -> !fir.class<none>
 // CHECK:             fir.store %[[VAL_22]] to %[[VAL_1]] : !fir.ref<!fir.class<none>>
-// CHECK:             %[[VAL_23:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+// CHECK:             %[[VAL_23:.*]] = fir.address_of(@_QQcl_{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
 // CHECK:             %[[VAL_24:.*]] = arith.constant {{.*}} : index
 // CHECK:             %[[VAL_25:.*]] = arith.constant {{.*}} : i32
 // CHECK:             %[[VAL_26:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.class<none>>) -> !fir.ref<!fir.box<none>>
diff --git a/flang/test/HLFIR/boxchar_emboxing.f90 b/flang/test/HLFIR/boxchar_emboxing.f90
index 3a7671668afaf7a..d34abf6229b1310 100644
--- a/flang/test/HLFIR/boxchar_emboxing.f90
+++ b/flang/test/HLFIR/boxchar_emboxing.f90
@@ -15,9 +15,9 @@
 ! CHECK:           cf.br ^bb3
 ! CHECK:         ^bb2:
 ! CHECK:           %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]]#1 {uniq_name = "_QFtest1Ex"} : (!fir.class<none>) -> (!fir.class<none>, !fir.class<none>)
-! CHECK:           %[[VAL_9:.*]] = fir.address_of(@_QQcl.4641494C) : !fir.ref<!fir.char<1,4>>
+! CHECK:           %[[VAL_9:.*]] = fir.address_of(@_QQcl_4641494C) : !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_10:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]] typeparams %[[VAL_10]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQcl.4641494C"} : (!fir.ref<!fir.char<1,4>>, index) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
+! CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]] typeparams %[[VAL_10]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQcl_4641494C"} : (!fir.ref<!fir.char<1,4>>, index) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
 ! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_11]]#1 : (!fir.ref<!fir.char<1,4>>) -> !fir.ref<i8>
 ! CHECK:           %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (index) -> i64
 ! CHECK:           %[[VAL_14:.*]] = arith.constant false
@@ -59,9 +59,9 @@ end subroutine test1
 ! CHECK:           cf.br ^bb3
 ! CHECK:         ^bb2:
 ! CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_1]]#1 {uniq_name = "_QFtest2Ex"} : (!fir.class<!fir.array<10xnone>>) -> (!fir.class<!fir.array<10xnone>>, !fir.class<!fir.array<10xnone>>)
-! CHECK:           %[[VAL_11:.*]] = fir.address_of(@_QQcl.4641494C) : !fir.ref<!fir.char<1,4>>
+! CHECK:           %[[VAL_11:.*]] = fir.address_of(@_QQcl_4641494C) : !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_12:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]] typeparams %[[VAL_12]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQcl.4641494C"} : (!fir.ref<!fir.char<1,4>>, index) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
+! CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]] typeparams %[[VAL_12]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQcl_4641494C"} : (!fir.ref<!fir.char<1,4>>, index) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
 ! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_13]]#1 : (!fir.ref<!fir.char<1,4>>) -> !fir.ref<i8>
 ! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (index) -> i64
 ! CHECK:           %[[VAL_16:.*]] = arith.constant false
diff --git a/flang/test/HLFIR/bufferize-destroy-for-derived.fir b/flang/test/HLFIR/bufferize-destroy-for-derived.fir
index 5c12bc580cfeadb..a79bd680f00a0b6 100644
--- a/flang/test/HLFIR/bufferize-destroy-for-derived.fir
+++ b/flang/test/HLFIR/bufferize-destroy-for-derived.fir
@@ -52,7 +52,7 @@ func.func @_QPtest2(%arg0: !fir.box<!fir.array<?x!fir.type<_QMtypesTt2{x:!fir.bo
 // CHECK:             hlfir.assign %{{.*}}#0 to %{{.*}} temporary_lhs : !fir.ref<!fir.type<_QMtypesTt2{x:!fir.box<!fir.heap<f32>>}>>, !fir.ref<!fir.type<_QMtypesTt2{x:!fir.box<!fir.heap<f32>>}>>
 // CHECK:           hlfir.ass...
[truncated]

Copy link
Contributor

@kiranchandramohan kiranchandramohan 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 patch. Please wait for comments from others before proceeding.

@@ -966,13 +966,13 @@ std::string fir::factory::uniqueCGIdent(llvm::StringRef prefix,
llvm::SmallString<32> str;
llvm::MD5::stringifyResult(result, str);
std::string hashName = prefix.str();
hashName.append(".").append(str.c_str());
hashName.append("_").append(str.c_str());
return fir::NameUniquer::doGenerated(hashName);
}
// "Short" identifiers use a reversible hex string
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there some change required in the demangling code?

return fir::NameUniquer::doGenerated(hashName);
}
// "Short" identifiers use a reversible hex string
std::string nm = prefix.str();
return fir::NameUniquer::doGenerated(
nm.append(".").append(llvm::toHex(name)));
nm.append("_").append(llvm::toHex(name)));
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

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

Thanks, this looks good to me.

Thanks @kiranchandramohan for pointing out the documentation and demangling. The constant litteral name are "QQ" internal name that are not meant to be demangled to some symbol + scope, and we do not document the mangling of the internal QQ name (they do not really matter from a Fortran ABI point of view since constant literals should be local to compilation units). The documentation only mentions QQ is reserved for internal names, so it is still valid after this change.

@fabianmcg, note that I see at least a couple of other cases where dots may be emitted in assembly names.

@fabianmcg
Copy link
Contributor Author

note that I see at least a couple of other cases where dots may be emitted in assembly names.

@jeanPerier I was planning to split . -> _ changes into multiple patches, should I bundle all mangling changes in this patch?

@jeanPerier
Copy link
Contributor

If it makes things easier, I think a more generic solution could also be to deal with this when dealing with the target aspects of the IR in the stage that lowers FIR to LLVM IR like the ExternalNameConversion pass https://github.com/llvm/llvm-project/blob/main/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp.

FIR symbol names do not have to be the assembly names already (and are not in the case of external subroutine/common blocks).

Although I am OK with the character and array litteral change in FIR that you have, they do not change the complexity and readability. Dealing with the derived type descriptor data may be a bit more complex to avoid collision with user defined symbols. And yes, it is OK with me and better to split the patches since they are touching a lot of test files.

@vzakhari
Copy link
Contributor

vzakhari commented Nov 6, 2023

@fabianmcg, can you please clarify if it is a requirement that in the final host and device "images" the variables are named the same way? Will there be any RegisterVar call in the host code that takes the variable's device name?

@fabianmcg
Copy link
Contributor Author

fabianmcg commented Nov 6, 2023

@jeanPerier one option is adding a pass exclusive to NVPTX that renames symbols with dots. I just thought that having a uniform naming scheme was better, I'm open to other options.

@fabianmcg, can you please clarify if it is a requirement that in the final host and device "images" the variables are named the same way? Will there be any RegisterVar call in the host code that takes the variable's device name?

@vzakhari I'm not 100% sure. Strictly speaking, in LLVM IR there are no hard requirements and one only needs to refer to the correct name, so they can be named differently. However, I don't know if there are additional limitations imposed by the current implementation of the OMP dialect and the OpenMP IRbuilder.

One thing to mention is that this issue is not being caused by mapping of symbols, but instead by the addition of literals to the device module, with these literal having invalid identifiers.

@fabianmcg
Copy link
Contributor Author

@jdoerfert just pointed out that $ is a better option for offload identifiers as there is no possibilities of collision with user defined names -literals are never going to collide. I see 2 options:

  1. Change all separators to $ or some other valid separator for the sake of consistency.
  2. Adding a pass to change . in offload identifiers.

@jdoerfert
Copy link
Member

@jdoerfert just pointed out that $ is a better option for offload identifiers as there is no possibilities of collision with user defined names -literals are never going to collide. I see 2 options:

  1. Change all separators to $ or some other valid separator for the sake of consistency.
  2. Adding a pass to change . in offload identifiers.

Since QQ is reserved, we can use _ with QQ, assuming all use cases have QQ or some other way of preventing clashes.

Wrt. renaming late, I generally advise against. It makes tracing names across stages unnecessarily complicated. Consistent names (throughout the pipeline and across targets) makes tooling and debugging much easier.

@jeanPerier
Copy link
Contributor

Since QQ is reserved, we can use _ with QQ, assuming all use cases have QQ or some other way of preventing clashes.

The second case I mentioned above (derived type runtime description data) is read only data, but is not mangled with QQ currently because it is created by semantics as compiler created symbol in user scopes and is transparent in lowering. The '.' currently ensures they cannot collide with user symbols.

Regarding '$', are we sure that all assembly languages are OK with it? For instance, googling for some ISA, the IBM AIX Version 7.2 defines that "Symbols may consist of numeric digits, underscores, periods, uppercase or lowercase letters, or any
combination of these." (page 28 of https://www.ibm.com/docs/en/ssw_aix_72/assembler/assembler_pdf.pdf). I am not an expert, so I am not sure this matters, but before changing '.' to '$', it should be ensured it is valid on every llvm targets, or this should be target specific mangling/renaming.

@fabianmcg
Copy link
Contributor Author

Regarding '$', are we sure that all assembly languages are OK with it?

@jeanPerier that's a good point we'd end up circling back if we encounter $ is not valid in a given target. What about an upper case separator, or a series of upper case chars?

  1. . -> X ?
  2. . -> X_X ?

I'm suggesting X because I think it's not in use.

@jeanPerier
Copy link
Contributor

@jeanPerier that's a good point we'd end up circling back if we encounter $ is not valid in a given target. What about an upper case separator, or a series of upper case chars?
I'm suggesting X because I think it's not in use.

I think it is a good idea. Adding @vdonaldson here to double check that there will not be collisions with this strategy.

@vdonaldson
Copy link
Contributor

Given the discussion to this point, I'm inclined to favor X. That should avoid collisions.

The derived type info use case may be the most significant, the most common, and the most visible. There are likely a few other places that use . in compiler-generated symbol names beyond those already mentioned. There are two instances of .list suffixes in lib/Lower/IO.cpp. The first one is here.

@fabianmcg fabianmcg changed the title [flang] Change uniqueCGIdent separator from . to _ [flang] Change uniqueCGIdent separator from . to X Nov 8, 2023
@fabianmcg
Copy link
Contributor Author

Switched . to X, follow up patches will change the remainder of . appearances to X and updating the docs.

Copy link
Contributor

@jeanPerier jeanPerier 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 working on the issue and for the update. I think you may have forgotten to push the updated mangling doc to mention X is now used as a separator in internal names. Otherwise looks great.

Also, you may want to locally rebase and test your PR with check-flang before merging to ensure that no new tests with QQcl. made it in the main branch during the review.

@fabianmcg fabianmcg merged commit fd389f4 into llvm:main Nov 8, 2023
@fabianmcg fabianmcg deleted the flang_mangling branch November 8, 2023 20:16
georgestagg added a commit to r-wasm/llvm-project that referenced this pull request Dec 4, 2023
TODO: Include additional changes to unit tests
vzakhari added a commit to vzakhari/llvm-project that referenced this pull request Aug 19, 2024
This change addresses more "issues" as the one resolved in llvm#71338.
Some targets (e.g. NVPTX) do not accept global names containing
`.`. In particular, the global variables created to represent
the runtime information of derived types use `.` in their names.
A derived type's descriptor object may be used in the device code,
e.g. to initialize a descriptor of a variable of this type.
Thus, the runtime type info objects may need to be compiled
for the device.

Moreover, at least the derived types' descriptor objects
may need to be registered (think of `omp declare target`)
for the host-device association so that the addendum pointer
can be properly mapped to the device for descriptors using
a derived type's descriptor as their addendum pointer.
The registration implies knowing the name of the global variable
in the device image so that proper host code can be created.
So it is better to name the globals the same way for the host
and the device.

CompilerGeneratedNamesConversion pass renames all uniqued globals
such that the special symbols (currently `.`) are replaced
with `X`. The pass is supposed to be run for the host and the device.

An option is added to FIR-to-LLVM conversion pass to indicate
whether the new pass has been run before or not. This setting
affects how the codegen computes the names of the derived types'
descriptors for FIR derived types.

fir::NameUniquer now allows `X` to be part of a name, because
the name deconstruction may be applied to the mangled names
after CompilerGeneratedNamesConversion pass.
vzakhari added a commit that referenced this pull request Aug 21, 2024
This change addresses more "issues" as the one resolved in #71338.
Some targets (e.g. NVPTX) do not accept global names containing
`.`. In particular, the global variables created to represent
the runtime information of derived types use `.` in their names.
A derived type's descriptor object may be used in the device code,
e.g. to initialize a descriptor of a variable of this type.
Thus, the runtime type info objects may need to be compiled
for the device.

Moreover, at least the derived types' descriptor objects
may need to be registered (think of `omp declare target`)
for the host-device association so that the addendum pointer
can be properly mapped to the device for descriptors using
a derived type's descriptor as their addendum pointer.
The registration implies knowing the name of the global variable
in the device image so that proper host code can be created.
So it is better to name the globals the same way for the host
and the device.

CompilerGeneratedNamesConversion pass renames all uniqued globals
such that the special symbols (currently `.`) are replaced
with `X`. The pass is supposed to be run for the host and the device.

An option is added to FIR-to-LLVM conversion pass to indicate
whether the new pass has been run before or not. This setting
affects how the codegen computes the names of the derived types'
descriptors for FIR derived types.

fir::NameUniquer now allows `X` to be part of a name, because
the name deconstruction may be applied to the mangled names
after CompilerGeneratedNamesConversion pass.
cjdb pushed a commit to cjdb/llvm-project that referenced this pull request Aug 23, 2024
…04859)

This change addresses more "issues" as the one resolved in llvm#71338.
Some targets (e.g. NVPTX) do not accept global names containing
`.`. In particular, the global variables created to represent
the runtime information of derived types use `.` in their names.
A derived type's descriptor object may be used in the device code,
e.g. to initialize a descriptor of a variable of this type.
Thus, the runtime type info objects may need to be compiled
for the device.

Moreover, at least the derived types' descriptor objects
may need to be registered (think of `omp declare target`)
for the host-device association so that the addendum pointer
can be properly mapped to the device for descriptors using
a derived type's descriptor as their addendum pointer.
The registration implies knowing the name of the global variable
in the device image so that proper host code can be created.
So it is better to name the globals the same way for the host
and the device.

CompilerGeneratedNamesConversion pass renames all uniqued globals
such that the special symbols (currently `.`) are replaced
with `X`. The pass is supposed to be run for the host and the device.

An option is added to FIR-to-LLVM conversion pass to indicate
whether the new pass has been run before or not. This setting
affects how the codegen computes the names of the derived types'
descriptors for FIR derived types.

fir::NameUniquer now allows `X` to be part of a name, because
the name deconstruction may be applied to the mangled names
after CompilerGeneratedNamesConversion pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:driver 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.

7 participants