[clang] 2bcba21 - [CPU-Dispatch] Make sure Dispatch names get updated if previously mangled

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 14 10:45:59 PST 2022


Author: Erich Keane
Date: 2022-01-14T10:45:55-08:00
New Revision: 2bcba21c8ba95de866ed6333fa5cd29d5d232afe

URL: https://github.com/llvm/llvm-project/commit/2bcba21c8ba95de866ed6333fa5cd29d5d232afe
DIFF: https://github.com/llvm/llvm-project/commit/2bcba21c8ba95de866ed6333fa5cd29d5d232afe.diff

LOG: [CPU-Dispatch] Make sure Dispatch names get updated if previously mangled

Cases where there is a mangling of a cpu-dispatch/cpu-specific function
before the function becomes 'multiversion' (such as a member function)
causes the wrong name to be emitted for one of the variants/resolver,
since the name is cached.  Make sure we invalidate the cache in
cpu-dispatch/cpu-specific modes, like we previously did for just target
multiversioning.

Added: 
    clang/test/CodeGen/attr-cpuspecific-renaming.cpp

Modified: 
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/CodeGen/CodeGenModule.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 42dfce32ed131..bd6fc49beda00 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1368,7 +1368,8 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
 }
 
 void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD,
-                                            const FunctionDecl *FD) {
+                                            const FunctionDecl *FD,
+                                            StringRef &CurName) {
   if (!FD->isMultiVersion())
     return;
 
@@ -1400,7 +1401,11 @@ void CodeGenModule::UpdateMultiVersionNames(GlobalDecl GD,
       if (ExistingRecord != std::end(Manglings))
         Manglings.remove(&(*ExistingRecord));
       auto Result = Manglings.insert(std::make_pair(OtherName, OtherGD));
-      MangledDeclNames[OtherGD.getCanonicalDecl()] = Result.first->first();
+      StringRef OtherNameRef = MangledDeclNames[OtherGD.getCanonicalDecl()] =
+          Result.first->first();
+      // If this is the current decl is being created, make sure we update the name.
+      if (GD.getCanonicalDecl() == OtherGD.getCanonicalDecl())
+        CurName = OtherNameRef;
       if (llvm::GlobalValue *Entry = GetGlobalValue(NonTargetName))
         Entry->setName(OtherName);
     }
@@ -3490,6 +3495,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
   }
 
   StringRef ResolverName = getMangledName(GD);
+  UpdateMultiVersionNames(GD, FD, ResolverName);
 
   llvm::Type *ResolverType;
   GlobalDecl ResolverGD;
@@ -3498,8 +3504,6 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
         llvm::PointerType::get(DeclTy,
                                Context.getTargetAddressSpace(FD->getType())),
         false);
-    assert(ResolverName.endswith(".resolver") &&
-           "CPUDispatch IFunc resolver doesn't end with .resolver??");
   }
   else {
     ResolverType = DeclTy;
@@ -3692,8 +3696,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
     }
 
     if (FD->isMultiVersion()) {
-      if (FD->hasAttr<TargetAttr>())
-        UpdateMultiVersionNames(GD, FD);
+        UpdateMultiVersionNames(GD, FD, MangledName);
       if (!IsForDefinition)
         return GetOrCreateMultiVersionResolver(GD, Ty, FD);
     }

diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index f18de6e4b861c..9ae9d624b925d 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1468,7 +1468,8 @@ class CodeGenModule : public CodeGenTypeCache {
   llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD,
                                                   llvm::Type *DeclTy,
                                                   const FunctionDecl *FD);
-  void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD);
+  void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD,
+                               StringRef &CurName);
 
   llvm::Constant *
   GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace,

diff  --git a/clang/test/CodeGen/attr-cpuspecific-renaming.cpp b/clang/test/CodeGen/attr-cpuspecific-renaming.cpp
new file mode 100644
index 0000000000000..f014f07ac246c
--- /dev/null
+++ b/clang/test/CodeGen/attr-cpuspecific-renaming.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=CHECK,LIN
+// RUN: %clang_cc1 -triple x86_64-windows-pc -emit-llvm -o - -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb %s | FileCheck %s --check-prefixes=CHECK,WIN
+
+// LIN: @[[S1_NAME:.+]].ifunc = weak_odr ifunc void (%struct.S1*), void (%struct.S1*)* ()* @[[S1_NAME]].resolver
+// LIN: @[[S2_NAME:.+]].ifunc = weak_odr ifunc void (%struct.S2*), void (%struct.S2*)* ()* @[[S2_NAME]].resolver
+// WIN: $"[[S1_NAME:.+]]" = comdat any
+// WIN: $"[[S2_NAME:.+]]" = comdat any
+
+struct S1 {
+  void foo();
+  void mv();
+};
+
+void S1::foo(){}
+
+__attribute__((cpu_dispatch(ivybridge, generic)))
+void S1::mv() {}
+// LIN: define weak_odr void (%struct.S1*)* @[[S1_NAME]].resolver
+// WIN: define weak_odr dso_local void @"[[S1_NAME]]"(%struct.S1*
+__attribute__((cpu_specific(generic)))
+void S1::mv() {}
+// CHECK: define dso_local {{.*}}void @{{\"?}}[[S1_NAME]].S{{\"?}}
+// CHECK: define dso_local {{.*}}void @{{\"?}}[[S1_NAME]].A{{\"?}}
+__attribute__((cpu_specific(ivybridge)))
+void S1::mv() {}
+
+struct S2 {
+  void foo();
+  void mv();
+};
+
+void S2::foo(){}
+
+__attribute__((cpu_specific(generic)))
+void S2::mv() {}
+// CHECK: define dso_local {{.*}}void @{{\"?}}[[S2_NAME]].A{{\"?}}
+__attribute__((cpu_dispatch(ivybridge, generic)))
+void S2::mv() {}
+// LIN: define weak_odr void (%struct.S2*)* @[[S2_NAME]].resolver
+// WIN: define weak_odr dso_local void @"[[S2_NAME]]"(%struct.S2*
+__attribute__((cpu_specific(ivybridge)))
+void S2::mv() {}
+// CHECK: define dso_local {{.*}}void @{{\"?}}[[S2_NAME]].S{{\"?}}


        


More information about the cfe-commits mailing list