summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/test/CodeGenCXX/attr-cpuspecific.cpp23
2 files changed, 31 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 227b8833342..f55fa3f1bcb 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2538,7 +2538,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);
@@ -2564,7 +2570,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..57b45e1da2e
--- /dev/null
+++ b/clang/test/CodeGenCXX/attr-cpuspecific.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,LINUX
+// RUN: %clang_cc1 -triple x86_64-windows-pc -fms-compatibility -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WINDOWS
+
+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
+
+// WINDOWS: define dso_local void @"?Func@S@@QEAAXXZ"(%struct.S*)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.S"(%struct.S* %0)
+// WINDOWS: musttail call void @"?Func@S@@QEAAXXZ.O"(%struct.S* %0)
+
OpenPOWER on IntegriCloud