-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang] Add support for [[msvc::noinline]] attribute. #91720
Conversation
@llvm/pr-subscribers-clang Author: Xu Zhang (simonzgx) ChangesFull diff: https://github.com/llvm/llvm-project/pull/91720.diff 3 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 0225598cbbe8a..2c7a238f61764 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1997,9 +1997,12 @@ def Convergent : InheritableAttr {
def NoInline : DeclOrStmtAttr {
let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">,
CXX11<"clang", "noinline">, C23<"clang", "noinline">,
+ CXX11<"msvc", "noinline">, C23<"msvc", "noinline">,
Declspec<"noinline">];
let Accessors = [Accessor<"isClangNoInline", [CXX11<"clang", "noinline">,
- C23<"clang", "noinline">]>];
+ C23<"clang", "noinline">,
+ CXX11<"msvc", "noinline">,
+ C23<"msvc", "noinline">]>];
let Documentation = [NoInlineDocs];
let Subjects = SubjectList<[Function, Stmt], WarnDiag,
"functions and statements">;
diff --git a/clang/test/CodeGen/attr-ms-noinline.cpp b/clang/test/CodeGen/attr-ms-noinline.cpp
new file mode 100644
index 0000000000000..99b0a05af715d
--- /dev/null
+++ b/clang/test/CodeGen/attr-ms-noinline.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
+
+bool bar();
+void f(bool, bool);
+void g(bool);
+
+static int baz(int x) {
+ return x * 10;
+}
+
+[[msvc::noinline]] bool noi() { }
+
+void foo(int i) {
+ [[msvc::noinline]] bar();
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR:[0-9]+]]
+ [[msvc::noinline]] i = baz(i);
+// CHECK: call noundef i32 @_ZL3bazi({{.*}}) #[[NOINLINEATTR]]
+ [[msvc::noinline]] (i = 4, bar());
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+ [[msvc::noinline]] (void)(bar());
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+ [[msvc::noinline]] f(bar(), bar());
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+// CHECK: call void @_Z1fbb({{.*}}) #[[NOINLINEATTR]]
+ [[msvc::noinline]] [] { bar(); bar(); }(); // noinline only applies to the anonymous function call
+// CHECK: call void @"_ZZ3fooiENK3$_0clEv"(ptr {{[^,]*}} %ref.tmp) #[[NOINLINEATTR]]
+ [[msvc::noinline]] for (bar(); bar(); bar()) {}
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+// CHECK: call noundef zeroext i1 @_Z3barv() #[[NOINLINEATTR]]
+ bar();
+// CHECK: call noundef zeroext i1 @_Z3barv()
+ [[msvc::noinline]] noi();
+// CHECK: call noundef zeroext i1 @_Z3noiv()
+ noi();
+// CHECK: call noundef zeroext i1 @_Z3noiv()
+}
+
+struct S {
+ friend bool operator==(const S &LHS, const S &RHS);
+};
+
+void func(const S &s1, const S &s2) {
+ [[msvc::noinline]]g(s1 == s2);
+// CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]]
+// CHECK: call void @_Z1gb({{.*}}) #[[NOINLINEATTR]]
+ bool b;
+ [[msvc::noinline]] b = s1 == s2;
+// CHECK: call noundef zeroext i1 @_ZeqRK1SS1_({{.*}}) #[[NOINLINEATTR]]
+}
+
+// CHECK: attributes #[[NOINLINEATTR]] = { noinline }
diff --git a/clang/test/Sema/attr-ms-noinline.cpp b/clang/test/Sema/attr-ms-noinline.cpp
new file mode 100644
index 0000000000000..292d34a41e411
--- /dev/null
+++ b/clang/test/Sema/attr-ms-noinline.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions
+
+int bar();
+
+void foo() {
+ [[msvc::noinline]] bar();
+ [[msvc::noinline(0)]] bar(); // expected-error {{'noinline' attribute takes no arguments}}
+ int x;
+ [[msvc::noinline]] x = 0; // expected-warning {{'noinline' attribute is ignored because there exists no call expression inside the statement}}
+ [[msvc::noinline]] { asm("nop"); } // expected-warning {{'noinline' attribute is ignored because there exists no call expression inside the statement}}
+ [[msvc::noinline]] label: x = 1; // expected-warning {{'noinline' attribute only applies to functions and statements}}
+
+
+ [[msvc::noinline]] always_inline_fn(); // expected-warning {{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ [[msvc::noinline]] flatten_fn(); // expected-warning {{statement attribute 'noinline' has higher precedence than function attribute 'flatten'}}
+ [[msvc::noinline]] noinline_fn();
+}
+
+[[msvc::noinline]] static int i = bar(); // expected-warning {{'noinline' attribute only applies to functions and statements}}
+
+// This used to crash the compiler.
+template<int D>
+int foo(int x) {
+ [[msvc::noinline]] return foo<D-1>(x + 1);
+}
+
+template<int D>
+[[msvc::always_inline]]
+int dependent(int x){ return x + D;} // #DEP
+[[msvc::always_inline]]
+int non_dependent(int x){return x;} // #NO_DEP
+
+template<int D> [[clang::always_inline]]
+int baz(int x) { // #BAZ
+ // expected-warning@+2{{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ // expected-note@#NO_DEP{{conflicting attribute is here}}
+ [[msvc::noinline]] non_dependent(x);
+ if constexpr (D>0) {
+ // expected-warning@+6{{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ // expected-note@#NO_DEP{{conflicting attribute is here}}
+ // expected-warning@+4 3{{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ // expected-note@#BAZ 3{{conflicting attribute is here}}
+ // expected-note@#BAZ_INST 3{{in instantiation}}
+ // expected-note@+1 3{{in instantiation}}
+ [[msvc::noinline]] return non_dependent(x), baz<D-1>(x + 1);
+ }
+ return x;
+}
+
+// We can't suppress if there is a variadic involved.
+template<int ... D>
+int variadic_baz(int x) {
+ // Diagnoses NO_DEP 2x, once during phase 1, the second during instantiation.
+ // Dianoses DEP 3x, once per variadic expansion.
+ // expected-warning@+5 2{{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ // expected-note@#NO_DEP 2{{conflicting attribute is here}}
+ // expected-warning@+3 3{{statement attribute 'noinline' has higher precedence than function attribute 'always_inline'}}
+ // expected-note@#DEP 3{{conflicting attribute is here}}
+ // expected-note@#VARIADIC_INST{{in instantiation}}
+ [[msvc::noinline]] return non_dependent(x) + (dependent<D>(x) + ...);
+}
+
+void use() {
+ baz<3>(0); // #BAZ_INST
+ variadic_baz<0, 1, 2>(0); // #VARIADIC_INST
+}
|
1d7973b
to
e17ba55
Compare
e17ba55
to
2029279
Compare
Hi @cor3ntin, could you please help review this patch? |
Hi @cor3ntin , this is just a gentle reminder to confirm if it is still convenient for you to review this patch, or if you could assist in inviting other appropriate reviewers? Thank you. |
clang/include/clang/Basic/Attr.td
Outdated
@@ -1997,9 +1997,12 @@ def Convergent : InheritableAttr { | |||
def NoInline : DeclOrStmtAttr { | |||
let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">, | |||
CXX11<"clang", "noinline">, C23<"clang", "noinline">, | |||
CXX11<"msvc", "noinline">, C23<"msvc", "noinline">, | |||
Declspec<"noinline">]; | |||
let Accessors = [Accessor<"isClangNoInline", [CXX11<"clang", "noinline">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably have a different name for this, since it is no longer accurate. Perhaps isStmtNoInline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to add a new accessors and name it isStmtNoInline
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just a rename. This is only used to reject this on a statement if it is NOT (currently) the clang spelling, then suggest the clang spelling. I think the behavior of suggesting [[clang::noinline]]
is still fine, but isClangNoInline
isn't an accurate name if spelled [[msvc::noinline]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, got it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
clang/test/Sema/attr-ms-noinline.cpp
Outdated
@@ -0,0 +1,72 @@ | |||
// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is a copy/paste of the other one, I'd rather see this added into the other test/merged instead to show off both spellings in one place (particularly because that is attr-noinline.cpp).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, will fix.
@@ -0,0 +1,53 @@ | |||
// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the same here, re merging the tests.
3f834a5
to
4aea776
Compare
7315477
to
c382cbd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You seem to have lost the tests in the latest version of this commit.
Have already added. |
Hi @erichkeane , can this patch be merged? Or if there is anything else I need to do, please let me know. |
Fixes llvm#90941. Add support for ``[[msvc::noinline]]`` attribute, which is actually an alias of ``[[clang::noinline]]``.
Fixes #90941.
Add support for
[[msvc::noinline]]
attribute, which is actually analias of
[[clang::noinline]]
.