Thanks!
On Mon, Sep 14, 2015 at 10:50 AM, Samuel F Antao <sfan...@us.ibm.com> wrote: > Hi Evgeniy, > > I commit a small change to one of the regression tests to allow a signext to > be generated: http://reviews.llvm.org/rL247584. > > It was causing an error in Power8 targets. In my view is an harmless change > but you may want to take a look and see if that is fine by you. > > Thanks! > Samuel > > 2015-09-11 21:07 GMT-04:00 Evgeniy Stepanov via cfe-commits > <cfe-commits@lists.llvm.org>: >> >> Author: eugenis >> Date: Fri Sep 11 20:07:37 2015 >> New Revision: 247494 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=247494&view=rev >> Log: >> Always_inline codegen rewrite. >> >> Current implementation may end up emitting an undefined reference for >> an "inline __attribute__((always_inline))" function by generating an >> "available_externally alwaysinline" IR function for it and then failing to >> inline all the calls. This happens when a call to such function is in dead >> code. As the inliner is an SCC pass, it does not process dead code. >> >> Libc++ relies on the compiler never emitting such undefined reference. >> >> With this patch, we emit a pair of >> 1. internal alwaysinline definition (called F.alwaysinline) >> 2a. A stub F() { musttail call F.alwaysinline } >> -- or, depending on the linkage -- >> 2b. A declaration of F. >> >> The frontend ensures that F.inlinefunction is only used for direct >> calls, and the stub is used for everything else (taking the address of >> the function, really). Declaration (2b) is emitted in the case when >> "inline" is meant for inlining only (like __gnu_inline__ and some >> other cases). >> >> This approach, among other nice properties, ensures that alwaysinline >> functions are always internal, making it impossible for a direct call >> to such function to produce an undefined symbol reference. >> >> This patch is based on ideas by Chandler Carruth and Richard Smith. >> >> Added: >> cfe/trunk/test/CodeGen/always_inline-unused.c >> cfe/trunk/test/CodeGen/always_inline-wrappers.c >> cfe/trunk/test/CodeGenCXX/alwaysinline.cpp >> Modified: >> cfe/trunk/lib/CodeGen/CGCXX.cpp >> cfe/trunk/lib/CodeGen/CGClass.cpp >> cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp >> cfe/trunk/lib/CodeGen/CodeGenModule.cpp >> cfe/trunk/lib/CodeGen/CodeGenModule.h >> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >> cfe/trunk/test/CodeGen/always-inline.c >> cfe/trunk/test/CodeGen/always_inline.c >> cfe/trunk/test/CodeGen/function-attributes.c >> cfe/trunk/test/CodeGen/pr9614.c >> cfe/trunk/test/Frontend/optimization-remark-line-directive.c >> cfe/trunk/test/Frontend/optimization-remark.c >> cfe/trunk/test/Modules/cxx-irgen.cpp >> >> Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGCXX.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Sep 11 20:07:37 2015 >> @@ -109,6 +109,9 @@ bool CodeGenModule::TryEmitBaseDestructo >> D->getType()->getAs<FunctionType>()->getCallConv()) >> return true; >> >> + if (BaseD->hasAttr<AlwaysInlineAttr>()) >> + return true; >> + >> return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base), >> GlobalDecl(BaseD, Dtor_Base), >> false); >> @@ -161,14 +164,7 @@ bool CodeGenModule::TryEmitDefinitionAsA >> >> // Instead of creating as alias to a linkonce_odr, replace all of the >> uses >> // of the aliasee. >> - if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && >> - (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage || >> - !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { >> - // FIXME: An extern template instantiation will create functions with >> - // linkage "AvailableExternally". In libc++, some classes also define >> - // members with attribute "AlwaysInline" and expect no reference to >> - // be generated. It is desirable to reenable this optimisation after >> - // corresponding LLVM changes. >> + if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) { >> Replacements[MangledName] = Aliasee; >> return false; >> } >> >> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Fri Sep 11 20:07:37 2015 >> @@ -1557,7 +1557,7 @@ void CodeGenFunction::EmitDestructorBody >> // -fapple-kext must inline any call to this dtor into >> // the caller's body. >> if (getLangOpts().AppleKext) >> - CurFn->addFnAttr(llvm::Attribute::AlwaysInline); >> + CGM.AddAlwaysInlineFunction(CurFn); >> >> break; >> } >> >> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Fri Sep 11 20:07:37 2015 >> @@ -2114,7 +2114,7 @@ emitTaskPrivateMappingFunction(CodeGenMo >> ".omp_task_privates_map.", &CGM.getModule()); >> CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskPrivatesMapFnInfo, >> TaskPrivatesMap); >> - TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline); >> + CGM.AddAlwaysInlineFunction(TaskPrivatesMap); >> CodeGenFunction CGF(CGM); >> CGF.disableDebugInfo(); >> CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap, >> >> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Sep 11 20:07:37 2015 >> @@ -448,6 +448,109 @@ void CodeGenModule::Release() { >> EmitVersionIdentMetadata(); >> >> EmitTargetMetadata(); >> + >> + RewriteAlwaysInlineFunctions(); >> +} >> + >> +void CodeGenModule::AddAlwaysInlineFunction(llvm::Function *Fn) { >> + AlwaysInlineFunctions.push_back(Fn); >> +} >> + >> +/// Find all uses of GV that are not direct calls or invokes. >> +static void FindNonDirectCallUses(llvm::GlobalValue *GV, >> + llvm::SmallVectorImpl<llvm::Use *> >> *Uses) { >> + llvm::GlobalValue::use_iterator UI = GV->use_begin(), E = >> GV->use_end(); >> + for (; UI != E;) { >> + llvm::Use &U = *UI; >> + ++UI; >> + >> + llvm::CallSite CS(U.getUser()); >> + bool isDirectCall = (CS.isCall() || CS.isInvoke()) && >> CS.isCallee(&U); >> + if (!isDirectCall) >> + Uses->push_back(&U); >> + } >> +} >> + >> +/// Replace a list of uses. >> +static void ReplaceUsesWith(const llvm::SmallVectorImpl<llvm::Use *> >> &Uses, >> + llvm::GlobalValue *V, >> + llvm::GlobalValue *Replacement) { >> + for (llvm::Use *U : Uses) { >> + auto *C = dyn_cast<llvm::Constant>(U->getUser()); >> + if (C && !isa<llvm::GlobalValue>(C)) >> + C->handleOperandChange(V, Replacement, U); >> + else >> + U->set(Replacement); >> + } >> +} >> + >> +void CodeGenModule::RewriteAlwaysInlineFunction(llvm::Function *Fn) { >> + std::string Name = Fn->getName(); >> + std::string InlineName = Name + ".alwaysinline"; >> + Fn->setName(InlineName); >> + >> + llvm::SmallVector<llvm::Use *, 8> NonDirectCallUses; >> + Fn->removeDeadConstantUsers(); >> + FindNonDirectCallUses(Fn, &NonDirectCallUses); >> + // Do not create the wrapper if there are no non-direct call uses, and >> we are >> + // not required to emit an external definition. >> + if (NonDirectCallUses.empty() && Fn->isDiscardableIfUnused()) >> + return; >> + >> + llvm::FunctionType *FT = Fn->getFunctionType(); >> + llvm::LLVMContext &Ctx = getModule().getContext(); >> + llvm::Function *StubFn = >> + llvm::Function::Create(FT, Fn->getLinkage(), Name, &getModule()); >> + assert(StubFn->getName() == Name && "name was uniqued!"); >> + >> + // Insert the stub immediately after the original function. Helps with >> the >> + // fragile tests, among other things. >> + StubFn->removeFromParent(); >> + TheModule.getFunctionList().insertAfter(Fn, StubFn); >> + >> + StubFn->copyAttributesFrom(Fn); >> + StubFn->setPersonalityFn(nullptr); >> + >> + // AvailableExternally functions are replaced with a declaration. >> + // Everyone else gets a wrapper that musttail-calls the original >> function. >> + if (Fn->hasAvailableExternallyLinkage()) { >> + StubFn->setLinkage(llvm::GlobalValue::ExternalLinkage); >> + } else { >> + llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", >> StubFn); >> + std::vector<llvm::Value *> Args; >> + for (llvm::Function::arg_iterator ai = StubFn->arg_begin(); >> + ai != StubFn->arg_end(); ++ai) >> + Args.push_back(&*ai); >> + llvm::CallInst *CI = llvm::CallInst::Create(Fn, Args, "", BB); >> + CI->setCallingConv(Fn->getCallingConv()); >> + CI->setTailCallKind(llvm::CallInst::TCK_MustTail); >> + CI->setAttributes(Fn->getAttributes()); >> + if (FT->getReturnType()->isVoidTy()) >> + llvm::ReturnInst::Create(Ctx, BB); >> + else >> + llvm::ReturnInst::Create(Ctx, CI, BB); >> + } >> + >> + if (Fn->hasComdat()) >> + StubFn->setComdat(Fn->getComdat()); >> + >> + ReplaceUsesWith(NonDirectCallUses, Fn, StubFn); >> + >> + // Replace all metadata uses with the stub. This is primarily to >> reattach >> + // DISubprogram metadata to the stub, because that's what will be >> emitted in >> + // the object file. >> + if (Fn->isUsedByMetadata()) >> + llvm::ValueAsMetadata::handleRAUW(Fn, StubFn); >> +} >> + >> +void CodeGenModule::RewriteAlwaysInlineFunctions() { >> + for (llvm::Function *Fn : AlwaysInlineFunctions) { >> + RewriteAlwaysInlineFunction(Fn); >> + Fn->setLinkage(llvm::GlobalValue::InternalLinkage); >> + Fn->addFnAttr(llvm::Attribute::AlwaysInline); >> + Fn->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); >> + Fn->setVisibility(llvm::GlobalValue::DefaultVisibility); >> + } >> } >> >> void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { >> @@ -772,7 +875,7 @@ void CodeGenModule::SetLLVMFunctionAttri >> >> !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, >> llvm::Attribute::NoInline)) >> { >> // (noinline wins over always_inline, and we can't specify both in >> IR) >> - B.addAttribute(llvm::Attribute::AlwaysInline); >> + AddAlwaysInlineFunction(F); >> } >> >> if (D->hasAttr<ColdAttr>()) { >> >> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original) >> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Sep 11 20:07:37 2015 >> @@ -489,6 +489,8 @@ private: >> /// MDNodes. >> llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap; >> >> + llvm::SmallVector<llvm::Function*, 8> AlwaysInlineFunctions; >> + >> public: >> CodeGenModule(ASTContext &C, const HeaderSearchOptions >> &headersearchopts, >> const PreprocessorOptions &ppopts, >> @@ -1131,6 +1133,8 @@ public: >> /// \breif Get the declaration of std::terminate for the platform. >> llvm::Constant *getTerminateFn(); >> >> + void AddAlwaysInlineFunction(llvm::Function *Fn); >> + >> private: >> llvm::Constant * >> GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, >> GlobalDecl D, >> @@ -1226,6 +1230,12 @@ private: >> /// Emits target specific Metadata for global declarations. >> void EmitTargetMetadata(); >> >> + /// Replaces alwaysinline functions with a pair of internal >> xxx.inlinefunction >> + /// for direct calls, and a stub for indirect calls, and rewrites all >> uses of >> + /// those. >> + void RewriteAlwaysInlineFunctions(); >> + void RewriteAlwaysInlineFunction(llvm::Function *Fn); >> + >> /// Emit the llvm.gcov metadata used to tell LLVM where to emit the >> .gcno and >> /// .gcda files in a way that persists in .bc files. >> void EmitCoverageFile(); >> >> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) >> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Fri Sep 11 20:07:37 2015 >> @@ -3311,6 +3311,9 @@ static StructorCodegen getCodegenToUse(C >> if (MD->getParent()->getNumVBases()) >> return StructorCodegen::Emit; >> >> + if (MD->hasAttr<AlwaysInlineAttr>()) >> + return StructorCodegen::Emit; >> + >> GlobalDecl AliasDecl; >> if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) { >> AliasDecl = GlobalDecl(DD, Dtor_Complete); >> >> Modified: cfe/trunk/test/CodeGen/always-inline.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/always-inline.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/always-inline.c (original) >> +++ cfe/trunk/test/CodeGen/always-inline.c Fri Sep 11 20:07:37 2015 >> @@ -1,7 +1,9 @@ >> // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s >> // RUN: %clang_cc1 -fno-inline -emit-llvm %s -o - | FileCheck %s >> >> +// CHECK-LABEL: define void @i_want_bar() >> // CHECK-NOT: foo >> +// CHECK: ret void >> >> void bar() { >> } >> >> Added: cfe/trunk/test/CodeGen/always_inline-unused.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/always_inline-unused.c?rev=247494&view=auto >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/always_inline-unused.c (added) >> +++ cfe/trunk/test/CodeGen/always_inline-unused.c Fri Sep 11 20:07:37 2015 >> @@ -0,0 +1,31 @@ >> +// Test alwaysinline definitions w/o any non-direct-call uses. >> +// None of the declarations are emitted. Stub are only emitted when the >> original >> +// function can not be discarded. >> + >> +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s >> + >> +void __attribute__((__always_inline__)) f1() {} >> +inline void __attribute__((__always_inline__)) f2() {} >> +static inline void __attribute__((__always_inline__)) f3() {} >> +inline void __attribute__((gnu_inline, __always_inline__)) f4() {} >> +static inline void __attribute__((gnu_inline, __always_inline__)) f5() {} >> +inline void __attribute__((visibility("hidden"), __always_inline__)) f6() >> {} >> +inline void __attribute__((visibility("hidden"), gnu_inline, >> __always_inline__)) f7() {} >> + >> +void g() { >> + f1(); >> + f2(); >> + f3(); >> + f4(); >> + f5(); >> + f6(); >> + f7(); >> +} >> + >> +// CHECK: define void @f1() >> +// CHECK-NOT: void @f2() >> +// CHECK-NOT: void @f3() >> +// CHECK: define void @f4() >> +// CHECK-NOT: void @f5() >> +// CHECK-NOT: void @f6() >> +// CHECK: define hidden void @f7() >> >> Added: cfe/trunk/test/CodeGen/always_inline-wrappers.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/always_inline-wrappers.c?rev=247494&view=auto >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/always_inline-wrappers.c (added) >> +++ cfe/trunk/test/CodeGen/always_inline-wrappers.c Fri Sep 11 20:07:37 >> 2015 >> @@ -0,0 +1,108 @@ >> +// Test different kinds of alwaysinline definitions. >> + >> +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s >> --check-prefix=CHECK --check-prefix=CHECK-INLINE >> +// RUN: %clang_cc1 -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s >> --check-prefix=CHECK-USE >> +// RUN: %clang_cc1 -disable-llvm-optzns -fno-inline -emit-llvm %s -o - | >> FileCheck %s --check-prefix=CHECK >> +// RUN: %clang_cc1 -disable-llvm-optzns -fno-inline -emit-llvm %s -o - | >> FileCheck %s --check-prefix=CHECK-USE >> + >> +void __attribute__((__always_inline__)) f1() {} >> +inline void __attribute__((__always_inline__)) f2() {} >> +static inline void __attribute__((__always_inline__)) f3() {} >> +inline void __attribute__((gnu_inline, __always_inline__)) f4() {} >> +static inline void __attribute__((gnu_inline, __always_inline__)) f5() {} >> +inline void __attribute__((visibility("hidden"), __always_inline__)) f6() >> {} >> +inline void __attribute__((visibility("hidden"), gnu_inline, >> __always_inline__)) f7() {} >> + >> +void g() { >> + f1(); >> + f2(); >> + f3(); >> + f4(); >> + f5(); >> + f6(); >> + f7(); >> +} >> + >> +void (*p)(void); >> +void h() { >> + p = f1; >> + p = f2; >> + p = f3; >> + p = f4; >> + p = f5; >> + p = f6; >> + p = f7; >> +} >> + >> +void (*const cp1)(void) = f1; >> +void (*p1)(void) = f1; >> +void (*p2)(int) = (void (*)(int))f1; >> + >> +void __attribute__((__always_inline__)) f8(void(*f)(void)) {} >> + >> +void call() { >> + f8(f1); >> +} >> + >> +// CHECK-DAG: define internal void @f1.alwaysinline() #[[AI:[0-9]+]] >> +// CHECK-DAG: define internal void @f2.alwaysinline() #[[AI_IH:[0-9]+]] >> +// CHECK-DAG: define internal void @f3.alwaysinline() #[[AI_IH]] >> +// CHECK-DAG: define internal void @f4.alwaysinline() #[[AI_IH]] >> +// CHECK-DAG: define internal void @f5.alwaysinline() #[[AI_IH]] >> +// CHECK-DAG: define internal void @f6.alwaysinline() #[[AI_IH]] >> +// CHECK-DAG: define internal void @f7.alwaysinline() #[[AI_IH]] >> + >> + >> +// CHECK-DAG: define void @f1() #[[NOAI:[01-9]+]] >> +// CHECK-DAG: musttail call void @f1.alwaysinline() >> + >> +// CHECK-DAG: declare void @f2() #[[NOAI:[01-9]+]] >> + >> +// CHECK-DAG: define internal void @f3() #[[NOAI:[01-9]+]] >> +// CHECK-DAG: musttail call void @f3.alwaysinline() >> + >> +// CHECK-DAG: define void @f4() #[[NOAI:[01-9]+]] >> +// CHECK-DAG: musttail call void @f4.alwaysinline() >> + >> +// CHECK-DAG: define internal void @f5() #[[NOAI:[01-9]+]] >> +// CHECK-DAG: musttail call void @f5.alwaysinline() >> + >> +// CHECK-DAG: declare hidden void @f6() #[[NOAI:[01-9]+]] >> + >> +// CHECK-DAG: define hidden void @f7() #[[NOAI:[01-9]+]] >> +// CHECK-DAG: musttail call void @f7.alwaysinline() >> + >> + >> +// CHECK-DAG: @cp1 = constant void ()* @f1, align >> +// CHECK-DAG: @p1 = global void ()* @f1, align >> +// CHECK-DAG: @p2 = global void (i32)* bitcast (void ()* @f1 to void >> (i32)*), align >> + >> +// CHECK: attributes #[[AI]] = {{.*alwaysinline.*}} >> +// CHECK-INLINE: attributes #[[AI_IH]] = {{.*alwaysinline.*inlinehint.*}} >> +// CHECK-NOT: attributes #[[NOAI]] = {{.*alwaysinline.*}} >> + >> +// CHECK-USE-LABEL: define void @g() >> +// CHECK-USE-NOT: ret void >> +// CHECK-USE: call void @f1.alwaysinline() >> +// CHECK-USE-NEXT: call void @f2.alwaysinline() >> +// CHECK-USE-NEXT: call void @f3.alwaysinline() >> +// CHECK-USE-NEXT: call void @f4.alwaysinline() >> +// CHECK-USE-NEXT: call void @f5.alwaysinline() >> +// CHECK-USE-NEXT: call void @f6.alwaysinline() >> +// CHECK-USE-NEXT: call void @f7.alwaysinline() >> +// CHECK-USE-NEXT: ret void >> + >> +// CHECK-USE-LABEL: define void @h() >> +// CHECK-USE-NOT: ret void >> +// CHECK-USE: store void ()* @f1, >> +// CHECK-USE-NEXT: store void ()* @f2, >> +// CHECK-USE-NEXT: store void ()* @f3, >> +// CHECK-USE-NEXT: store void ()* @f4, >> +// CHECK-USE-NEXT: store void ()* @f5, >> +// CHECK-USE-NEXT: store void ()* @f6, >> +// CHECK-USE-NEXT: store void ()* @f7, >> +// CHECK-USE-NEXT: ret void >> + >> +// CHECK-USE-LABEL: define void @call() >> +// CHECK-USE: call void @f8.alwaysinline(void ()* @f1) >> +// CHECK-USE: ret void >> >> Modified: cfe/trunk/test/CodeGen/always_inline.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/always_inline.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/always_inline.c (original) >> +++ cfe/trunk/test/CodeGen/always_inline.c Fri Sep 11 20:07:37 2015 >> @@ -1,8 +1,5 @@ >> -// RUN: %clang -emit-llvm -S -o %t %s >> -// RUN: not grep '@f0' %t >> -// RUN: not grep 'call ' %t >> -// RUN: %clang -mllvm -disable-llvm-optzns -emit-llvm -S -o %t %s >> -// RUN: grep '@f0' %t | count 2 >> +// RUN: %clang -target x86_64-pc-linux-gnu -emit-llvm -S -o - %s | >> FileCheck %s >> +// RUN: %clang -target x86_64-pc-linux-gnu -mllvm -disable-llvm-optzns >> -emit-llvm -S -o - %s | FileCheck %s --check-prefix=CHECK-NO-OPTZNS >> >> //static int f0() { >> static int __attribute__((always_inline)) f0() { >> @@ -18,3 +15,14 @@ inline int f2() __attribute__((always_in >> int f2() { return 7; } >> int f3(void) { return f2(); } >> >> +// CHECK-LABEL: define i32 @f1() >> +// CHECK: ret i32 1 >> +// CHECK-LABEL: define i32 @f2() >> +// CHECK: ret i32 7 >> +// CHECK-LABEL: define i32 @f3() >> +// CHECK: ret i32 7 >> + >> +// CHECK-NO-OPTZNS: define i32 @f3() >> +// CHECK-NO-OPTZNS-NOT: ret i32 >> +// CHECK-NO-OPTZNS: call i32 @f2.alwaysinline() >> +// CHECK-NO-OPTZNS-NEXT: ret i32 >> >> Modified: cfe/trunk/test/CodeGen/function-attributes.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/function-attributes.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/function-attributes.c (original) >> +++ cfe/trunk/test/CodeGen/function-attributes.c Fri Sep 11 20:07:37 2015 >> @@ -25,8 +25,8 @@ void f6(signed short x) { } >> >> void f7(unsigned short x) { } >> >> -// CHECK-LABEL: define void @f8() >> -// CHECK: [[AI:#[0-9]+]] >> +// CHECK: define void @f8() >> +// CHECK: [[NUW:#[0-9]+]] >> // CHECK: { >> void __attribute__((always_inline)) f8(void) { } >> >> @@ -129,7 +129,6 @@ void f20(void) { >> } >> >> // CHECK: attributes [[NUW]] = { nounwind optsize readnone{{.*}} } >> -// CHECK: attributes [[AI]] = { alwaysinline nounwind optsize >> readnone{{.*}} } >> // CHECK: attributes [[ALIGN]] = { nounwind optsize readnone >> alignstack=16{{.*}} } >> // CHECK: attributes [[RT]] = { nounwind optsize returns_twice{{.*}} } >> // CHECK: attributes [[NR]] = { noreturn nounwind optsize } >> >> Modified: cfe/trunk/test/CodeGen/pr9614.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pr9614.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/CodeGen/pr9614.c (original) >> +++ cfe/trunk/test/CodeGen/pr9614.c Fri Sep 11 20:07:37 2015 >> @@ -1,4 +1,5 @@ >> -// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck >> %s >> +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm %s -o - | FileCheck >> %s --check-prefix=CHECK --check-prefix=CHECK0 >> +// RUN: %clang_cc1 -triple x86_64-pc-linux -O1 -disable-llvm-optzns >> -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1 >> >> extern void foo_alias (void) __asm ("foo"); >> inline void foo (void) { >> @@ -24,7 +25,7 @@ extern inline __attribute__((__always_in >> >> void f(void) { >> foo(); >> - abs(0); >> + int x = abs(0); >> strrchr_foo("", '.'); >> prefetch(); >> memchr("", '.', 0); >> @@ -32,9 +33,10 @@ void f(void) { >> >> // CHECK-LABEL: define void @f() >> // CHECK: call void @foo() >> -// CHECK: call i32 @abs(i32 0) >> +// CHECK: call i32 @abs( >> // CHECK: call i8* @strrchr( >> -// CHECK: call void @llvm.prefetch( >> +// CHECK0: call void @llvm.prefetch( >> +// CHECK1: call void @prefetch.alwaysinline( >> // CHECK: call i8* @memchr( >> // CHECK: ret void >> >> >> Added: cfe/trunk/test/CodeGenCXX/alwaysinline.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/alwaysinline.cpp?rev=247494&view=auto >> >> ============================================================================== >> --- cfe/trunk/test/CodeGenCXX/alwaysinline.cpp (added) >> +++ cfe/trunk/test/CodeGenCXX/alwaysinline.cpp Fri Sep 11 20:07:37 2015 >> @@ -0,0 +1,68 @@ >> +// Test different kinds of alwaysinline *structor definitions. >> + >> +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -disable-llvm-optzns >> -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK >> +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -disable-llvm-optzns >> -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-CALL >> + >> +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -mconstructor-aliases >> -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK >> +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -mconstructor-aliases >> -disable-llvm-optzns -emit-llvm %s -o - | FileCheck %s >> --check-prefix=CHECK-CALL >> + >> +struct A1 { >> + __attribute__((__always_inline__)) A1() {} >> + __attribute__((__always_inline__)) ~A1() {} >> +}; >> + >> +void g1() { >> + A1 a1; >> +} >> + >> +struct A2 { >> + inline __attribute__((__always_inline__)) A2() {} >> + inline __attribute__((__always_inline__)) ~A2() {} >> +}; >> + >> +void g2() { >> + A2 a2; >> +} >> + >> +struct A3 { >> + inline __attribute__((gnu_inline, __always_inline__)) A3() {} >> + inline __attribute__((gnu_inline, __always_inline__)) ~A3() {} >> +}; >> + >> +void g3() { >> + A3 a3; >> +} >> + >> +// CHECK-DAG: define internal void @_ZN2A1C1Ev.alwaysinline(%struct.A1* >> %this) unnamed_addr #[[AI:[01-9]+]] >> +// CHECK-DAG: define internal void @_ZN2A1C2Ev.alwaysinline(%struct.A1* >> %this) unnamed_addr #[[AI]] >> +// CHECK-DAG: define internal void @_ZN2A1D1Ev.alwaysinline(%struct.A1* >> %this) unnamed_addr #[[AI]] >> +// CHECK-DAG: define internal void @_ZN2A1D2Ev.alwaysinline(%struct.A1* >> %this) unnamed_addr #[[AI]] >> + >> +// CHECK-DAG: define internal void @_ZN2A2C1Ev.alwaysinline(%struct.A2* >> %this) unnamed_addr #[[AIIH:[01-9]+]] >> +// CHECK-DAG: define internal void @_ZN2A2C2Ev.alwaysinline(%struct.A2* >> %this) unnamed_addr #[[AIIH]] >> +// CHECK-DAG: define internal void @_ZN2A2D1Ev.alwaysinline(%struct.A2* >> %this) unnamed_addr #[[AIIH]] >> +// CHECK-DAG: define internal void @_ZN2A2D2Ev.alwaysinline(%struct.A2* >> %this) unnamed_addr #[[AIIH]] >> + >> +// CHECK-DAG: define internal void @_ZN2A3C1Ev.alwaysinline(%struct.A3* >> %this) unnamed_addr #[[AIIH]] >> +// CHECK-DAG: define internal void @_ZN2A3C2Ev.alwaysinline(%struct.A3* >> %this) unnamed_addr #[[AIIH]] >> +// CHECK-DAG: define internal void @_ZN2A3D1Ev.alwaysinline(%struct.A3* >> %this) unnamed_addr #[[AIIH]] >> +// CHECK-DAG: define internal void @_ZN2A3D2Ev.alwaysinline(%struct.A3* >> %this) unnamed_addr #[[AIIH]] >> + >> +// CHECK-DAG: attributes #[[AI]] = {{.*alwaysinline.*}} >> +// CHECK-DAG: attributes #[[AIIH]] = {{.*alwaysinline.*inlinehint.*}} >> +// CHECK-NOT: attributes #[[NOAI]] = {{.*alwaysinline.*}} >> + >> +// CHECK-CALL-LABEL: define void @_Z2g1v() >> +// CHECK-CALL: call void @_ZN2A1C1Ev.alwaysinline >> +// CHECK-CALL: call void @_ZN2A1D1Ev.alwaysinline >> +// CHECK-CALL: ret void >> + >> +// CHECK-CALL-LABEL: define void @_Z2g2v() >> +// CHECK-CALL: call void @_ZN2A2C1Ev.alwaysinline >> +// CHECK-CALL: call void @_ZN2A2D1Ev.alwaysinline >> +// CHECK-CALL: ret void >> + >> +// CHECK-CALL-LABEL: define void @_Z2g3v() >> +// CHECK-CALL: call void @_ZN2A3C1Ev.alwaysinline >> +// CHECK-CALL: call void @_ZN2A3D1Ev.alwaysinline >> +// CHECK-CALL: ret void >> >> Modified: cfe/trunk/test/Frontend/optimization-remark-line-directive.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/optimization-remark-line-directive.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/Frontend/optimization-remark-line-directive.c >> (original) >> +++ cfe/trunk/test/Frontend/optimization-remark-line-directive.c Fri Sep >> 11 20:07:37 2015 >> @@ -5,8 +5,9 @@ >> // RUN: %clang_cc1 %s -Rpass=inline -gline-tables-only -dwarf-column-info >> -emit-llvm-only -verify >> >> int foo(int x, int y) __attribute__((always_inline)); >> +// expected-remark@+1 {{foo.alwaysinline inlined into foo}} >> int foo(int x, int y) { return x + y; } >> >> -// expected-remark@+2 {{foo inlined into bar}} expected-note@+2 {{could >> not determine the original source location for >> /bad/path/to/original.c:1230:25}} >> +// expected-remark@+2 {{foo.alwaysinline inlined into bar}} >> expected-note@+2 {{could not determine the original source location for >> /bad/path/to/original.c:1230:25}} >> #line 1230 "/bad/path/to/original.c" >> int bar(int j) { return foo(j, j - 2); } >> >> Modified: cfe/trunk/test/Frontend/optimization-remark.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/optimization-remark.c?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/Frontend/optimization-remark.c (original) >> +++ cfe/trunk/test/Frontend/optimization-remark.c Fri Sep 11 20:07:37 2015 >> @@ -32,6 +32,8 @@ >> // CHECK-NOT: !llvm.dbg.cu = !{ >> >> int foo(int x, int y) __attribute__((always_inline)); >> +// expected-remark@+2 {{foo.alwaysinline should always be inlined}} >> +// expected-remark@+1 {{foo.alwaysinline inlined into foo}} >> int foo(int x, int y) { return x + y; } >> >> float foz(int x, int y) __attribute__((noinline)); >> @@ -45,7 +47,7 @@ int bar(int j) { >> // expected-remark@+5 {{foz will not be inlined into bar}} >> // expected-remark@+4 {{foz should never be inlined}} >> // expected-remark@+3 {{foz will not be inlined into bar}} >> -// expected-remark@+2 {{foo should always be inlined}} >> -// expected-remark@+1 {{foo inlined into bar}} >> +// expected-remark@+2 {{foo.alwaysinline should always be inlined}} >> +// expected-remark@+1 {{foo.alwaysinline inlined into bar}} >> return foo(j, j - 2) * foz(j - 2, j); >> } >> >> Modified: cfe/trunk/test/Modules/cxx-irgen.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-irgen.cpp?rev=247494&r1=247493&r2=247494&view=diff >> >> ============================================================================== >> --- cfe/trunk/test/Modules/cxx-irgen.cpp (original) >> +++ cfe/trunk/test/Modules/cxx-irgen.cpp Fri Sep 11 20:07:37 2015 >> @@ -26,14 +26,14 @@ namespace EmitInlineMethods { >> }; >> } >> >> -// CHECK-DAG: define available_externally hidden {{.*}}{{signext >> i32|i32}} @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align >> +// CHECK-DAG: define internal i32 @_ZN1SIiE1gEv.alwaysinline() >> #[[ALWAYS_INLINE:.*]] align >> int a = S<int>::g(); >> >> int b = h(); >> >> // CHECK-DAG: define linkonce_odr {{.*}}{{signext i32|i32}} >> @_Z3minIiET_S0_S0_(i32 >> int c = min(1, 2); >> -// CHECK: define available_externally {{.*}}{{signext i32|i32}} >> @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align >> +// CHECK-DAG: define internal {{.*}}{{signext i32|i32}} >> @_ZN1SIiE1fEv.alwaysinline() #[[ALWAYS_INLINE]] align >> >> namespace ImplicitSpecialMembers { >> // CHECK-LABEL: define {{.*}} @_ZN22ImplicitSpecialMembers1BC2ERKS0_( >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits