diff options
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/attr-cpuspecific.cpp | 17 |
2 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 448a8b298e8..3e33735c504 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -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/clang/test/CodeGenCXX/attr-cpuspecific.cpp b/clang/test/CodeGenCXX/attr-cpuspecific.cpp new file mode 100644 index 00000000000..ae5702feb8c --- /dev/null +++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp @@ -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 |