]> granicus.if.org Git - clang/commitdiff
Merging r345838:
authorTom Stellard <tstellar@redhat.com>
Sat, 8 Dec 2018 04:54:24 +0000 (04:54 +0000)
committerTom Stellard <tstellar@redhat.com>
Sat, 8 Dec 2018 04:54:24 +0000 (04:54 +0000)
------------------------------------------------------------------------
r345838 | erichkeane | 2018-11-01 08:11:41 -0700 (Thu, 01 Nov 2018) | 8 lines

CPU-Dispatch- Fix type of a member function, prevent deferrals

The member type creation for a cpu-dispatch function was not correctly
including the 'this' parameter, so ensure that the type is properly
determined. Also, disable defer in the cases of emitting the functoins,
as it can end up resulting in the wrong version being emitted.

Change-Id: I0b8fc5e0b0d1ae1a9d98fd54f35f27f6e5d5d083
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_70@348684 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/attr-cpuspecific.cpp [new file with mode: 0644]

index 448a8b298e83f5fd1f5ac4d72514324512f0c611..3e33735c504073134d6c4ebc63375d5c19bae76e 100644 (file)
@@ -2467,7 +2467,13 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
   assert(FD && "Not a FunctionDecl?");
   const auto *DD = FD->getAttr<CPUDispatchAttr>();
   assert(DD && "Not a cpu_dispatch Function?");
-  llvm::Type *DeclTy = getTypes().ConvertTypeForMem(FD->getType());
+  QualType CanonTy = Context.getCanonicalType(FD->getType());
+  llvm::Type *DeclTy = getTypes().ConvertFunctionType(CanonTy, FD);
+
+  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
+    const CGFunctionInfo &FInfo = getTypes().arrangeCXXMethodDeclaration(CXXFD);
+    DeclTy = getTypes().GetFunctionType(FInfo);
+  }
 
   StringRef ResolverName = getMangledName(GD);
   llvm::Type *ResolverType = llvm::FunctionType::get(
@@ -2485,7 +2491,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) {
     std::string MangledName = getMangledNameImpl(*this, GD, FD, true) +
                               getCPUSpecificMangling(*this, II->getName());
     llvm::Constant *Func = GetOrCreateLLVMFunction(
-        MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/false,
+        MangledName, DeclTy, GD, /*ForVTable=*/false, /*DontDefer=*/true,
         /*IsThunk=*/false, llvm::AttributeList(), ForDefinition);
     llvm::SmallVector<StringRef, 32> Features;
     Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features);
diff --git a/test/CodeGenCXX/attr-cpuspecific.cpp b/test/CodeGenCXX/attr-cpuspecific.cpp
new file mode 100644 (file)
index 0000000..ae5702f
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
+
+struct S {
+  __attribute__((cpu_specific(atom)))
+  void Func(){}
+  __attribute__((cpu_dispatch(ivybridge,atom)))
+  void Func(){}
+};
+
+void foo() {
+  S s;
+  s.Func();
+}
+
+// LINUX: define void (%struct.S*)* @_ZN1S4FuncEv.resolver
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.S
+// LINUX: ret void (%struct.S*)* @_ZN1S4FuncEv.O