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 <[email protected]>
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 <[email protected]>
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;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to