[clang] 78d0e91 - Refactor -funique-internal-linakge-names implementation.

Sriraman Tallam via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 5 13:34:53 PST 2021


Author: Sriraman Tallam
Date: 2021-03-05T13:32:17-08:00
New Revision: 78d0e91865f6038adb23ec272c3e1e7e1525057f

URL: https://github.com/llvm/llvm-project/commit/78d0e91865f6038adb23ec272c3e1e7e1525057f
DIFF: https://github.com/llvm/llvm-project/commit/78d0e91865f6038adb23ec272c3e1e7e1525057f.diff

LOG: Refactor -funique-internal-linakge-names implementation.

The option -funique-internal-linkage-names was added in D73307 and D78243 as a
LLVM early pass to insert a unique suffix to internal linkage functions and
vars. The unique suffix was the hash of the module path. However, we found
that this can be done more cleanly in clang early and the fixes that need to
be done later can be completely avoided. The fixes in particular are trying
to modify the DW_AT_linkage_name and finding the right place to insert the
pass.

This patch ressurects the original implementation proposed in D73307 which
was reviewed and then ditched in favor of the pass based approach.

Differential Revision: https://reviews.llvm.org/D96109

Added: 
    clang/test/CodeGen/unique-internal-linkage-names-dwarf.c
    clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp

Modified: 
    clang/include/clang/AST/Mangle.h
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/AST/Mangle.cpp
    clang/lib/CodeGen/BackendUtil.cpp
    clang/lib/CodeGen/CGCall.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/CodeGen/CodeGenModule.h
    clang/test/CodeGen/unique-internal-linkage-names.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h
index 13b436cdca3e..dc620ec10ff9 100644
--- a/clang/include/clang/AST/Mangle.h
+++ b/clang/include/clang/AST/Mangle.h
@@ -110,6 +110,12 @@ class MangleContext {
   virtual bool isDeviceMangleContext() const { return false; }
   virtual void setDeviceMangleContext(bool) {}
 
+  virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
+    return false;
+  }
+
+  virtual void needsUniqueInternalLinkageNames() { }
+
   // FIXME: consider replacing raw_ostream & with something like SmallString &.
   void mangleName(GlobalDecl GD, raw_ostream &);
   virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 8bc9d33d5bae..885d9e28ee69 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -126,6 +126,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
   llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
 
   bool IsDevCtx = false;
+  bool NeedsUniqueInternalLinkageNames = false;
 
 public:
   explicit ItaniumMangleContextImpl(ASTContext &Context,
@@ -140,6 +141,11 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
     return false;
   }
 
+  bool isUniqueInternalLinkageDecl(const NamedDecl *ND) override;
+  void needsUniqueInternalLinkageNames() override {
+    NeedsUniqueInternalLinkageNames = true;
+  }
+
   bool isDeviceMangleContext() const override { return IsDevCtx; }
   void setDeviceMangleContext(bool IsDev) override { IsDevCtx = IsDev; }
 
@@ -613,6 +619,33 @@ class CXXNameMangler {
 
 }
 
+static bool isInternalLinkageDecl(const NamedDecl *ND) {
+  if (ND && ND->getFormalLinkage() == InternalLinkage &&
+      !ND->isExternallyVisible() &&
+      getEffectiveDeclContext(ND)->isFileContext() &&
+      !ND->isInAnonymousNamespace())
+    return true;
+  return false;
+}
+
+// Check if this Decl needs a unique internal linkage name.
+bool ItaniumMangleContextImpl::isUniqueInternalLinkageDecl(
+    const NamedDecl *ND) {
+  if (!NeedsUniqueInternalLinkageNames || !ND)
+    return false;
+
+  // For C functions without prototypes, return false as their
+  // names should not be mangled.
+  if (auto *FD = dyn_cast<FunctionDecl>(ND)) {
+    if (!FD->getType()->getAs<FunctionProtoType>())
+      return false;
+  }
+
+  if (isInternalLinkageDecl(ND))
+    return true;
+  return false;
+}
+
 bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
   const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
   if (FD) {
@@ -1376,10 +1409,7 @@ void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
       // 12_GLOBAL__N_1 mangling is quite sufficient there, and this better
       // matches GCC anyway, because GCC does not treat anonymous namespaces as
       // implying internal linkage.
-      if (ND && ND->getFormalLinkage() == InternalLinkage &&
-          !ND->isExternallyVisible() &&
-          getEffectiveDeclContext(ND)->isFileContext() &&
-          !ND->isInAnonymousNamespace())
+      if (isInternalLinkageDecl(ND))
         Out << 'L';
 
       auto *FD = dyn_cast<FunctionDecl>(ND);

diff  --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 3282fcbd584f..2b0d55568cb8 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -116,6 +116,12 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
   if (!D->hasExternalFormalLinkage() && D->getOwningModuleForLinkage())
     return true;
 
+  // C functions with internal linkage have to be mangled with option
+  // -funique-internal-linkage-names.
+  if (!getASTContext().getLangOpts().CPlusPlus &&
+      isUniqueInternalLinkageDecl(D))
+    return true;
+
   // In C, functions with no attributes never need to be mangled. Fastpath them.
   if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
     return false;

diff  --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index bfa47e5dc16c..36b6588e773f 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -84,7 +84,6 @@
 #include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
 #include "llvm/Transforms/Utils/SymbolRewriter.h"
-#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h"
 #include <memory>
 using namespace clang;
 using namespace llvm;
@@ -817,12 +816,6 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
   if (!CodeGenOpts.RewriteMapFiles.empty())
     addSymbolRewriterPass(CodeGenOpts, &MPM);
 
-  // Add UniqueInternalLinkageNames Pass which renames internal linkage symbols
-  // with unique names.
-  if (CodeGenOpts.UniqueInternalLinkageNames) {
-    MPM.add(createUniqueInternalLinkageNamesPass());
-  }
-
   if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts, LangOpts)) {
     MPM.add(createGCOVProfilerPass(*Options));
     if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo)
@@ -1256,7 +1249,6 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
   // non-integrated assemblers don't recognize .cgprofile section.
   PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
   PTO.Coroutines = LangOpts.Coroutines;
-  PTO.UniqueLinkageNames = CodeGenOpts.UniqueInternalLinkageNames;
 
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(CodeGenOpts.DebugPassManager);

diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index edcaa528437b..da993bed7ba0 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2150,6 +2150,16 @@ void CodeGenModule::ConstructAttributeList(
     }
   }
 
+  // Add "sample-profile-suffix-elision-policy" attribute for internal linkage
+  // functions with -funique-internal-linkage-names.
+  if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
+    if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
+      if (this->getFunctionLinkage(Fn) == llvm::GlobalValue::InternalLinkage)
+        FuncAttrs.addAttribute("sample-profile-suffix-elision-policy",
+                               "selected");
+    }
+  }
+
   // Collect non-call-site function IR attributes from declaration-specific
   // information.
   if (!AttrOnCallSite) {

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 5623bd7542ec..4bf339786d42 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -180,6 +180,34 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
   // CoverageMappingModuleGen object.
   if (CodeGenOpts.CoverageMapping)
     CoverageMapping.reset(new CoverageMappingModuleGen(*this, *CoverageInfo));
+
+  // Generate the module name hash here if needed.
+  if (CodeGenOpts.UniqueInternalLinkageNames &&
+      !getModule().getSourceFileName().empty()) {
+    std::string Path = getModule().getSourceFileName();
+    // Check if a path substitution is needed from the MacroPrefixMap.
+    for (const auto &Entry : PPO.MacroPrefixMap)
+      if (Path.rfind(Entry.first, 0) != std::string::npos) {
+        Path = Entry.second + Path.substr(Entry.first.size());
+        break;
+      }
+    llvm::MD5 Md5;
+    Md5.update(Path);
+    llvm::MD5::MD5Result R;
+    Md5.final(R);
+    SmallString<32> Str;
+    llvm::MD5::stringifyResult(R, Str);
+    // Convert MD5hash to Decimal. Demangler suffixes can either contain
+    // numbers or characters but not both.
+    llvm::APInt IntHash(128, Str.str(), 16);
+    // Prepend "__uniq" before the hash for tools like profilers to understand
+    // that this symbol is of internal linkage type.  The "__uniq" is the
+    // pre-determined prefix that is used to tell tools that this symbol was
+    // created with -funique-internal-linakge-symbols and the tools can strip or
+    // keep the prefix as needed.
+    ModuleNameHash = (Twine(".__uniq.") +
+        Twine(IntHash.toString(/* Radix = */ 10, /* Signed = */false))).str();
+  }
 }
 
 CodeGenModule::~CodeGenModule() {}
@@ -1147,13 +1175,30 @@ static void AppendTargetMangling(const CodeGenModule &CGM,
   }
 }
 
-static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD,
+// Returns true if GD is a function/var decl with internal linkage and
+// needs a unique suffix after the mangled name.
+static bool isUniqueInternalLinkageDecl(GlobalDecl GD,
+                                        CodeGenModule &CGM) {
+  const Decl *D = GD.getDecl();
+  if (!CGM.getModuleNameHash().empty() &&
+      ((isa<FunctionDecl>(D) &&
+        CGM.getFunctionLinkage(GD) == llvm::GlobalValue::InternalLinkage) ||
+       (isa<VarDecl>(D) && CGM.getContext().GetGVALinkageForVariable(
+                               cast<VarDecl>(D)) == GVA_Internal)))
+    return true;
+  return false;
+}
+
+static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
                                       const NamedDecl *ND,
                                       bool OmitMultiVersionMangling = false) {
   SmallString<256> Buffer;
   llvm::raw_svector_ostream Out(Buffer);
   MangleContext &MC = CGM.getCXXABI().getMangleContext();
-  if (MC.shouldMangleDeclName(ND))
+  if (!CGM.getModuleNameHash().empty())
+    MC.needsUniqueInternalLinkageNames();
+  bool ShouldMangle = MC.shouldMangleDeclName(ND);
+  if (ShouldMangle)
     MC.mangleName(GD.getWithDecl(ND), Out);
   else {
     IdentifierInfo *II = ND->getIdentifier();
@@ -1171,6 +1216,20 @@ static std::string getMangledNameImpl(const CodeGenModule &CGM, GlobalDecl GD,
     }
   }
 
+  // Check if the module name hash should be appended for internal linkage
+  // symbols.   This should come before multi-version target suffixes are
+  // appended. This is to keep the name and module hash suffix of the
+  // internal linkage function together.  The unique suffix should only be
+  // added when name mangling is done to make sure that the final name can
+  // be properly demangled.  For example, for C functions without prototypes,
+  // name mangling is not done and the unique suffix should not be appeneded
+  // then.
+  if (ShouldMangle && isUniqueInternalLinkageDecl(GD, CGM)) {
+    assert(CGM.getCodeGenOpts().UniqueInternalLinkageNames &&
+           "Hash computed when not explicitly requested");
+    Out << CGM.getModuleNameHash();
+  }
+
   if (const auto *FD = dyn_cast<FunctionDecl>(ND))
     if (FD->isMultiVersion() && !OmitMultiVersionMangling) {
       switch (FD->getMultiVersionKind()) {

diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a22438382dbd..ad432445e315 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -28,6 +28,7 @@
 #include "clang/Basic/NoSanitizeList.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/XRayLists.h"
+#include "clang/Lex/PreprocessorOptions.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -72,7 +73,6 @@ class VarDecl;
 class LangOptions;
 class CodeGenOptions;
 class HeaderSearchOptions;
-class PreprocessorOptions;
 class DiagnosticsEngine;
 class AnnotateAttr;
 class CXXDestructorDecl;
@@ -311,6 +311,7 @@ class CodeGenModule : public CodeGenTypeCache {
   const TargetInfo &Target;
   std::unique_ptr<CGCXXABI> ABI;
   llvm::LLVMContext &VMContext;
+  std::string ModuleNameHash = "";
 
   std::unique_ptr<CodeGenTBAA> TBAA;
 
@@ -586,6 +587,8 @@ class CodeGenModule : public CodeGenTypeCache {
   /// Return true iff an Objective-C runtime has been configured.
   bool hasObjCRuntime() { return !!ObjCRuntime; }
 
+  const std::string &getModuleNameHash() const { return ModuleNameHash; }
+
   /// Return a reference to the configured OpenCL runtime.
   CGOpenCLRuntime &getOpenCLRuntime() {
     assert(OpenCLRuntime != nullptr);

diff  --git a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c
new file mode 100644
index 000000000000..916d293f2e5a
--- /dev/null
+++ b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.c
@@ -0,0 +1,28 @@
+// This test checks if C functions with internal linkage names are mangled
+// and the module hash suffixes attached including emitting DW_AT_linkage_name.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=4 -emit-llvm -o -  %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=4 -funique-internal-linkage-names -emit-llvm -o -  %s | FileCheck %s --check-prefix=UNIQUE
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=5 -emit-llvm -o -  %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=5 -funique-internal-linkage-names -emit-llvm -o -  %s | FileCheck %s --check-prefix=UNIQUE
+
+static int glob;
+static int foo(void) {
+  return glob;
+}
+
+void baz() {
+  foo();
+}
+
+// PLAIN: @glob = internal global i32
+// PLAIN: define internal i32 @foo()
+// PLAIN: distinct !DIGlobalVariable(name: "glob"{{.*}})
+// PLAIN: distinct !DISubprogram(name: "foo"{{.*}})
+// PLAIN-NOT: linkageName:
+//
+// UNIQUE: @_ZL4glob.[[MODHASH:__uniq.[0-9]+]] = internal global i32
+// UNIQUE: define internal i32 @_ZL3foov.[[MODHASH]]()
+// UNIQUE: distinct !DIGlobalVariable(name: "glob", linkageName: "_ZL4glob.[[MODHASH]]"{{.*}})
+// UNIQUE: distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.[[MODHASH]]"{{.*}})

diff  --git a/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp
new file mode 100644
index 000000000000..41b13754396e
--- /dev/null
+++ b/clang/test/CodeGen/unique-internal-linkage-names-dwarf.cpp
@@ -0,0 +1,60 @@
+// This test checks if C++ functions with internal linkage names are mangled
+// and the module hash suffixes attached including emitting DW_AT_linkage_name.
+//
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=4 -emit-llvm -o - %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=4 -funique-internal-linkage-names -emit-llvm -o - %s | FileCheck %s --check-prefix=UNIQUE
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=5 -emit-llvm -o - %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -debug-info-kind=limited -dwarf-version=5 -funique-internal-linkage-names -emit-llvm -o - %s | FileCheck %s --check-prefix=UNIQUE
+
+static int glob_foo = 5;
+static int foo(void) {
+  __builtin_printf("%p", &glob_foo);
+  return glob_foo;
+}
+
+// Anonymous namespaces generate internal linkage symbols.
+namespace {
+  int glob_bar;
+  int bar() {
+    return glob_bar;
+  }
+}
+
+extern "C" {
+  static int glob_zip;
+  static int zip(void) {
+    return glob_zip;
+  }
+}
+
+void baz() {
+  foo();
+  bar();
+  zip();
+}
+
+// PLAIN-DAG: @_ZL8glob_foo = internal global i32
+// PLAIN-DAG: define internal i32 @_ZL3foov()
+// PLAIN-DAG: distinct !DIGlobalVariable(name: "glob_foo", linkageName: "_ZL8glob_foo"{{.*}})
+// PLAIN-DAG: distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov"{{.*}})
+// PLAIN-DAG: @_ZN12_GLOBAL__N_18glob_barE = internal global i32
+// PLAIN-DAG: define internal i32 @_ZN12_GLOBAL__N_13barEv()
+// PLAIN-DAG: distinct !DIGlobalVariable(name: "glob_bar", linkageName: "_ZN12_GLOBAL__N_18glob_barE"{{.*}})
+// PLAIN-DAG: distinct !DISubprogram(name: "bar", linkageName: "_ZN12_GLOBAL__N_13barEv"{{.*}})
+// PLAIN-DAG: @_ZL8glob_zip = internal global i32
+// PLAIN-DAG: define internal i32 @_ZL3zipv()
+// PLAIN-DAG: distinct !DIGlobalVariable(name: "glob_zip", linkageName: "_ZL8glob_zip"{{.*}})
+// PLAIN-DAG: distinct !DISubprogram(name: "zip", linkageName: "_ZL3zipv"{{.*}})
+
+// UNIQUE-DAG: @_ZL8glob_foo.[[MODHASH:__uniq\.[0-9]+]] = internal global i32
+// UNIQUE-DAG: define internal i32 @_ZL3foov.[[MODHASH]]()
+// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_foo", linkageName: "_ZL8glob_foo.[[MODHASH]]"{{.*}})
+// UNIQUE-DAG: distinct !DISubprogram(name: "foo", linkageName: "_ZL3foov.[[MODHASH]]"{{.*}})
+// UNIQUE-DAG: @_ZN12_GLOBAL__N_18glob_barE.[[MODHASH]] = internal global i32
+// UNIQUE-DAG: define internal i32 @_ZN12_GLOBAL__N_13barEv.[[MODHASH]]()
+// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_bar", linkageName: "_ZN12_GLOBAL__N_18glob_barE.[[MODHASH]]"{{.*}})
+// UNIQUE-DAG: distinct !DISubprogram(name: "bar", linkageName: "_ZN12_GLOBAL__N_13barEv.[[MODHASH]]"{{.*}})
+// UNIQUE-DAG: @_ZL8glob_zip.[[MODHASH]] = internal global i32
+// UNIQUE-DAG: define internal i32 @_ZL3zipv.[[MODHASH]]()
+// UNIQUE-DAG: distinct !DIGlobalVariable(name: "glob_zip", linkageName: "_ZL8glob_zip.[[MODHASH]]"{{.*}})
+// UNIQUE-DAG: distinct !DISubprogram(name: "zip", linkageName: "_ZL3zipv.[[MODHASH]]"{{.*}})

diff  --git a/clang/test/CodeGen/unique-internal-linkage-names.cpp b/clang/test/CodeGen/unique-internal-linkage-names.cpp
index b731ed07f4a7..d3949a186803 100644
--- a/clang/test/CodeGen/unique-internal-linkage-names.cpp
+++ b/clang/test/CodeGen/unique-internal-linkage-names.cpp
@@ -1,10 +1,7 @@
 // This test checks if internal linkage symbols get unique names with
 // -funique-internal-linkage-names option.
 // RUN: %clang_cc1 -triple x86_64 -x c++ -S -emit-llvm -o - < %s | FileCheck %s --check-prefix=PLAIN
-// RUN: %clang_cc1 -triple x86_64 -x c++ -O0 -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
-// RUN: %clang_cc1 -triple x86_64 -x c++ -O1 -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUEO1
-// RUN: %clang_cc1 -triple x86_64 -x c++ -O0 -S -emit-llvm -fexperimental-new-pass-manager -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
-// RUN: %clang_cc1 -triple x86_64 -x c++ -O1 -S -emit-llvm -fexperimental-new-pass-manager -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUEO1
+// RUN: %clang_cc1 -triple x86_64 -x c++  -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE
 
 static int glob;
 static int foo() {
@@ -53,15 +50,13 @@ int mver_call() {
 // PLAIN: define weak_odr i32 ()* @_ZL4mverv.resolver()
 // PLAIN: define internal i32 @_ZL4mverv()
 // PLAIN: define internal i32 @_ZL4mverv.sse4.2()
+// PLAIN-NOT: "sample-profile-suffix-elision-policy"
 // UNIQUE: @_ZL4glob.__uniq.{{[0-9]+}} = internal global
 // UNIQUE: @_ZZ8retAnonMvE5fGlob.__uniq.{{[0-9]+}} = internal global
 // UNIQUE: @_ZN12_GLOBAL__N_16anon_mE.__uniq.{{[0-9]+}} = internal global
-// UNIQUE: define internal i32 @_ZL3foov.__uniq.{{[0-9]+}}()
+// UNIQUE: define internal i32 @_ZL3foov.__uniq.{{[0-9]+}}() #[[#ATTR:]] {
 // UNIQUE: define internal i32 @_ZN12_GLOBAL__N_14getMEv.__uniq.{{[0-9]+}}
-// UNIQUE: define weak_odr i32 ()* @_ZL4mverv.resolver()
+// UNIQUE: define weak_odr i32 ()* @_ZL4mverv.__uniq.{{[0-9]+}}.resolver()
 // UNIQUE: define internal i32 @_ZL4mverv.__uniq.{{[0-9]+}}()
-// UNIQUE: define internal i32 @_ZL4mverv.sse4.2.__uniq.{{[0-9]+}}
-// UNIQUEO1: define internal i32 @_ZL3foov.__uniq.{{[0-9]+}}()
-// UNIQUEO1: define weak_odr i32 ()* @_ZL4mverv.resolver()
-// UNIQUEO1: define internal i32 @_ZL4mverv.__uniq.{{[0-9]+}}()
-// UNIQUEO1: define internal i32 @_ZL4mverv.sse4.2.__uniq.{{[0-9]+}}
+// UNIQUE: define internal i32 @_ZL4mverv.__uniq.{{[0-9]+}}.sse4.2
+// UNIQUE: attributes #[[#ATTR]] = { {{.*}}"sample-profile-suffix-elision-policy"{{.*}} }


        


More information about the cfe-commits mailing list