https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/163666
>From 27d6d60f6805ab4b5aae1f6303b9564409def860 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Wed, 15 Oct 2025 17:26:19 -0700 Subject: [PATCH 1/5] [clang] Add clang::nooutline Attribute This change: - Adds a `[[clang::nooutline]]` function attribute for C and C++. There is no equivalent GNU syntax for this attribute, so no `__attribute__` syntax. - Uses the presence of `[[clang::nooutline]]` to add the `nooutline` attribute to IR function definitions. - Adds test for the above. The `nooutline` attribute disables both the Machine Outliner (enabled at Oz for some targets), and the IR Outliner (disabled by default). --- clang/include/clang/Basic/Attr.td | 7 +++++++ clang/lib/CodeGen/CodeGenModule.cpp | 3 +++ clang/test/CodeGen/attr-nooutline.c | 16 ++++++++++++++++ ...agma-attribute-supported-attributes-list.test | 1 + clang/test/Sema/attr-nooutline.c | 7 +++++++ clang/test/Sema/attr-nooutline.cpp | 7 +++++++ 6 files changed, 41 insertions(+) create mode 100644 clang/test/CodeGen/attr-nooutline.c create mode 100644 clang/test/Sema/attr-nooutline.c create mode 100644 clang/test/Sema/attr-nooutline.cpp diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ea3f9df6d8342..361ae41da97dc 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2371,6 +2371,13 @@ def NoInline : DeclOrStmtAttr { let SimpleHandler = 1; } +def NoOutline : DeclOrStmtAttr { + let Spellings = [CXX11<"clang", "nooutline">, C23<"clang", "nooutline">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [Undocumented]; + let SimpleHandler = 1; +} + def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { let Spellings = [GCC<"nomips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 65f5468c4b998..6a087be3751f0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2928,6 +2928,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::MinSize); } + if (D->hasAttr<NoOutlineAttr>()) + B.addAttribute(llvm::Attribute::NoOutline); + F->addFnAttrs(B); unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c new file mode 100644 index 0000000000000..b9f175da24cb5 --- /dev/null +++ b/clang/test/CodeGen/attr-nooutline.c @@ -0,0 +1,16 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -disable-O0-optnone -o - | FileCheck %s + + +// CHECK: Function Attrs: noinline nooutline nounwind +// CHECK-LABEL: define dso_local i32 @t1( +// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// +[[clang::nooutline]] int t1(int x) { + return x; +} diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index d6d900f3caf84..a7c667fa6018d 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -130,6 +130,7 @@ // CHECK-NEXT: NoMerge (SubjectMatchRule_function, SubjectMatchRule_variable) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) // CHECK-NEXT: NoMips16 (SubjectMatchRule_function) +// CHECK-NEXT: NoOutline (SubjectMatchRule_function) // CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function) // CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record) // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global) diff --git a/clang/test/Sema/attr-nooutline.c b/clang/test/Sema/attr-nooutline.c new file mode 100644 index 0000000000000..83848c22d1003 --- /dev/null +++ b/clang/test/Sema/attr-nooutline.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only + +[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} + +[[clang::nooutline]] void t1(void); + +[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} diff --git a/clang/test/Sema/attr-nooutline.cpp b/clang/test/Sema/attr-nooutline.cpp new file mode 100644 index 0000000000000..b6c9b3995081a --- /dev/null +++ b/clang/test/Sema/attr-nooutline.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions + +[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} + +[[clang::nooutline]] void t1(void); + +[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} >From 5a8495bb7145cc77933164cfeeca3b1a75531901 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 13:25:32 -0700 Subject: [PATCH 2/5] Address reviewer feedback: Tests, Docs, TableGen --- clang/include/clang/Basic/Attr.td | 4 ++-- clang/include/clang/Basic/AttrDocs.td | 30 +++++++++++++++++++++++++++ clang/test/CodeGen/attr-nooutline.c | 29 +++++++++++++++++--------- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 361ae41da97dc..f2a372503c041 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2372,9 +2372,9 @@ def NoInline : DeclOrStmtAttr { } def NoOutline : DeclOrStmtAttr { - let Spellings = [CXX11<"clang", "nooutline">, C23<"clang", "nooutline">]; + let Spellings = [Clang<"nooutline">]; let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [Undocumented]; + let Documentation = [NoOutlineDocs]; let SimpleHandler = 1; } diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index cad45501df6d2..67fadaff6e4a9 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -862,6 +862,36 @@ with ``__noinline__`` defined as a macro as ``__attribute__((noinline))``. }]; } +def NoOutlineDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This function attribute suppresses outlining from the annotated function. + +Outlining is the process where common parts of separate functions are extracted +into a separate function (or assembly snippet), and calls to that function or +snippet are inserted in the original functions. In this way, it can be seen as +the opposite of inlining. It can help to reduce code size. + +.. code-block:: c + + [[clang::nooutline]] int x1(int y) { + int z = COMPLEX_MACRO(y); // Not outlined + return z + const1; + } + + int x2(int y) { + int z = COMPLEX_MACRO(y); // May be outlined + return z * const2; + } + + int x3(int y) { + int z = COMPLEX_MACRO(y); // May be outlined + reutrn z / const3; + } + + }]; +} + def MustTailDocs : Documentation { let Category = DocCatStmt; let Content = [{ diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c index b9f175da24cb5..8519414397a8b 100644 --- a/clang/test/CodeGen/attr-nooutline.c +++ b/clang/test/CodeGen/attr-nooutline.c @@ -1,15 +1,24 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 -// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -disable-O0-optnone -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=CXX - -// CHECK: Function Attrs: noinline nooutline nounwind -// CHECK-LABEL: define dso_local i32 @t1( -// CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -// CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 -// CHECK-NEXT: ret i32 [[TMP0]] +// C: Function Attrs: noinline nooutline nounwind optnone +// C-LABEL: define dso_local i32 @t1( +// C-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// C-NEXT: [[ENTRY:.*:]] +// C-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// C-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// C-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// C-NEXT: ret i32 [[TMP0]] +// +// CXX: Function Attrs: mustprogress noinline nooutline nounwind optnone +// CXX-LABEL: define dso_local noundef i32 @_Z2t1i( +// CXX-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CXX-NEXT: [[ENTRY:.*:]] +// CXX-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 +// CXX-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 +// CXX-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 +// CXX-NEXT: ret i32 [[TMP0]] // [[clang::nooutline]] int t1(int x) { return x; >From f3dd70b17a3f0b5be70c6c74fd6be5f90ae62564 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 13:46:36 -0700 Subject: [PATCH 3/5] Release Notes --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59fdbc80e8bed..91571aee7ad6c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -138,6 +138,9 @@ Non-comprehensive list of changes in this release Usable in constant expressions. Implicit conversion is supported for class/struct types with conversion operators. +- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from + annotated functions. This uses the LLVM `nooutline` attribute. + New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added >From cf49e40141a958eb91db61fe64d0871ce6552bf6 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 14:07:51 -0700 Subject: [PATCH 4/5] Address Review Feedback: Flags, Release Notes --- clang/docs/ReleaseNotes.rst | 6 +++--- clang/test/Sema/attr-nooutline.c | 2 +- clang/test/Sema/attr-nooutline.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 91571aee7ad6c..3c40407faf9d1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -138,9 +138,6 @@ Non-comprehensive list of changes in this release Usable in constant expressions. Implicit conversion is supported for class/struct types with conversion operators. -- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from - annotated functions. This uses the LLVM `nooutline` attribute. - New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added @@ -165,6 +162,9 @@ Attribute Changes in Clang will still generate a stack protector if other local variables or command line flags require it. +- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from + annotated functions. This uses the LLVM `nooutline` attribute. + Improvements to Clang's diagnostics ----------------------------------- - Added ``-Wlifetime-safety`` to enable lifetime safety analysis, diff --git a/clang/test/Sema/attr-nooutline.c b/clang/test/Sema/attr-nooutline.c index 83848c22d1003..ceb77c5d59bd8 100644 --- a/clang/test/Sema/attr-nooutline.c +++ b/clang/test/Sema/attr-nooutline.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 -verify -fsyntax-only %s [[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} diff --git a/clang/test/Sema/attr-nooutline.cpp b/clang/test/Sema/attr-nooutline.cpp index b6c9b3995081a..ceb77c5d59bd8 100644 --- a/clang/test/Sema/attr-nooutline.cpp +++ b/clang/test/Sema/attr-nooutline.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions +// RUN: %clang_cc1 -verify -fsyntax-only %s [[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} >From a0cf394ff731797b7e9069ef2a5399df71afb67b Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Tue, 10 Feb 2026 17:57:41 -0800 Subject: [PATCH 5/5] Change spelling to clang::no_outline, more tests --- clang/docs/ReleaseNotes.rst | 2 +- clang/include/clang/Basic/Attr.td | 6 +- clang/include/clang/Basic/AttrDocs.td | 18 --- clang/test/CodeGen/attr-no-outline.c | 107 ++++++++++++++++++ clang/test/CodeGen/attr-nooutline.c | 25 ---- clang/test/CodeGenObjC/attr-no-outline.m | 40 +++++++ ...a-attribute-supported-attributes-list.test | 2 +- clang/test/Sema/attr-no-outline.c | 7 ++ clang/test/Sema/attr-no-outline.cpp | 7 ++ clang/test/Sema/attr-nooutline.c | 7 -- clang/test/Sema/attr-nooutline.cpp | 7 -- 11 files changed, 166 insertions(+), 62 deletions(-) create mode 100644 clang/test/CodeGen/attr-no-outline.c delete mode 100644 clang/test/CodeGen/attr-nooutline.c create mode 100644 clang/test/CodeGenObjC/attr-no-outline.m create mode 100644 clang/test/Sema/attr-no-outline.c create mode 100644 clang/test/Sema/attr-no-outline.cpp delete mode 100644 clang/test/Sema/attr-nooutline.c delete mode 100644 clang/test/Sema/attr-nooutline.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3c40407faf9d1..5bc96736e108e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -162,7 +162,7 @@ Attribute Changes in Clang will still generate a stack protector if other local variables or command line flags require it. -- Added a new attribute, ``[[clang::nooutline]]`` to suppress outlining from +- Added a new attribute, ``[[clang::no_outline]]`` to suppress outlining from annotated functions. This uses the LLVM `nooutline` attribute. Improvements to Clang's diagnostics diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f2a372503c041..2621d178d99e8 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2372,10 +2372,10 @@ def NoInline : DeclOrStmtAttr { } def NoOutline : DeclOrStmtAttr { - let Spellings = [Clang<"nooutline">]; - let Subjects = SubjectList<[Function], ErrorDiag>; + let Spellings = [Clang<"no_outline">]; + let Subjects = SubjectList<[Function, ObjCMethod, Block], ErrorDiag>; let Documentation = [NoOutlineDocs]; - let SimpleHandler = 1; + let SimpleHandler = true; } def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 67fadaff6e4a9..f91fe2c7b0259 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -871,24 +871,6 @@ Outlining is the process where common parts of separate functions are extracted into a separate function (or assembly snippet), and calls to that function or snippet are inserted in the original functions. In this way, it can be seen as the opposite of inlining. It can help to reduce code size. - -.. code-block:: c - - [[clang::nooutline]] int x1(int y) { - int z = COMPLEX_MACRO(y); // Not outlined - return z + const1; - } - - int x2(int y) { - int z = COMPLEX_MACRO(y); // May be outlined - return z * const2; - } - - int x3(int y) { - int z = COMPLEX_MACRO(y); // May be outlined - reutrn z / const3; - } - }]; } diff --git a/clang/test/CodeGen/attr-no-outline.c b/clang/test/CodeGen/attr-no-outline.c new file mode 100644 index 0000000000000..60d2ab5563f34 --- /dev/null +++ b/clang/test/CodeGen/attr-no-outline.c @@ -0,0 +1,107 @@ +// RUN: %clang_cc1 -emit-llvm -x c %s -triple x86_64-unknown-linux-gnu -o - -femit-all-decls -fblocks | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - -femit-all-decls -fblocks | FileCheck %s --check-prefix=CXX +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - -femit-all-decls -fblocks -std=c++23 | FileCheck %s --check-prefixes=CXX,CXX23 + +// C-LABEL: define dso_local i32 @toplevel_func( +// C-SAME: ) #[[ATTR0:[0-9]+]] { + +// CXX-LABEL: define dso_local noundef i32 @_Z13toplevel_funci( +// CXX-SAME: ) #[[ATTR0:[0-9]+]] { +[[clang::no_outline]] int toplevel_func(int x) { + return x; +} + + +// C-only: Function without prototype +#ifndef __cplusplus +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-non-prototype" +#pragma clang diagnostic ignored "-Wimplicit-int" + +// C-LABEL: define dso_local i32 @no_proto_func( +// C-SAME: ) #[[ATTR0]] { + +[[clang::no_outline]] no_proto_func(x) +int x; { + return x; +} + +#pragma clang diagnostic pop +#endif + +// With Blocks +#if __has_feature(blocks) + +int func_with_block(int x) { +// C-LABEL: define internal i32 @__func_with_block_block_invoke( +// C-SAME: ) #[[ATTR0]] { + +// CXX-LABEL: define internal noundef i32 @___Z15func_with_blocki_block_invoke( +// CXX-SAME: ) #[[ATTR1:[0-9]+]] { + + int (^block)(int) = ^ __attribute__((no_outline)) int (int y) { return y; }; + + return block(x); +} +#endif + +// C++-only: Member Functions, Lambdas, Templates +#ifdef __cplusplus + +struct my_struct { + +// CXX-LABEL: define linkonce_odr noundef i32 @_ZN9my_struct11member_funcEi( +// CXX-SAME: ) #[[ATTR0]] comdat + [[clang::no_outline]] int member_func(int x) { + return x; + } + +// CXX-LABEL: define linkonce_odr noundef i32 @_ZN9my_struct11static_funcEi( +// CXX-SAME: ) #[[ATTR0]] comdat + [[clang::no_outline]] static int static_func(int x) { + return x; + } +}; + +template <typename T> struct templated_struct { + [[clang::no_outline]] T member_func(T x) { + return x; + } + + [[clang::no_outline]] static T static_func(T x) { + return x; + } +}; + +// CXX-LABEL: define weak_odr noundef i32 @_ZN16templated_structIiE11member_funcEi( +// CXX-SAME: ) #[[ATTR0]] comdat +// CXX-LABEL: define weak_odr noundef i32 @_ZN16templated_structIiE11static_funcEi( +// CXX-SAME: ) #[[ATTR0]] comdat +template struct templated_struct<int>; + + +#if __cplusplus >= 202302L +int func_with_lambda(int x) { + // CXX23-LABEL: define internal noundef i32 @"_ZZ16func_with_lambdaiENK3$_0clEv"( + // CXX23-SAME: ) #[[ATTR0]] + auto lambda = [x][[clang::no_outline]]() -> int { + return x; + }; + + return lambda(); +} +#endif +#endif + + +// C: attributes #[[ATTR0]] = { +// C-SAME: nooutline +// C-SAME: } + +// CXX: attributes #[[ATTR0]] = { +// CXX-SAME: nooutline +// CXX-SAME: } + +// CXX: attributes #[[ATTR1]] = { +// CXX-SAME: nooutline +// CXX-SAME: } diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c deleted file mode 100644 index 8519414397a8b..0000000000000 --- a/clang/test/CodeGen/attr-nooutline.c +++ /dev/null @@ -1,25 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 -// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=C -// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=CXX - -// C: Function Attrs: noinline nooutline nounwind optnone -// C-LABEL: define dso_local i32 @t1( -// C-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { -// C-NEXT: [[ENTRY:.*:]] -// C-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -// C-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 -// C-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 -// C-NEXT: ret i32 [[TMP0]] -// -// CXX: Function Attrs: mustprogress noinline nooutline nounwind optnone -// CXX-LABEL: define dso_local noundef i32 @_Z2t1i( -// CXX-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { -// CXX-NEXT: [[ENTRY:.*:]] -// CXX-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 -// CXX-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 -// CXX-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 -// CXX-NEXT: ret i32 [[TMP0]] -// -[[clang::nooutline]] int t1(int x) { - return x; -} diff --git a/clang/test/CodeGenObjC/attr-no-outline.m b/clang/test/CodeGenObjC/attr-no-outline.m new file mode 100644 index 0000000000000..f2f5e790386f1 --- /dev/null +++ b/clang/test/CodeGenObjC/attr-no-outline.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s --check-prefix=OBJC +// RUN: %clang_cc1 -emit-llvm -x objective-c++ %s -o - | FileCheck %s --check-prefix=OBJCXX + +@interface Test +- (int)method:(int)x; ++ (int)static_method:(int)x; +@end + +@implementation Test + +// OBJC-LABEL: define internal i32 @"\01-[Test method:]"( +// OBJC: ) #[[ATTR0:[0-9]+]] { + +// OBJCXX-LABEL: define internal noundef i32 @"\01-[Test method:]"( +// OBJCXX: ) #[[ATTR0:[0-9]+]] { +- (int)method:(int)x [[clang::no_outline]] { + return x; +} + +// OBJC-LABEL: define internal i32 @"\01+[Test static_method:]"( +// OBJC: ) #[[ATTR0]] { + +// OBJCXX-LABEL: define internal noundef i32 @"\01+[Test static_method:]"( +// OBJCXX: ) #[[ATTR0]] { ++ (int)static_method:(int)x [[clang::no_outline]] { + return x; +} + +@end + +// OBJC: attributes #[[ATTR0]] = { +// OBJC-SAME: nooutline +// OBJC-SAME: } + +// OBJCXX: attributes #[[ATTR0]] = { +// OBJCXX-SAME: nooutline +// OBJCXX-SAME: } + + + diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index a7c667fa6018d..626a0743238d5 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -130,7 +130,7 @@ // CHECK-NEXT: NoMerge (SubjectMatchRule_function, SubjectMatchRule_variable) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) // CHECK-NEXT: NoMips16 (SubjectMatchRule_function) -// CHECK-NEXT: NoOutline (SubjectMatchRule_function) +// CHECK-NEXT: NoOutline (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_block) // CHECK-NEXT: NoProfileFunction (SubjectMatchRule_function) // CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record) // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global) diff --git a/clang/test/Sema/attr-no-outline.c b/clang/test/Sema/attr-no-outline.c new file mode 100644 index 0000000000000..d6ddc2a1349d0 --- /dev/null +++ b/clang/test/Sema/attr-no-outline.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +[[clang::no_outline]] int a; // expected-error {{'clang::no_outline' attribute only applies to functions}} + +[[clang::no_outline]] void t1(void); + +[[clang::no_outline(2)]] void t2(void); // expected-error {{'clang::no_outline' attribute takes no arguments}} diff --git a/clang/test/Sema/attr-no-outline.cpp b/clang/test/Sema/attr-no-outline.cpp new file mode 100644 index 0000000000000..d6ddc2a1349d0 --- /dev/null +++ b/clang/test/Sema/attr-no-outline.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +[[clang::no_outline]] int a; // expected-error {{'clang::no_outline' attribute only applies to functions}} + +[[clang::no_outline]] void t1(void); + +[[clang::no_outline(2)]] void t2(void); // expected-error {{'clang::no_outline' attribute takes no arguments}} diff --git a/clang/test/Sema/attr-nooutline.c b/clang/test/Sema/attr-nooutline.c deleted file mode 100644 index ceb77c5d59bd8..0000000000000 --- a/clang/test/Sema/attr-nooutline.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s - -[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} - -[[clang::nooutline]] void t1(void); - -[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} diff --git a/clang/test/Sema/attr-nooutline.cpp b/clang/test/Sema/attr-nooutline.cpp deleted file mode 100644 index ceb77c5d59bd8..0000000000000 --- a/clang/test/Sema/attr-nooutline.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s - -[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} - -[[clang::nooutline]] void t1(void); - -[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
