From ed4a11b99a3071d3e1297ac627e4f3a268c90fc7 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Thu, 1 Nov 2018 15:11:41 +0000 Subject: [PATCH] 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/trunk@345838 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 10 ++++++++-- test/CodeGenCXX/attr-cpuspecific.cpp | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/CodeGenCXX/attr-cpuspecific.cpp diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 227b883334..f55fa3f1bc 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2538,7 +2538,13 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { assert(FD && "Not a FunctionDecl?"); const auto *DD = FD->getAttr(); 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(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 Features; Target.getCPUSpecificCPUDispatchFeatures(II->getName(), Features); diff --git a/test/CodeGenCXX/attr-cpuspecific.cpp b/test/CodeGenCXX/attr-cpuspecific.cpp new file mode 100644 index 0000000000..57b45e1da2 --- /dev/null +++ b/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) + -- 2.50.1