diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -751,6 +751,7 @@ public: AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo(Triple, Opts) { + this->MCountName = "__mcount"; this->TheCXXABI.set(TargetCXXABI::XL); if (this->PointerWidth == 64) { diff --git a/clang/test/CodeGen/mcount-aix.c b/clang/test/CodeGen/mcount-aix.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/mcount-aix.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -pg -triple powerpc-ibm-aix7.2.0.0 -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -pg -triple powerpc64-ibm-aix7.2.0.0 -S -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK64 + +void foo() { +} + +void bar() { + foo(); +} +// CHECK: @[[GLOB0:[0-9]+]] = internal global i32 0 +// CHECK: @[[GLOB1:[0-9]+]] = internal global i32 0 +// CHECK64: @[[GLOB0:[0-9]+]] = internal global i64 0 +// CHECK64: @[[GLOB1:[0-9]+]] = internal global i64 0 +// CHECK-LABEL: @foo( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @__mcount(ptr @[[GLOB0]]) +// CHECK64-LABEL: @foo( +// CHECK64-NEXT: entry: +// CHECK64-NEXT: call void @__mcount(ptr @[[GLOB0]]) +// CHECK-LABEL: @bar( +// CHECK-NEXT: entry: +// CHECK-NEXT: call void @__mcount(ptr @[[GLOB1]]) +// CHECK64-LABEL: @bar( +// CHECK64-NEXT: entry: +// CHECK64-NEXT: call void @__mcount(ptr @[[GLOB1]]) diff --git a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp --- a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp +++ b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" +#include "llvm/ADT/Triple.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Dominators.h" @@ -34,9 +35,24 @@ Func == "__mcount" || Func == "_mcount" || Func == "__cyg_profile_func_enter_bare") { - FunctionCallee Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C)); - CallInst *Call = CallInst::Create(Fn, "", InsertionPt); - Call->setDebugLoc(DL); + Triple TargetTriple(M.getTargetTriple()); + if (TargetTriple.isOSAIX() && Func == "__mcount") { + Type *SizeTy = M.getDataLayout().getIntPtrType(C); + Type *SizePtrTy = SizeTy->getPointerTo(); + GlobalVariable *GV = new GlobalVariable(M, SizeTy, /*isConstant=*/false, + GlobalValue::InternalLinkage, + ConstantInt::get(SizeTy, 0)); + CallInst *Call = CallInst::Create( + M.getOrInsertFunction(Func, + FunctionType::get(Type::getVoidTy(C), {SizePtrTy}, + /*isVarArg=*/false)), + {GV}, "", InsertionPt); + Call->setDebugLoc(DL); + } else { + FunctionCallee Fn = M.getOrInsertFunction(Func, Type::getVoidTy(C)); + CallInst *Call = CallInst::Create(Fn, "", InsertionPt); + Call->setDebugLoc(DL); + } return; }