[clang] [clang] Add noipa attribute (PR #207502)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jul 4 02:54:04 PDT 2026
https://github.com/Disservin created https://github.com/llvm/llvm-project/pull/207502
Adds a `__attribute__((noipa))` attribute to clang, more info on this attribute can be found in #203304.
We also set the noinline attribute on the targeted function as pointed out by @jryans in #203304.
fixes https://github.com/llvm/llvm-project/issues/40819
Assisted by GPT 5.4 for tests
>From 0f3be6f5f12219590ea10ff7cdd7e9bb0e60ba87 Mon Sep 17 00:00:00 2001
From: Disservin <disservin.social at gmail.com>
Date: Sat, 4 Jul 2026 10:57:45 +0200
Subject: [PATCH 1/2] Add tests
---
clang/test/CodeGen/attr-noipa.c | 28 +++++++++++++++++++
...a-attribute-supported-attributes-list.test | 1 +
clang/test/Sema/attr-noipa.c | 7 +++++
clang/test/Sema/attr-noipa.cpp | 7 +++++
4 files changed, 43 insertions(+)
create mode 100644 clang/test/CodeGen/attr-noipa.c
create mode 100644 clang/test/Sema/attr-noipa.c
create mode 100644 clang/test/Sema/attr-noipa.cpp
diff --git a/clang/test/CodeGen/attr-noipa.c b/clang/test/CodeGen/attr-noipa.c
new file mode 100644
index 0000000000000..82394793827f1
--- /dev/null
+++ b/clang/test/CodeGen/attr-noipa.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -x c %s -triple x86_64-unknown-linux-gnu -O1 -o - | FileCheck %s --check-prefix=C
+// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -std=c++23 -O1 -o - | FileCheck %s --check-prefix=CXX
+
+// C-LABEL: define {{.*}} @with_noipa(
+// C-SAME: ) {{.*}}#[[NOIPA_ATTR:[0-9]+]] {
+__attribute__((noipa)) int with_noipa(int x) {
+ return x + 1;
+}
+
+// C-LABEL: define {{.*}} @without_noipa(
+// C-SAME: ) {{.*}}#[[PLAIN_ATTR:[0-9]+]] {
+int without_noipa(int x) {
+ return x - 1;
+}
+
+// CXX-LABEL: define {{.*}} @_Z10with_noipai(
+// CXX-SAME: ) {{.*}}#[[NOIPA_ATTR:[0-9]+]] {
+
+// CXX-LABEL: define {{.*}} @_Z13without_noipai(
+// CXX-SAME: ) {{.*}}#[[PLAIN_ATTR:[0-9]+]] {
+
+// C: attributes #[[NOIPA_ATTR]] = { {{.*}}noipa{{.*}} }
+// C: attributes #[[PLAIN_ATTR]] = { {{.*}} }
+// C-NOT: attributes #[[PLAIN_ATTR]] = { {{.*}}noipa{{.*}} }
+
+// CXX: attributes #[[NOIPA_ATTR]] = { {{.*}}noipa{{.*}} }
+// CXX: attributes #[[PLAIN_ATTR]] = { {{.*}} }
+// CXX-NOT: attributes #[[PLAIN_ATTR]] = { {{.*}}noipa{{.*}} }
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 8bca68e2119e7..f952a4e57543c 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -127,6 +127,7 @@
// CHECK-NEXT: NoDuplicate (SubjectMatchRule_function)
// CHECK-NEXT: NoEscape (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: NoFieldProtection (SubjectMatchRule_field)
+// CHECK-NEXT: NoIPA (SubjectMatchRule_function)
// CHECK-NEXT: NoInline (SubjectMatchRule_function)
// CHECK-NEXT: NoInstrumentFunction (SubjectMatchRule_function, SubjectMatchRule_objc_method)
// CHECK-NEXT: NoMerge (SubjectMatchRule_function, SubjectMatchRule_variable)
diff --git a/clang/test/Sema/attr-noipa.c b/clang/test/Sema/attr-noipa.c
new file mode 100644
index 0000000000000..a22e04dd71ca3
--- /dev/null
+++ b/clang/test/Sema/attr-noipa.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+__attribute__((noipa)) int a; // expected-warning {{'noipa' attribute only applies to functions}}
+
+__attribute__((noipa)) void t1(void);
+
+__attribute__((noipa(2))) void t2(void); // expected-error {{'noipa' attribute takes no arguments}}
diff --git a/clang/test/Sema/attr-noipa.cpp b/clang/test/Sema/attr-noipa.cpp
new file mode 100644
index 0000000000000..1d4cb60c84d0a
--- /dev/null
+++ b/clang/test/Sema/attr-noipa.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+__attribute__((noipa)) int a; // expected-warning {{'noipa' attribute only applies to functions}}
+
+__attribute__((noipa)) void t1();
+
+__attribute__((noipa(2))) void t2(); // expected-error {{'noipa' attribute takes no arguments}}
>From 10c677422bd1e1a166af928aaa943f9546b099ff Mon Sep 17 00:00:00 2001
From: Disservin <disservin.social at gmail.com>
Date: Sat, 4 Jul 2026 10:57:55 +0200
Subject: [PATCH 2/2] [clang] Add noipa attribute
---
clang/include/clang/Basic/Attr.td | 7 +++++++
clang/include/clang/Basic/AttrDocs.td | 10 ++++++++++
clang/lib/CodeGen/CodeGenModule.cpp | 6 ++++++
3 files changed, 23 insertions(+)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 3f57104d474a7..3123ae3d369c3 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2420,6 +2420,13 @@ def NoOutline : DeclOrStmtAttr {
let SimpleHandler = true;
}
+def NoIPA : InheritableAttr {
+ let Spellings = [GCC<"noipa">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [NoIPADocs];
+ let SimpleHandler = 1;
+}
+
def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> {
let Spellings = [GCC<"nomips16">];
let Subjects = SubjectList<[Function], ErrorDiag>;
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index b67a5b076237c..37d0f303a8cfc 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1043,6 +1043,16 @@ the opposite of inlining. It can help to reduce code size.
}];
}
+def NoIPADocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+This function attribute suppresses interprocedural optimization involving the
+annotated function. Clang lowers it to LLVM IR's ``noipa`` function attribute
+and sets the ```noinline`` function attribute as well, unless always_inline
+is specified.
+ }];
+}
+
def MustTailDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 813cd67e4dd51..c9ddfbaa9a4e7 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3105,6 +3105,12 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if (CodeGenOpts.DisableOutlining || D->hasAttr<NoOutlineAttr>())
B.addAttribute(llvm::Attribute::NoOutline);
+ if (D->hasAttr<NoIPAAttr>()) {
+ B.addAttribute(llvm::Attribute::NoIPA);
+ if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline))
+ B.addAttribute(llvm::Attribute::NoInline);
+ }
+
F->addFnAttrs(B);
llvm::MaybeAlign ExplicitAlignment;
More information about the cfe-commits
mailing list