Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -44,7 +44,6 @@ class CodeGenOptions : public CodeGenOptionsBase { public: enum InliningMethod { - NoInlining, // Perform no inlining whatsoever. NormalInlining, // Use the standard function inlining pass. OnlyHintInlining, // Inline only (implicitly) hinted functions. OnlyAlwaysInlining // Only run the always inlining pass. Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -105,8 +105,6 @@ CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled. -CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. - ///< Disables use of the inline keyword. CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. CODEGENOPT(FlushDenorm , 1, 0) ///< Allow FP denorm numbers to be flushed to zero CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt @@ -234,7 +232,7 @@ CODEGENOPT(EmitCodeView, 1, 0) /// The kind of inlining to perform. -ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) +ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining) // Vector functions library to use. ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary) Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -303,8 +303,6 @@ createTLII(TargetTriple, CodeGenOpts)); switch (Inlining) { - case CodeGenOptions::NoInlining: - break; case CodeGenOptions::NormalInlining: case CodeGenOptions::OnlyHintInlining: { PMBuilder.Inliner = Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -757,6 +757,7 @@ FnTy, llvm::GlobalValue::InternalLinkage, IsCombiner ? ".omp_combiner." : ".omp_initializer.", &CGM.getModule()); CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo); + Fn->removeFnAttr(llvm::Attribute::NoInline); Fn->addFnAttr(llvm::Attribute::AlwaysInline); CodeGenFunction CGF(CGM); // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions. @@ -3472,6 +3473,7 @@ ".omp_task_privates_map.", &CGM.getModule()); CGM.SetInternalFunctionAttributes(/*D=*/nullptr, TaskPrivatesMap, TaskPrivatesMapFnInfo); + TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline); TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline); CodeGenFunction CGF(CGM); CGF.disableDebugInfo(); Index: lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -368,6 +368,7 @@ CGOpenMPRuntime::emitParallelOrTeamsOutlinedFunction( D, ThreadIDVar, InnermostKind, CodeGen); OutlinedFun = cast(OutlinedFunVal); + OutlinedFun->removeFnAttr(llvm::Attribute::NoInline); OutlinedFun->addFnAttr(llvm::Attribute::AlwaysInline); } else llvm_unreachable("parallel directive is not yet supported for nvptx " Index: lib/CodeGen/CodeGenFunction.cpp =================================================================== --- lib/CodeGen/CodeGenFunction.cpp +++ lib/CodeGen/CodeGenFunction.cpp @@ -775,27 +775,9 @@ } } - // Pass inline keyword to optimizer if it appears explicitly on any - // declaration. Also, in the case of -fno-inline attach NoInline - // attribute to all functions that are not marked AlwaysInline, or - // to all functions that are not marked inline or implicitly inline - // in the case of -finline-hint-functions. - if (const FunctionDecl *FD = dyn_cast_or_null(D)) { - const CodeGenOptions& CodeGenOpts = CGM.getCodeGenOpts(); - if (!CodeGenOpts.NoInline) { - for (auto RI : FD->redecls()) - if (RI->isInlineSpecified()) { - Fn->addFnAttr(llvm::Attribute::InlineHint); - break; - } - if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyHintInlining && - !FD->isInlined() && !Fn->hasFnAttribute(llvm::Attribute::InlineHint)) - Fn->addFnAttr(llvm::Attribute::NoInline); - } else if (!FD->hasAttr()) - Fn->addFnAttr(llvm::Attribute::NoInline); + if (const FunctionDecl *FD = dyn_cast_or_null(D)) if (CGM.getLangOpts().OpenMP && FD->hasAttr()) CGM.getOpenMPRuntime().emitDeclareSimdFunction(FD, Fn); - } // Add no-jump-tables value. Fn->addFnAttr("no-jump-tables", Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -875,6 +875,13 @@ B.addAttribute(llvm::Attribute::StackProtectReq); if (!D) { + // If we don't have a declaration to control inlining, the function isn't + // explicitly marked as alwaysinline for semantic reasons, and inlining is + // disabled, mark the function as noinline. + if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && + CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) + B.addAttribute(llvm::Attribute::NoInline); + F->addAttributes(llvm::AttributeSet::FunctionIndex, llvm::AttributeSet::get( F->getContext(), @@ -882,7 +889,23 @@ return; } - if (D->hasAttr()) { + if (D->hasAttr()) { + B.addAttribute(llvm::Attribute::OptimizeNone); + + // OptimizeNone implies noinline; we should not be inlining such functions. + B.addAttribute(llvm::Attribute::NoInline); + assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && + "OptimizeNone and AlwaysInline on same function!"); + + // We still need to handle naked functions even though optnone subsumes + // much of their semantics. + if (D->hasAttr()) + B.addAttribute(llvm::Attribute::Naked); + + // OptimizeNone wins over OptimizeForSize and MinSize. + F->removeFnAttr(llvm::Attribute::OptimizeForSize); + F->removeFnAttr(llvm::Attribute::MinSize); + } else if (D->hasAttr()) { // Naked implies noinline: we should not be inlining such functions. B.addAttribute(llvm::Attribute::Naked); B.addAttribute(llvm::Attribute::NoInline); @@ -891,41 +914,47 @@ } else if (D->hasAttr()) { B.addAttribute(llvm::Attribute::NoInline); } else if (D->hasAttr() && - !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, - llvm::Attribute::NoInline)) { + !F->hasFnAttribute(llvm::Attribute::NoInline)) { // (noinline wins over always_inline, and we can't specify both in IR) B.addAttribute(llvm::Attribute::AlwaysInline); + } else if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) { + // If we're not inlining, then force everything that isn't always_inline to + // carry an explicit noinline attribute. + if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline)) + B.addAttribute(llvm::Attribute::NoInline); + } else { + // Otherwise, propagate the inline hint attribute and potentially use its + // absence to mark things as noinline. + if (auto *FD = dyn_cast(D)) { + if (any_of(FD->redecls(), [&](const FunctionDecl *Redecl) { + return Redecl->isInlineSpecified(); + })) { + B.addAttribute(llvm::Attribute::InlineHint); + } else if (CodeGenOpts.getInlining() == + CodeGenOptions::OnlyHintInlining && + !FD->isInlined() && + !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { + B.addAttribute(llvm::Attribute::NoInline); + } + } } - if (D->hasAttr()) { - if (!D->hasAttr()) + // Add other optimization related attributes if we are optimizing this + // function. + if (!D->hasAttr()) { + if (D->hasAttr()) { B.addAttribute(llvm::Attribute::OptimizeForSize); - B.addAttribute(llvm::Attribute::Cold); - } + B.addAttribute(llvm::Attribute::Cold); + } - if (D->hasAttr()) - B.addAttribute(llvm::Attribute::MinSize); + if (D->hasAttr()) + B.addAttribute(llvm::Attribute::MinSize); + } F->addAttributes(llvm::AttributeSet::FunctionIndex, llvm::AttributeSet::get( F->getContext(), llvm::AttributeSet::FunctionIndex, B)); - if (D->hasAttr()) { - // OptimizeNone implies noinline; we should not be inlining such functions. - F->addFnAttr(llvm::Attribute::OptimizeNone); - F->addFnAttr(llvm::Attribute::NoInline); - - // OptimizeNone wins over OptimizeForSize, MinSize, AlwaysInline. - F->removeFnAttr(llvm::Attribute::OptimizeForSize); - F->removeFnAttr(llvm::Attribute::MinSize); - assert(!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && - "OptimizeNone and AlwaysInline on same function!"); - - // Attribute 'inlinehint' has no effect on 'optnone' functions. - // Explicitly remove it from the set of function attributes. - F->removeFnAttr(llvm::Attribute::InlineHint); - } - unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); if (alignment) F->setAlignment(alignment); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -442,21 +442,23 @@ Opts.OptimizationLevel = OptimizationLevel; // We must always run at least the always inlining pass. - Opts.setInlining( - (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining - : CodeGenOptions::OnlyAlwaysInlining); + Opts.setInlining((Opts.OptimizationLevel > 1) + ? CodeGenOptions::NormalInlining + : CodeGenOptions::OnlyAlwaysInlining); // -fno-inline-functions overrides OptimizationLevel > 1. - Opts.NoInline = Args.hasArg(OPT_fno_inline); - if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions, - options::OPT_finline_hint_functions, - options::OPT_fno_inline_functions)) { - const Option& InlineOpt = InlineArg->getOption(); - if (InlineOpt.matches(options::OPT_finline_functions)) - Opts.setInlining(CodeGenOptions::NormalInlining); - else if (InlineOpt.matches(options::OPT_finline_hint_functions)) - Opts.setInlining(CodeGenOptions::OnlyHintInlining); - else - Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining); + if (Arg *InlineArg = Args.getLastArg( + options::OPT_finline_functions, options::OPT_finline_hint_functions, + options::OPT_fno_inline_functions, options::OPT_fno_inline)) { + // There is no effect at O0 when we won't inline anyways. + if (Opts.OptimizationLevel > 1) { + const Option &InlineOpt = InlineArg->getOption(); + if (InlineOpt.matches(options::OPT_finline_functions)) + Opts.setInlining(CodeGenOptions::NormalInlining); + else if (InlineOpt.matches(options::OPT_finline_hint_functions)) + Opts.setInlining(CodeGenOptions::OnlyHintInlining); + else + Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining); + } } if (Arg *A = Args.getLastArg(OPT_fveclib)) { @@ -2188,7 +2190,12 @@ // This is the __NO_INLINE__ define, which just depends on things like the // optimization level and -fno-inline, not actually whether the backend has // inlining enabled. - Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline); + Opts.NoInlineDefine = !Opts.Optimize; + if (Arg *InlineArg = Args.getLastArg( + options::OPT_finline_functions, options::OPT_finline_hint_functions, + options::OPT_fno_inline_functions, options::OPT_fno_inline)) + if (InlineArg->getOption().matches(options::OPT_fno_inline)) + Opts.NoInlineDefine = true; Opts.FastMath = Args.hasArg(OPT_ffast_math) || Args.hasArg(OPT_cl_fast_relaxed_math); Index: test/CXX/special/class.dtor/p3-0x.cpp =================================================================== --- test/CXX/special/class.dtor/p3-0x.cpp +++ test/CXX/special/class.dtor/p3-0x.cpp @@ -176,4 +176,4 @@ template TVC::~TVC() {} -// CHECK: attributes [[ATTRGRP]] = { nounwind{{.*}} } +// CHECK: attributes [[ATTRGRP]] = { noinline nounwind{{.*}} } Index: test/CodeGen/2008-04-08-NoExceptions.c =================================================================== --- test/CodeGen/2008-04-08-NoExceptions.c +++ test/CodeGen/2008-04-08-NoExceptions.c @@ -9,4 +9,4 @@ // CHECK-NOT: declare void @f() [[NUW]] -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/address-safety-attr-kasan.cpp =================================================================== --- test/CodeGen/address-safety-attr-kasan.cpp +++ test/CodeGen/address-safety-attr-kasan.cpp @@ -8,31 +8,31 @@ int HasSanitizeAddress() { return 1; } -// CHECK-NOASAN: {{Function Attrs: nounwind$}} -// CHECK-ASAN: Function Attrs: nounwind sanitize_address -// CHECK-KASAN: Function Attrs: nounwind sanitize_address +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address +// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address __attribute__((no_sanitize("address"))) int NoSanitizeQuoteAddress() { return 0; } -// CHECK-NOASAN: {{Function Attrs: nounwind$}} -// CHECK-ASAN: {{Function Attrs: nounwind$}} -// CHECK-KASAN: {{Function Attrs: nounwind sanitize_address$}} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}} __attribute__((no_sanitize_address)) int NoSanitizeAddress() { return 0; } -// CHECK-NOASAN: {{Function Attrs: nounwind$}} -// CHECK-ASAN: {{Function Attrs: nounwind$}} -// CHECK-KASAN: {{Function Attrs: nounwind sanitize_address$}} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}} __attribute__((no_sanitize("kernel-address"))) int NoSanitizeKernelAddress() { return 0; } -// CHECK-NOASAN: {{Function Attrs: nounwind$}} -// CHECK-ASAN: {{Function Attrs: nounwind sanitize_address$}} -// CHECK-KASAN: {{Function Attrs: nounwind$}} +// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}} +// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}} +// CHECK-KASAN: {{Function Attrs: noinline nounwind$}} Index: test/CodeGen/address-safety-attr.cpp =================================================================== --- test/CodeGen/address-safety-attr.cpp +++ test/CodeGen/address-safety-attr.cpp @@ -143,13 +143,13 @@ // BLFUNC: @__cxx_global_var_init{{.*}}[[WITH]] // ASAN: @__cxx_global_var_init{{.*}}[[WITH]] -// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} } +// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} } -// BLFILE: attributes [[WITH]] = { nounwind sanitize_address{{.*}} } -// BLFILE: attributes [[NOATTR]] = { nounwind{{.*}} } +// BLFILE: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} } +// BLFILE: attributes [[NOATTR]] = { noinline nounwind{{.*}} } -// BLFUNC: attributes [[WITH]] = { nounwind sanitize_address{{.*}} } -// BLFUNC: attributes [[NOATTR]] = { nounwind{{.*}} } +// BLFUNC: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} } +// BLFUNC: attributes [[NOATTR]] = { noinline nounwind{{.*}} } -// ASAN: attributes [[WITH]] = { nounwind sanitize_address{{.*}} } -// ASAN: attributes [[NOATTR]] = { nounwind{{.*}} } +// ASAN: attributes [[WITH]] = { noinline nounwind sanitize_address{{.*}} } +// ASAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} } Index: test/CodeGen/address-space-field1.c =================================================================== --- test/CodeGen/address-space-field1.c +++ test/CodeGen/address-space-field1.c @@ -37,4 +37,4 @@ p1->b = p2->a; } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/alias.c =================================================================== --- test/CodeGen/alias.c +++ test/CodeGen/alias.c @@ -77,9 +77,9 @@ // CHECKCC: call arm_aapcs_vfpcc i32 @inner_weak(i32 %{{.*}}) // CHECKCC: define internal arm_aapcs_vfpcc i32 @inner_weak(i32 %a) [[NUW]] { -// CHECKBASIC: attributes [[NUW]] = { nounwind{{.*}} } +// CHECKBASIC: attributes [[NUW]] = { noinline nounwind{{.*}} } -// CHECKCC: attributes [[NUW]] = { nounwind{{.*}} } +// CHECKCC: attributes [[NUW]] = { noinline nounwind{{.*}} } void test8_bar() {} void test8_foo() __attribute__((weak, alias("test8_bar"))); Index: test/CodeGen/attr-minsize.cpp =================================================================== --- test/CodeGen/attr-minsize.cpp +++ test/CodeGen/attr-minsize.cpp @@ -76,4 +76,4 @@ // Oz: attributes [[MINSIZE]] = { minsize{{.*}} } -// OTHER: attributes [[MS]] = { minsize nounwind{{.*}} } +// OTHER: attributes [[MS]] = { minsize{{.*}} } Index: test/CodeGen/attributes.c =================================================================== --- test/CodeGen/attributes.c +++ test/CodeGen/attributes.c @@ -90,5 +90,5 @@ // CHECK: define void @t22() [[NUW]] section ".bar" -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } -// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } +// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } Index: test/CodeGen/incomplete-function-type-2.c =================================================================== --- test/CodeGen/incomplete-function-type-2.c +++ test/CodeGen/incomplete-function-type-2.c @@ -16,4 +16,4 @@ p1(0.0); } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/inline-optim.c =================================================================== --- test/CodeGen/inline-optim.c +++ test/CodeGen/inline-optim.c @@ -2,8 +2,8 @@ // RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s // RUN: %clang_cc1 -triple i686-pc-win32 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s -// RUN: %clang_cc1 -triple i686-pc-win32 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s -// RUN: %clang_cc1 -triple i686-pc-win32 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s +// RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s +// RUN: %clang_cc1 -triple i686-pc-win32 -O3 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s inline int inline_hint(int a, int b) { return(a+b); } Index: test/CodeGen/mips16-attr.c =================================================================== --- test/CodeGen/mips16-attr.c +++ test/CodeGen/mips16-attr.c @@ -11,7 +11,7 @@ // CHECK: define void @nofoo() [[NOMIPS16:#[0-9]+]] -// CHECK: attributes [[MIPS16]] = { nounwind {{.*}} "mips16" {{.*}} } +// CHECK: attributes [[MIPS16]] = { noinline nounwind {{.*}} "mips16" {{.*}} } -// CHECK: attributes [[NOMIPS16]] = { nounwind {{.*}} "nomips16" {{.*}} } +// CHECK: attributes [[NOMIPS16]] = { noinline nounwind {{.*}} "nomips16" {{.*}} } Index: test/CodeGen/mrtd.c =================================================================== --- test/CodeGen/mrtd.c +++ test/CodeGen/mrtd.c @@ -25,4 +25,4 @@ // CHECK-LABEL: define x86_stdcallcc void @quux // CHECK: call void (i32, ...) @qux -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/ms-declspecs.c =================================================================== --- test/CodeGen/ms-declspecs.c +++ test/CodeGen/ms-declspecs.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -O2 -disable-llvm-optzns -o - | FileCheck %s __declspec(selectany) int x1 = 1; const __declspec(selectany) int x2 = 2; Index: test/CodeGen/ppc64-complex-parms.c =================================================================== --- test/CodeGen/ppc64-complex-parms.c +++ test/CodeGen/ppc64-complex-parms.c @@ -180,4 +180,4 @@ // CHECK: %[[VAR77:[A-Za-z0-9.]+]] = load i64, i64* %[[VAR76]], align 8 // CHECK: %{{[A-Za-z0-9.]+}} = call i64 @foo_long_long(i64 %[[VAR75]], i64 %[[VAR77]]) -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/ppc64-complex-return.c =================================================================== --- test/CodeGen/ppc64-complex-return.c +++ test/CodeGen/ppc64-complex-return.c @@ -126,4 +126,4 @@ // CHECK: extractvalue { i64, i64 } [[VAR8]], 1 -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/ppc64-extend.c =================================================================== --- test/CodeGen/ppc64-extend.c +++ test/CodeGen/ppc64-extend.c @@ -13,4 +13,4 @@ unsigned int f4(void) { return 0; } // CHECK: define zeroext i32 @f4() [[NUW]] -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGen/sanitize-thread-attr.cpp =================================================================== --- test/CodeGen/sanitize-thread-attr.cpp +++ test/CodeGen/sanitize-thread-attr.cpp @@ -54,9 +54,9 @@ // BL: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]] // TSAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]] -// WITHOUT: attributes [[NOATTR]] = { nounwind{{.*}} } +// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} } -// BL: attributes [[NOATTR]] = { nounwind{{.*}} } +// BL: attributes [[NOATTR]] = { noinline nounwind{{.*}} } -// TSAN: attributes [[NOATTR]] = { nounwind{{.*}} } -// TSAN: attributes [[WITH]] = { nounwind sanitize_thread{{.*}} } +// TSAN: attributes [[NOATTR]] = { noinline nounwind{{.*}} } +// TSAN: attributes [[WITH]] = { noinline nounwind sanitize_thread{{.*}} } Index: test/CodeGen/sanitize-thread-no-checking-at-run-time.m =================================================================== --- test/CodeGen/sanitize-thread-no-checking-at-run-time.m +++ test/CodeGen/sanitize-thread-no-checking-at-run-time.m @@ -31,4 +31,4 @@ // TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]] // TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]] // TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]] -// TSAN: attributes [[ATTR]] = { nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} } +// TSAN: attributes [[ATTR]] = { noinline nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} } Index: test/CodeGen/unwind-attr.c =================================================================== --- test/CodeGen/unwind-attr.c +++ test/CodeGen/unwind-attr.c @@ -23,7 +23,7 @@ return 0; } -// CHECK: attributes [[TF]] = { "{{.*}} } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[TF]] = { noinline "{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } -// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/attr.cpp =================================================================== --- test/CodeGenCXX/attr.cpp +++ test/CodeGenCXX/attr.cpp @@ -31,4 +31,4 @@ // CHECK at top of file extern "C" int test2() __attribute__((alias("_Z5test1v"))); -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/cxx11-exception-spec.cpp =================================================================== --- test/CodeGenCXX/cxx11-exception-spec.cpp +++ test/CodeGenCXX/cxx11-exception-spec.cpp @@ -121,7 +121,7 @@ } // CHECK: attributes [[NONE]] = { {{.*}} } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NUW2]] = { nounwind{{.*}} } Index: test/CodeGenCXX/cxx11-noreturn.cpp =================================================================== --- test/CodeGenCXX/cxx11-noreturn.cpp +++ test/CodeGenCXX/cxx11-noreturn.cpp @@ -7,4 +7,4 @@ while (g()) {} } -// CHECK: attributes [[NR]] = { noreturn nounwind{{.*}} } +// CHECK: attributes [[NR]] = { noinline noreturn nounwind{{.*}} } Index: test/CodeGenCXX/derived-to-base.cpp =================================================================== --- test/CodeGenCXX/derived-to-base.cpp +++ test/CodeGenCXX/derived-to-base.cpp @@ -46,4 +46,4 @@ } } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/global-dtor-no-atexit.cpp =================================================================== --- test/CodeGenCXX/global-dtor-no-atexit.cpp +++ test/CodeGenCXX/global-dtor-no-atexit.cpp @@ -43,4 +43,4 @@ static A a1, a2; } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/global-init.cpp =================================================================== --- test/CodeGenCXX/global-init.cpp +++ test/CodeGenCXX/global-init.cpp @@ -204,8 +204,8 @@ // rdar://problem/8090834: this should be nounwind // CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { -// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK-NOEXC: attributes [[NUW]] = { noinline nounwind{{.*}} } // PR21811: attach the appropriate attribute to the global init function // CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { -// CHECK-FP: attributes [[NUX]] = { nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} } +// CHECK-FP: attributes [[NUX]] = { noinline nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} } Index: test/CodeGenCXX/inline-hint.cpp =================================================================== --- test/CodeGenCXX/inline-hint.cpp +++ test/CodeGenCXX/inline-hint.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE -// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED -// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED +// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -O2 -fno-inline -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE // Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A struct A { Index: test/CodeGenCXX/main-norecurse.cpp =================================================================== --- test/CodeGenCXX/main-norecurse.cpp +++ test/CodeGenCXX/main-norecurse.cpp @@ -5,4 +5,4 @@ return 1; } -// CHECK: attributes #0 = { norecurse{{.*}} } +// CHECK: attributes #0 = { noinline norecurse{{.*}} } Index: test/CodeGenCXX/microsoft-abi-array-cookies.cpp =================================================================== --- test/CodeGenCXX/microsoft-abi-array-cookies.cpp +++ test/CodeGenCXX/microsoft-abi-array-cookies.cpp @@ -68,4 +68,4 @@ void delete_s(S *s) { delete[] s; } } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/no-exceptions.cpp =================================================================== --- test/CodeGenCXX/no-exceptions.cpp +++ test/CodeGenCXX/no-exceptions.cpp @@ -11,4 +11,4 @@ // CHECK: ret void } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/optnone-class-members.cpp =================================================================== --- test/CodeGenCXX/optnone-class-members.cpp +++ test/CodeGenCXX/optnone-class-members.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -x c++ | FileCheck %s +// RUN: %clang_cc1 < %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-optzns -emit-llvm -x c++ | FileCheck %s // Test attribute 'optnone' on methods: // -- member functions; Index: test/CodeGenCXX/optnone-def-decl.cpp =================================================================== --- test/CodeGenCXX/optnone-def-decl.cpp +++ test/CodeGenCXX/optnone-def-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fms-extensions -O2 -disable-llvm-optzns -emit-llvm -o - | FileCheck %s // Test optnone on both function declarations and function definitions. // Verify also that we don't generate invalid IR functions with Index: test/CodeGenCXX/reference-cast.cpp =================================================================== --- test/CodeGenCXX/reference-cast.cpp +++ test/CodeGenCXX/reference-cast.cpp @@ -193,4 +193,4 @@ // CHECK: store i64 } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/threadsafe-statics.cpp =================================================================== --- test/CodeGenCXX/threadsafe-statics.cpp +++ test/CodeGenCXX/threadsafe-statics.cpp @@ -22,6 +22,6 @@ // NO-TSS-NOT: call void @__cxa_guard_release // NO-TSS: ret void -// WITH-TSS: attributes [[NUW]] = { nounwind{{.*}} } +// WITH-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} } -// NO-TSS: attributes [[NUW]] = { nounwind{{.*}} } +// NO-TSS: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenCXX/thunks.cpp =================================================================== --- test/CodeGenCXX/thunks.cpp +++ test/CodeGenCXX/thunks.cpp @@ -405,4 +405,4 @@ // CHECK-OPT-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv // CHECK-OPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv -// CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind uwtable{{.*}} } Index: test/CodeGenCXX/virtual-base-cast.cpp =================================================================== --- test/CodeGenCXX/virtual-base-cast.cpp +++ test/CodeGenCXX/virtual-base-cast.cpp @@ -82,4 +82,4 @@ // MSVC: add nsw i32 4, %[[offset]] // MSVC: } -// CHECK: attributes [[NUW]] = { nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenObjC/gnu-exceptions.m =================================================================== --- test/CodeGenObjC/gnu-exceptions.m +++ test/CodeGenObjC/gnu-exceptions.m @@ -32,4 +32,4 @@ log(1); } -// CHECK: attributes [[TF]] = { "{{.*}} } +// CHECK: attributes [[TF]] = { noinline "{{.*}} } Index: test/CodeGenObjC/objc-literal-tests.m =================================================================== --- test/CodeGenObjC/objc-literal-tests.m +++ test/CodeGenObjC/objc-literal-tests.m @@ -94,4 +94,4 @@ bar(^(void) { return YES; }); } -// CHECK: attributes [[NUW]] = { {{(norecurse )?}}nounwind{{.*}} } +// CHECK: attributes [[NUW]] = { noinline {{(norecurse )?}}nounwind{{.*}} } Index: test/CodeGenObjCXX/lambda-expressions.mm =================================================================== --- test/CodeGenObjCXX/lambda-expressions.mm +++ test/CodeGenObjCXX/lambda-expressions.mm @@ -125,5 +125,5 @@ } -// ARC: attributes [[NUW]] = { nounwind{{.*}} } -// MRC: attributes [[NUW]] = { nounwind{{.*}} } +// ARC: attributes [[NUW]] = { noinline nounwind{{.*}} } +// MRC: attributes [[NUW]] = { noinline nounwind{{.*}} } Index: test/CodeGenOpenCL/amdgpu-attrs.cl =================================================================== --- test/CodeGenOpenCL/amdgpu-attrs.cl +++ test/CodeGenOpenCL/amdgpu-attrs.cl @@ -141,26 +141,26 @@ // CHECK-NOT: "amdgpu-num-sgpr"="0" // CHECK-NOT: "amdgpu-num-vgpr"="0" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" -// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { nounwind "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { nounwind "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32" -// CHECK-DAG: attributes [[NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" +// CHECK-DAG: attributes [[WAVES_PER_EU_2]] = { noinline nounwind "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[WAVES_PER_EU_2_4]] = { noinline nounwind "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32" +// CHECK-DAG: attributes [[NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" -// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" +// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" -// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2" +// CHECK-DAG: attributes [[FLAT_WORK_GROUP_SIZE_32_64_WAVES_PER_EU_2_4_NUM_SGPR_32_NUM_VGPR_64]] = { noinline nounwind "amdgpu-flat-work-group-size"="32,64" "amdgpu-num-sgpr"="32" "amdgpu-num-vgpr"="64" "amdgpu-waves-per-eu"="2,4" Index: test/Driver/darwin-iphone-defaults.m =================================================================== --- test/Driver/darwin-iphone-defaults.m +++ test/Driver/darwin-iphone-defaults.m @@ -26,4 +26,4 @@ [I1 alloc]; } -// CHECK: attributes [[F0]] = { ssp{{.*}} } +// CHECK: attributes [[F0]] = { noinline ssp{{.*}} } Index: test/PCH/objc_container.m =================================================================== --- test/PCH/objc_container.m +++ test/PCH/objc_container.m @@ -21,5 +21,5 @@ // CHECK-IR: {{call.*objc_msgSend}} // CHECK-IR: ret void -// CHECK-IR: attributes #0 = { nounwind {{.*}} } +// CHECK-IR: attributes #0 = { noinline nounwind {{.*}} } // CHECK-IR: attributes #1 = { nonlazybind }