https://github.com/kaviya2510 updated 
https://github.com/llvm/llvm-project/pull/216680

>From 0f00a4d07fc599511bfb821731f32d5449c08e54 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <[email protected]>
Date: Mon, 17 Aug 2026 15:31:44 +0530
Subject: [PATCH 1/3] [Flang][Driver] Added support for
 -funique-internal-linkage-names

---
 clang/include/clang/Options/Options.td        |  4 +--
 clang/lib/Driver/ToolChains/Flang.cpp         |  3 +++
 .../include/flang/Frontend/CodeGenOptions.def |  1 +
 flang/include/flang/Lower/Bridge.h            |  4 +++
 .../flang/Optimizer/Transforms/Passes.td      |  4 +++
 flang/include/flang/Tools/CrossToolHelpers.h  |  3 +++
 flang/lib/Frontend/CompilerInvocation.cpp     |  5 ++++
 flang/lib/Lower/Bridge.cpp                    | 15 ++++++++++-
 flang/lib/Optimizer/Passes/Pipelines.cpp      |  4 +--
 .../lib/Optimizer/Transforms/FunctionAttr.cpp |  7 +++++
 .../Driver/funique-internal-linkage-names.f90 | 20 ++++++++++++++
 .../unique-internal-linkage-names.f90         | 22 ++++++++++++++++
 ...on-attrs-unique-internal-linkage-names.fir | 26 +++++++++++++++++++
 mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td   |  3 ++-
 mlir/lib/Target/LLVMIR/ModuleImport.cpp       |  7 +++++
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp  |  5 ++++
 .../sample-profile-suffix-elision-policy.ll   | 15 +++++++++++
 .../sample-profile-suffix-elision-policy.mlir |  7 +++++
 18 files changed, 149 insertions(+), 6 deletions(-)
 create mode 100644 flang/test/Driver/funique-internal-linkage-names.f90
 create mode 100644 flang/test/Integration/unique-internal-linkage-names.f90
 create mode 100644 
flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir
 create mode 100644 
mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll
 create mode 100644 
mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index d4bf48040029f5..80fda1515d8cb5 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -5089,10 +5089,10 @@ defm unique_basic_block_section_names : 
BoolFOption<"unique-basic-block-section-
   NegFlag<SetFalse>>;
 defm unique_internal_linkage_names : 
BoolFOption<"unique-internal-linkage-names",
   CodeGenOpts<"UniqueInternalLinkageNames">, DefaultFalse,
-  PosFlag<SetTrue, [], [ClangOption, CC1Option],
+  PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option],
           "Uniqueify Internal Linkage Symbol Names by appending"
             " the MD5 hash of the module path">,
-  NegFlag<SetFalse>>;
+  NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option]>>;
 defm unique_section_names : BoolFOption<"unique-section-names",
   CodeGenOpts<"UniqueSectionNames">, DefaultTrue,
   NegFlag<SetFalse, [], [ClangOption, CC1Option],
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 95a11eb36be080..70e71fe42f1199 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -357,6 +357,9 @@ void Flang::addCodegenOptions(const ArgList &Args,
                     options::OPT_fno_experimental_loop_fusion);
   Args.AddLastArg(CmdArgs, options::OPT_ffp_sum_reassociation,
                   options::OPT_fno_fp_sum_reassociation);
+                  
+  Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names,
+    options::OPT_fno_unique_internal_linkage_names);
 
   handleInterchangeLoopsArgs(Args, CmdArgs);
   handleVectorizeLoopsArgs(Args, CmdArgs);
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def 
b/flang/include/flang/Frontend/CodeGenOptions.def
index a036311829e280..86994f7710576c 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -61,6 +61,7 @@ CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis 
pass
 CODEGENOPT(DwarfVersion, 3, 0) ///< Dwarf version
 CODEGENOPT(DebugInfoForProfiling, 1, 0)  ///< Emit extra debug info to make 
sample profile more accurate.
 CODEGENOPT(PseudoProbeForProfiling, 1, 0) ///< Emit pseudo probes for sample 
profiling.
+CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Append MD5 hash to internal 
linkage symbols.
 
 CODEGENOPT(Underscoring, 1, 1)
 ENUM_CODEGENOPT(FPMaxminBehavior, Fortran::common::FPMaxminBehavior, 2, 
Fortran::common::FPMaxminBehavior::Legacy)
diff --git a/flang/include/flang/Lower/Bridge.h 
b/flang/include/flang/Lower/Bridge.h
index dbddef7b1169d1..f8421f27e6ec25 100644
--- a/flang/include/flang/Lower/Bridge.h
+++ b/flang/include/flang/Lower/Bridge.h
@@ -24,6 +24,7 @@
 #include "flang/Support/Fortran.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/OwningOpRef.h"
+#include "llvm/ProfileData/SampleProf.h"
 #include <set>
 
 namespace llvm {
@@ -118,6 +119,8 @@ class LoweringBridge {
     return languageFeatures;
   }
 
+  const std::string &getModuleNameHash() const { return moduleNameHash; }
+
   /// Create a folding context. Careful: this is very expensive.
   Fortran::evaluate::FoldingContext createFoldingContext();
 
@@ -180,6 +183,7 @@ class LoweringBridge {
   const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults;
   const Fortran::common::LanguageFeatureControl &languageFeatures;
   std::set<std::string> tempNames;
+  std::string moduleNameHash;
   std::optional<mlir::DiagnosticEngine::HandlerID> diagHandlerID;
 };
 
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td 
b/flang/include/flang/Optimizer/Transforms/Passes.td
index 619f44e53bac5f..f857e19f4ae461 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -527,6 +527,10 @@ def FunctionAttr : Pass<"function-attr", 
"mlir::func::FuncOp"> {
               /*default=*/"false",
               "Set the disable-tail-calls attribute on functions to prevent "
               "tail call optimization.">,
+       Option<"UniqueInternalLinkageNames", "unique-internal-linkage-names",
+              "bool", /*default=*/"false",
+              "Set the sample-profile-suffix-elision-policy attribute on "
+              "internal linkage functions in the module.">,
        Option<"tuneCPU", "tune-cpu", "std::string", /*default=*/"",
               "Set the tune-cpu attribute on functions in the module.">,
        Option<"setNoCapture", "set-nocapture", "bool", /*default=*/"false",
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h 
b/flang/include/flang/Tools/CrossToolHelpers.h
index 692b7fd7129f2e..b9add141663b9c 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -138,6 +138,7 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
     Reciprocals = opts.Reciprocals;
     PreferVectorWidth = opts.PreferVectorWidth;
     UseSampleProfile = !opts.SampleProfileFile.empty();
+    UniqueInternalLinkageNames = opts.UniqueInternalLinkageNames;
     DebugInfoForProfiling = opts.DebugInfoForProfiling;
     if (opts.InstrumentFunctions) {
       InstrumentFunctionEntry = "__cyg_profile_func_enter";
@@ -178,6 +179,8 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
   bool EnableOpenMPIsTargetDevice =
       false; ///< Compiling for an OpenMP target device.
   bool UseSampleProfile = false; ///< Enable sample based profiling
+  bool UniqueInternalLinkageNames = false; ///< Append MD5 hash suffix to
+                                           ///< internal linkage symbol names.
   bool DebugInfoForProfiling = false; ///< Enable extra debugging info
   bool DisableTailCalls = false; ///< Disable tail call optimization
   bool EnableOpenMPSimd = false; ///< Enable OpenMP simd-only mode.
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 85e5f477dcb8c7..253c7932202a39 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -317,6 +317,11 @@ static void 
parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
                    clang::options::OPT_fno_safe_trampoline, false))
     opts.EnableSafeTrampoline = 1;
 
+  if (args.hasFlag(clang::options::OPT_funique_internal_linkage_names,
+                   clang::options::OPT_fno_unique_internal_linkage_names,
+                   false))
+    opts.UniqueInternalLinkageNames = 1;
+
   if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation,
                    clang::options::OPT_fno_fp_sum_reassociation, true))
     opts.SplitSumExpressionTree = 1;
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 784a87cc619979..ddf8fbecd987ce 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1239,9 +1239,15 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
   }
   std::string
   mangleName(const Fortran::semantics::Symbol &symbol) override final {
-    return Fortran::lower::mangle::mangleName(
+    std::string mangledName = Fortran::lower::mangle::mangleName(
         symbol, scopeBlockIdMap, /*keepExternalInScope=*/false,
         getLoweringOptions().getUnderscoring());
+    const auto &hash = bridge.getModuleNameHash();
+    if (!hash.empty() &&
+        Fortran::semantics::ClassifyProcedure(symbol) ==
+            Fortran::semantics::ProcedureDefinitionClass::Internal)
+      mangledName += hash;
+    return mangledName;
   }
   std::string mangleName(
       const Fortran::semantics::DerivedTypeSpec &derivedType) override final {
@@ -7136,6 +7142,13 @@ Fortran::lower::LoweringBridge::LoweringBridge(
   else if (languageFeatures.IsEnabled(
                Fortran::common::LanguageFeature::CudaManaged))
     fir::setCudaHeapAllocMode(*module, fir::CudaHeapAllocMode::Managed);
+
+  if (cgOpts.UniqueInternalLinkageNames) {
+    if (auto fileLoc = mlir::dyn_cast<mlir::FileLineColLoc>(module->getLoc())) 
{
+      moduleNameHash =
+          llvm::getUniqueInternalLinkagePostfix(fileLoc.getFilename());
+    }
+  }
 }
 
 Fortran::lower::LoweringBridge::~LoweringBridge() {
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp 
b/flang/lib/Optimizer/Passes/Pipelines.cpp
index b73a1ce4a47c64..517f7995ac340c 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -464,8 +464,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager 
&pm,
        config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath,
        config.ApproxFuncFPMath, config.NoSignedZerosFPMath, 
config.UnsafeFPMath,
        config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile,
-       config.DisableTailCalls, /*tuneCPU=*/"", setNoCapture, setNoAlias,
-       setReadOnly}));
+       config.DisableTailCalls, config.UniqueInternalLinkageNames,  
/*tuneCPU=*/"", 
+       setNoCapture, setNoAlias, setReadOnly}));
 
   if (config.EnableOpenMP) {
     pm.addNestedPass<mlir::func::FuncOp>(
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp 
b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
index 1aadd16fe1cf44..958a9ea87cd6d8 100644
--- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -144,6 +144,13 @@ void FunctionAttrPass::runOnOperation() {
             context, mlir::LLVM::LLVMFuncOp::getUseSampleProfileAttrName(
                          llvmFuncOpName)),
         mlir::BoolAttr::get(context, true));
+  if (UniqueInternalLinkageNames && fir::isInternalProcedure(func))
+    func->setAttr(
+        getLlvmFuncPropertyAttrName(
+            context,
+            
mlir::LLVM::LLVMFuncOp::getSampleProfileSuffixElisionPolicyAttrName(
+                llvmFuncOpName)),
+        mlir::StringAttr::get(context, "selected"));
 
   if (disableTailCalls)
     func->setAttr(
diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 
b/flang/test/Driver/funique-internal-linkage-names.f90
new file mode 100644
index 00000000000000..88cafb520a0192
--- /dev/null
+++ b/flang/test/Driver/funique-internal-linkage-names.f90
@@ -0,0 +1,20 @@
+! Test that -funique-internal-linkage-names / 
-fno-unique-internal-linkage-names are forwarded to flang -fc1.
+
+! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DEFAULT
+! RUN: %flang -### -funique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=ENABLED
+! RUN: %flang -### -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=DISABLED
+! RUN: %flang -### -funique-internal-linkage-names 
-fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=DISABLED
+! RUN: %flang -### -fno-unique-internal-linkage-names 
-funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED
+
+! DEFAULT-NOT: "-funique-internal-linkage-names"
+! DEFAULT-NOT: "-fno-unique-internal-linkage-names"
+
+! ENABLED: "-fc1"{{.*}}"-funique-internal-linkage-names"
+! DISABLED-NOT: "-funique-internal-linkage-names"
+
+subroutine host()
+  call inner()
+contains
+  subroutine inner()
+  end subroutine
+end subroutine
diff --git a/flang/test/Integration/unique-internal-linkage-names.f90 
b/flang/test/Integration/unique-internal-linkage-names.f90
new file mode 100644
index 00000000000000..c96e854b8eae44
--- /dev/null
+++ b/flang/test/Integration/unique-internal-linkage-names.f90
@@ -0,0 +1,22 @@
+! Test that -funique-internal-linkage-names appends a hash suffix to internal
+! procedures and sets the "sample-profile-suffix-elision-policy" attribute.
+
+! RUN: %flang_fc1 -emit-llvm -funique-internal-linkage-names -o - %s | 
FileCheck %s
+
+! CHECK-LABEL: define void @test_(
+! CHECK      : call void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}})
+
+! CHECK-LABEL: define internal void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) 
#0
+! CHECK-NOT  : define internal void @_QFtestPfoo(
+
+! CHECK: attributes #0 = { "sample-profile-suffix-elision-policy"="selected" }
+
+subroutine test(x)
+  integer, intent(inout) :: x
+  call foo(x)
+contains
+  subroutine foo(y)
+    integer, intent(inout) :: y
+    y = y + 1
+  end subroutine
+end subroutine
diff --git 
a/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir 
b/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir
new file mode 100644
index 00000000000000..9d5cf40ea6e35a
--- /dev/null
+++ b/flang/test/Transforms/function-attrs-unique-internal-linkage-names.fir
@@ -0,0 +1,26 @@
+// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | 
FileCheck %s --check-prefix=ENABLED
+// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | 
FileCheck %s --check-prefix=DISABLED
+
+// Internal procedure: has fir.host_symbol, should get the attribute.
+// ENABLED-LABEL: func.func @_QFhost_subPinner(
+// ENABLED-SAME: llvm.sample_profile_suffix_elision_policy = "selected"
+
+// DISABLED-LABEL: func.func @_QFhost_subPinner(
+// DISABLED-NOT: sample_profile_suffix_elision_policy
+func.func @_QFhost_subPinner(%arg0: !fir.ref<i32>) attributes {fir.host_symbol 
= @_QFhost_sub} {
+  return
+}
+
+// Host procedure: no fir.host_symbol, should NOT get the attribute.
+// ENABLED-LABEL: func.func @_QFhost_sub(
+// ENABLED-NOT: sample_profile_suffix_elision_policy
+func.func @_QFhost_sub(%arg0: !fir.ref<i32>) {
+  return
+}
+
+// External procedure: should NOT get the attribute.
+// ENABLED-LABEL: func.func @_QPexternal_sub(
+// ENABLED-NOT: sample_profile_suffix_elision_policy
+func.func @_QPexternal_sub(%arg0: !fir.ref<i32>) {
+  return
+}
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 5998bd01f9bdf5..c8efc741d0acb6 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -2160,7 +2160,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [
     OptionalAttr<LLVM_FunctionMetadataArrayAttr>:$function_metadata,
     OptionalAttr<UWTableKindAttr>:$uwtable_kind,
     OptionalAttr<BoolAttr>:$use_sample_profile,
-    OptionalAttr<BoolAttr>:$disable_tail_calls
+    OptionalAttr<BoolAttr>:$disable_tail_calls,
+    OptionalAttr<StrAttr>:$sample_profile_suffix_elision_policy
   );
 
   let regions = (region AnyRegion:$body);
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp 
b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index bfecde8b664a9b..ab7eb2e690d57f 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -2927,6 +2927,7 @@ static constexpr std::array kExplicitLLVMFuncOpAttributes{
     StringLiteral("save-reg-params"),
     StringLiteral("target-features"),
     StringLiteral("trap-func-name"),
+    StringLiteral("sample-profile-suffix-elision-policy"),
     StringLiteral("tune-cpu"),
     StringLiteral("uniform-work-group-size"),
     StringLiteral("uwtable"),
@@ -3103,6 +3104,12 @@ void 
ModuleImport::processFunctionAttributes(llvm::Function *func,
       emitError(funcOp.getLoc())
           << "unknown value '" << val << "' for 'disable-tail-calls' 
attribute";
   }
+  
+  if (llvm::Attribute attr =
+          func->getFnAttribute("sample-profile-suffix-elision-policy");
+      attr.isStringAttribute())
+    funcOp.setSampleProfileSuffixElisionPolicy(
+        StringAttr::get(context, attr.getValueAsString()));
 
   if (llvm::Attribute attr = func->getFnAttribute("target-cpu");
       attr.isStringAttribute())
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp 
b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 50365b5a5b3a13..0cce25c6275bc9 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1745,6 +1745,11 @@ LogicalResult 
ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
   if (auto disableTailCalls = func.getDisableTailCalls())
     llvmFunc->addFnAttr("disable-tail-calls",
                         llvm::toStringRef(*disableTailCalls));
+                        
+  if (auto sampleProfileSuffixElisionPolicy =
+          func.getSampleProfileSuffixElisionPolicy())
+    llvmFunc->addFnAttr("sample-profile-suffix-elision-policy",
+                        *sampleProfileSuffixElisionPolicy);
 
   if (auto attr = func.getVscaleRange())
     llvmFunc->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
diff --git 
a/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll 
b/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll
new file mode 100644
index 00000000000000..8f9a59fea827cf
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/sample-profile-suffix-elision-policy.ll
@@ -0,0 +1,15 @@
+; RUN: mlir-translate -import-llvm %s | FileCheck %s
+
+; CHECK-LABEL: llvm.func @with_elision_policy()
+; CHECK-SAME: sample_profile_suffix_elision_policy = "selected"
+define void @with_elision_policy() #0 {
+  ret void
+}
+
+; CHECK-LABEL: llvm.func @without_elision_policy()
+; CHECK-NOT: sample_profile_suffix_elision_policy
+define void @without_elision_policy() {
+  ret void
+}
+
+attributes #0 = { "sample-profile-suffix-elision-policy"="selected" }
diff --git a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir 
b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir
new file mode 100644
index 00000000000000..4882a886d45588
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir
@@ -0,0 +1,7 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// CHECK: define void @with_elision_policy() #[[ATTRS:.*]] {
+// CHECK: attributes #[[ATTRS]] = { 
"sample-profile-suffix-elision-policy"="selected" }
+llvm.func @with_elision_policy() attributes 
{sample_profile_suffix_elision_policy = "selected"} {
+  llvm.return
+}

>From 100409b530d484716adc71a5fca2c17f15436c13 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <[email protected]>
Date: Thu, 20 Aug 2026 00:56:31 +0530
Subject: [PATCH 2/3] [Flang] Preserve .__uniq. suffix in
 CompilerGeneratedNamesConversion pass and added new testcases

---
 clang/include/clang/Options/Options.td        |  2 +-
 clang/lib/Driver/ToolChains/Flang.cpp         |  4 +--
 flang/lib/Frontend/CompilerInvocation.cpp     |  8 +++---
 .../Transforms/CompilerGeneratedNames.cpp     |  2 ++
 .../Driver/funique-internal-linkage-names.f90 | 17 +++++-------
 .../unique-internal-linkage-names.f90         | 22 ----------------
 .../Lower/unique-internal-linkage-names.f90   | 20 ++++++++++++++
 ...ion-attr-unique-internal-linkage-names.fir | 26 +++++++++++++++++++
 .../LLVMIR/unique-internal-linkage-names.mlir | 20 ++++++++++++++
 9 files changed, 80 insertions(+), 41 deletions(-)
 delete mode 100644 flang/test/Integration/unique-internal-linkage-names.f90
 create mode 100644 flang/test/Lower/unique-internal-linkage-names.f90
 create mode 100644 
flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
 create mode 100644 mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 80fda1515d8cb5..15b2196b68e76e 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -5092,7 +5092,7 @@ defm unique_internal_linkage_names : 
BoolFOption<"unique-internal-linkage-names"
   PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option],
           "Uniqueify Internal Linkage Symbol Names by appending"
             " the MD5 hash of the module path">,
-  NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option]>>;
+  NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption]>>;
 defm unique_section_names : BoolFOption<"unique-section-names",
   CodeGenOpts<"UniqueSectionNames">, DefaultTrue,
   NegFlag<SetFalse, [], [ClangOption, CC1Option],
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index 70e71fe42f1199..b333f0d56a3958 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -357,9 +357,9 @@ void Flang::addCodegenOptions(const ArgList &Args,
                     options::OPT_fno_experimental_loop_fusion);
   Args.AddLastArg(CmdArgs, options::OPT_ffp_sum_reassociation,
                   options::OPT_fno_fp_sum_reassociation);
-                  
+
   Args.addOptInFlag(CmdArgs, options::OPT_funique_internal_linkage_names,
-    options::OPT_fno_unique_internal_linkage_names);
+                    options::OPT_fno_unique_internal_linkage_names);
 
   handleInterchangeLoopsArgs(Args, CmdArgs);
   handleVectorizeLoopsArgs(Args, CmdArgs);
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 253c7932202a39..1dd28e4f0a99b5 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -317,11 +317,6 @@ static void 
parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
                    clang::options::OPT_fno_safe_trampoline, false))
     opts.EnableSafeTrampoline = 1;
 
-  if (args.hasFlag(clang::options::OPT_funique_internal_linkage_names,
-                   clang::options::OPT_fno_unique_internal_linkage_names,
-                   false))
-    opts.UniqueInternalLinkageNames = 1;
-
   if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation,
                    clang::options::OPT_fno_fp_sum_reassociation, true))
     opts.SplitSumExpressionTree = 1;
@@ -332,6 +327,9 @@ static void 
parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
       args.hasFlag(clang::options::OPT_floop_interchange,
                    clang::options::OPT_fno_loop_interchange, true);
 
+  if (args.hasArg(clang::options::OPT_funique_internal_linkage_names))
+    opts.UniqueInternalLinkageNames = 1;
+
   if (args.getLastArg(clang::options::OPT_fexperimental_loop_fusion))
     opts.FuseLoops = 1;
 
diff --git a/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp 
b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp
index 7a173da514b168..ca33639bbb8885 100644
--- a/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp
+++ b/flang/lib/Optimizer/Transforms/CompilerGeneratedNames.cpp
@@ -45,6 +45,8 @@ void CompilerGeneratedNamesConversionPass::runOnOperation() {
 
   auto processOp = [&](mlir::Operation &op) {
     auto symName = mlir::cast<mlir::SymbolOpInterface>(&op).getNameAttr();
+    if (symName.getValue().contains(".__uniq."))
+      return;
     auto deconstructedName = fir::NameUniquer::deconstruct(symName);
     if (deconstructedName.first != fir::NameUniquer::NameKind::NOT_UNIQUED &&
         !fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) {
diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 
b/flang/test/Driver/funique-internal-linkage-names.f90
index 88cafb520a0192..6192e3617cec04 100644
--- a/flang/test/Driver/funique-internal-linkage-names.f90
+++ b/flang/test/Driver/funique-internal-linkage-names.f90
@@ -1,20 +1,15 @@
 ! Test that -funique-internal-linkage-names / 
-fno-unique-internal-linkage-names are forwarded to flang -fc1.
 
-! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DEFAULT
+! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=DISABLED
 ! RUN: %flang -### -funique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=ENABLED
 ! RUN: %flang -### -fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=DISABLED
 ! RUN: %flang -### -funique-internal-linkage-names 
-fno-unique-internal-linkage-names %s 2>&1 | FileCheck %s 
--check-prefix=DISABLED
 ! RUN: %flang -### -fno-unique-internal-linkage-names 
-funique-internal-linkage-names %s 2>&1 | FileCheck %s --check-prefix=ENABLED
 
-! DEFAULT-NOT: "-funique-internal-linkage-names"
-! DEFAULT-NOT: "-fno-unique-internal-linkage-names"
-
-! ENABLED: "-fc1"{{.*}}"-funique-internal-linkage-names"
+! DISABLED: "-fc1"
 ! DISABLED-NOT: "-funique-internal-linkage-names"
+! DISABLED-NOT: "-fno-unique-internal-linkage-names"
+
+! ENABLED: "-fc1"
+! ENABLED-SAME: "-funique-internal-linkage-names"
 
-subroutine host()
-  call inner()
-contains
-  subroutine inner()
-  end subroutine
-end subroutine
diff --git a/flang/test/Integration/unique-internal-linkage-names.f90 
b/flang/test/Integration/unique-internal-linkage-names.f90
deleted file mode 100644
index c96e854b8eae44..00000000000000
--- a/flang/test/Integration/unique-internal-linkage-names.f90
+++ /dev/null
@@ -1,22 +0,0 @@
-! Test that -funique-internal-linkage-names appends a hash suffix to internal
-! procedures and sets the "sample-profile-suffix-elision-policy" attribute.
-
-! RUN: %flang_fc1 -emit-llvm -funique-internal-linkage-names -o - %s | 
FileCheck %s
-
-! CHECK-LABEL: define void @test_(
-! CHECK      : call void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}})
-
-! CHECK-LABEL: define internal void @_QFtestPfooX__uniqX{{[0-9]+}}(ptr {{.*}}) 
#0
-! CHECK-NOT  : define internal void @_QFtestPfoo(
-
-! CHECK: attributes #0 = { "sample-profile-suffix-elision-policy"="selected" }
-
-subroutine test(x)
-  integer, intent(inout) :: x
-  call foo(x)
-contains
-  subroutine foo(y)
-    integer, intent(inout) :: y
-    y = y + 1
-  end subroutine
-end subroutine
diff --git a/flang/test/Lower/unique-internal-linkage-names.f90 
b/flang/test/Lower/unique-internal-linkage-names.f90
new file mode 100644
index 00000000000000..811519f3db5abd
--- /dev/null
+++ b/flang/test/Lower/unique-internal-linkage-names.f90
@@ -0,0 +1,20 @@
+! Test that -funique-internal-linkage-names appends a .__uniq. hash suffix
+! to internal procedures at the FIR level.
+
+! RUN: %flang_fc1 -emit-fir -funique-internal-linkage-names -o - %s | 
FileCheck %s
+
+! CHECK-LABEL: func.func @_QPtest
+! CHECK: fir.call @_QFtestPfoo.__uniq.{{[0-9]+}}
+
+! CHECK: func.func private @_QFtestPfoo.__uniq.{{[0-9]+}}
+! CHECK-SAME: attributes {fir.host_symbol = @_QPtest, llvm.linkage = 
#llvm.linkage<internal>}
+
+subroutine test(x)
+  integer, intent(inout) :: x
+  call foo(x)
+contains
+  subroutine foo(y)
+    integer, intent(inout) :: y
+    y = y + 1
+  end subroutine
+end subroutine
diff --git 
a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir 
b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
new file mode 100644
index 00000000000000..0284f75004b628
--- /dev/null
+++ b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
@@ -0,0 +1,26 @@
+// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | 
FileCheck %s --check-prefix=ENABLED
+// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | 
FileCheck %s --check-prefix=DISABLED
+
+// ENABLED: func.func @_QPtest() {
+// ENABLED-NEXT:   return
+// ENABLED-NEXT: }
+
+// DISABLED: func.func @_QPtest() {
+// DISABLED-NEXT:   return
+// DISABLED-NEXT: }
+func.func @_QPtest() {
+  return
+}
+
+// ENABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest, 
llvm.sample_profile_suffix_elision_policy = "selected"} {
+// ENABLED-NEXT:   return
+// ENABLED-NEXT: }
+
+// DISABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} {
+// DISABLED-NEXT:   return
+// DISABLED-NEXT: }
+
+func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} {
+  return
+}
+
diff --git a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir 
b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir
new file mode 100644
index 00000000000000..a1113caed3ed11
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir
@@ -0,0 +1,20 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+// CHECK-LABEL: define void @test_(ptr noalias %0)
+// CHECK: call void @_QFtestPfoo.__uniq.12345(ptr %0)
+
+llvm.func @test_(%arg0: !llvm.ptr {llvm.noalias}) {
+  llvm.call @_QFtestPfoo.__uniq.12345(%arg0) : (!llvm.ptr) -> ()
+  llvm.return
+}
+
+// CHECK-LABEL: define internal void @_QFtestPfoo.__uniq.12345(ptr noalias %0)
+llvm.func internal @_QFtestPfoo.__uniq.12345(%arg0: !llvm.ptr {llvm.noalias}) 
attributes {sample_profile_suffix_elision_policy = "selected"} {
+  %0 = llvm.load %arg0 : !llvm.ptr -> i32
+  %1 = llvm.mlir.constant(1 : i32) : i32
+  %2 = llvm.add %0, %1 : i32
+  llvm.store %2, %arg0 : i32, !llvm.ptr
+  llvm.return
+}
+
+// CHECK: attributes #[[ATTRS:.*]] = { 
"sample-profile-suffix-elision-policy"="selected" }

>From 882e73beaf693b5973d8c01451978683628dc4f1 Mon Sep 17 00:00:00 2001
From: Kaviya Rajendiran <[email protected]>
Date: Fri, 28 Aug 2026 15:58:33 +0530
Subject: [PATCH 3/3] [Flang] Addressed review comment and modified testcases
 and formatting issues

---
 flang/lib/Lower/Bridge.cpp                    |  2 +-
 flang/lib/Optimizer/Passes/Pipelines.cpp      |  4 +--
 .../Driver/funique-internal-linkage-names.f90 |  1 -
 .../Lower/unique-internal-linkage-names.f90   |  9 +++----
 ...ion-attr-unique-internal-linkage-names.fir | 26 -------------------
 mlir/lib/Target/LLVMIR/ModuleImport.cpp       |  2 +-
 mlir/lib/Target/LLVMIR/ModuleTranslation.cpp  |  2 +-
 .../sample-profile-suffix-elision-policy.mlir | 11 ++++++--
 .../LLVMIR/unique-internal-linkage-names.mlir | 20 --------------
 9 files changed, 17 insertions(+), 60 deletions(-)
 delete mode 100644 
flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
 delete mode 100644 mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index ddf8fbecd987ce..968cdbc951ecc4 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -1242,7 +1242,7 @@ class FirConverter : public 
Fortran::lower::AbstractConverter {
     std::string mangledName = Fortran::lower::mangle::mangleName(
         symbol, scopeBlockIdMap, /*keepExternalInScope=*/false,
         getLoweringOptions().getUnderscoring());
-    const auto &hash = bridge.getModuleNameHash();
+    const std::string &hash = bridge.getModuleNameHash();
     if (!hash.empty() &&
         Fortran::semantics::ClassifyProcedure(symbol) ==
             Fortran::semantics::ProcedureDefinitionClass::Internal)
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp 
b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 517f7995ac340c..fc5b5ef6460a92 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -464,8 +464,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager 
&pm,
        config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath,
        config.ApproxFuncFPMath, config.NoSignedZerosFPMath, 
config.UnsafeFPMath,
        config.Reciprocals, config.PreferVectorWidth, config.UseSampleProfile,
-       config.DisableTailCalls, config.UniqueInternalLinkageNames,  
/*tuneCPU=*/"", 
-       setNoCapture, setNoAlias, setReadOnly}));
+       config.DisableTailCalls, config.UniqueInternalLinkageNames,
+       /*tuneCPU=*/"", setNoCapture, setNoAlias, setReadOnly}));
 
   if (config.EnableOpenMP) {
     pm.addNestedPass<mlir::func::FuncOp>(
diff --git a/flang/test/Driver/funique-internal-linkage-names.f90 
b/flang/test/Driver/funique-internal-linkage-names.f90
index 6192e3617cec04..d81e405cff5411 100644
--- a/flang/test/Driver/funique-internal-linkage-names.f90
+++ b/flang/test/Driver/funique-internal-linkage-names.f90
@@ -12,4 +12,3 @@
 
 ! ENABLED: "-fc1"
 ! ENABLED-SAME: "-funique-internal-linkage-names"
-
diff --git a/flang/test/Lower/unique-internal-linkage-names.f90 
b/flang/test/Lower/unique-internal-linkage-names.f90
index 811519f3db5abd..7699212ddff3a7 100644
--- a/flang/test/Lower/unique-internal-linkage-names.f90
+++ b/flang/test/Lower/unique-internal-linkage-names.f90
@@ -9,12 +9,9 @@
 ! CHECK: func.func private @_QFtestPfoo.__uniq.{{[0-9]+}}
 ! CHECK-SAME: attributes {fir.host_symbol = @_QPtest, llvm.linkage = 
#llvm.linkage<internal>}
 
-subroutine test(x)
-  integer, intent(inout) :: x
-  call foo(x)
+subroutine test()
+  call foo()
 contains
-  subroutine foo(y)
-    integer, intent(inout) :: y
-    y = y + 1
+  subroutine foo()
   end subroutine
 end subroutine
diff --git 
a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir 
b/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
deleted file mode 100644
index 0284f75004b628..00000000000000
--- a/flang/test/Transforms/function-attr-unique-internal-linkage-names.fir
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: fir-opt --function-attr="unique-internal-linkage-names=true" %s | 
FileCheck %s --check-prefix=ENABLED
-// RUN: fir-opt --function-attr="unique-internal-linkage-names=false" %s | 
FileCheck %s --check-prefix=DISABLED
-
-// ENABLED: func.func @_QPtest() {
-// ENABLED-NEXT:   return
-// ENABLED-NEXT: }
-
-// DISABLED: func.func @_QPtest() {
-// DISABLED-NEXT:   return
-// DISABLED-NEXT: }
-func.func @_QPtest() {
-  return
-}
-
-// ENABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest, 
llvm.sample_profile_suffix_elision_policy = "selected"} {
-// ENABLED-NEXT:   return
-// ENABLED-NEXT: }
-
-// DISABLED: func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} {
-// DISABLED-NEXT:   return
-// DISABLED-NEXT: }
-
-func.func @_QFtestPfoo() attributes {fir.host_symbol = @_QPtest} {
-  return
-}
-
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp 
b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index ab7eb2e690d57f..04f69433b97a00 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -3104,7 +3104,7 @@ void 
ModuleImport::processFunctionAttributes(llvm::Function *func,
       emitError(funcOp.getLoc())
           << "unknown value '" << val << "' for 'disable-tail-calls' 
attribute";
   }
-  
+
   if (llvm::Attribute attr =
           func->getFnAttribute("sample-profile-suffix-elision-policy");
       attr.isStringAttribute())
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp 
b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 0cce25c6275bc9..bd11a493f4bd3d 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1745,7 +1745,7 @@ LogicalResult 
ModuleTranslation::convertOneFunction(LLVMFuncOp func) {
   if (auto disableTailCalls = func.getDisableTailCalls())
     llvmFunc->addFnAttr("disable-tail-calls",
                         llvm::toStringRef(*disableTailCalls));
-                        
+
   if (auto sampleProfileSuffixElisionPolicy =
           func.getSampleProfileSuffixElisionPolicy())
     llvmFunc->addFnAttr("sample-profile-suffix-elision-policy",
diff --git a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir 
b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir
index 4882a886d45588..49536205713186 100644
--- a/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir
+++ b/mlir/test/Target/LLVMIR/sample-profile-suffix-elision-policy.mlir
@@ -1,7 +1,14 @@
 // RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
 
-// CHECK: define void @with_elision_policy() #[[ATTRS:.*]] {
-// CHECK: attributes #[[ATTRS]] = { 
"sample-profile-suffix-elision-policy"="selected" }
+// CHECK: define void @with_elision_policy() #[[ATTRS_WITH:.*]] {
 llvm.func @with_elision_policy() attributes 
{sample_profile_suffix_elision_policy = "selected"} {
   llvm.return
 }
+
+// CHECK: define void @without_elision_policy() {
+// CHECK-NOT: "sample-profile-suffix-elision-policy"
+llvm.func @without_elision_policy() {
+  llvm.return
+}
+
+// CHECK: attributes #[[ATTRS_WITH]] = { 
"sample-profile-suffix-elision-policy"="selected" }
diff --git a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir 
b/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir
deleted file mode 100644
index a1113caed3ed11..00000000000000
--- a/mlir/test/Target/LLVMIR/unique-internal-linkage-names.mlir
+++ /dev/null
@@ -1,20 +0,0 @@
-// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
-
-// CHECK-LABEL: define void @test_(ptr noalias %0)
-// CHECK: call void @_QFtestPfoo.__uniq.12345(ptr %0)
-
-llvm.func @test_(%arg0: !llvm.ptr {llvm.noalias}) {
-  llvm.call @_QFtestPfoo.__uniq.12345(%arg0) : (!llvm.ptr) -> ()
-  llvm.return
-}
-
-// CHECK-LABEL: define internal void @_QFtestPfoo.__uniq.12345(ptr noalias %0)
-llvm.func internal @_QFtestPfoo.__uniq.12345(%arg0: !llvm.ptr {llvm.noalias}) 
attributes {sample_profile_suffix_elision_policy = "selected"} {
-  %0 = llvm.load %arg0 : !llvm.ptr -> i32
-  %1 = llvm.mlir.constant(1 : i32) : i32
-  %2 = llvm.add %0, %1 : i32
-  llvm.store %2, %arg0 : i32, !llvm.ptr
-  llvm.return
-}
-
-// CHECK: attributes #[[ATTRS:.*]] = { 
"sample-profile-suffix-elision-policy"="selected" }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to