[llvm] 3999dca - [Inline] prevent inlining on noprofile mismatch
Nick Desaulniers via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 29 10:43:09 PDT 2021
Author: Nick Desaulniers
Date: 2021-06-29T10:32:03-07:00
New Revision: 3999dcae5e763adceb2c3bc1dbc8f2c005c808ef
URL: https://github.com/llvm/llvm-project/commit/3999dcae5e763adceb2c3bc1dbc8f2c005c808ef
DIFF: https://github.com/llvm/llvm-project/commit/3999dcae5e763adceb2c3bc1dbc8f2c005c808ef.diff
LOG: [Inline] prevent inlining on noprofile mismatch
Similar to
commit bc044a88ee3c ("[Inline] prevent inlining on stack protector mismatch")
The noprofile function attribute is meant to prevent compiler
instrumentation from being inserted into a function. Inlining may defeat
the developer's intent. If the caller and callee don't either BOTH have
the attribute or BOTH lack the attribute, suppress inline substitution.
This matches behavior being proposed in GCC:
https://gcc.gnu.org/pipermail/gcc-patches/2021-June/573511.html
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80223
Add LangRef entry for noprofile fn attr, similar to text added in D93422
and D104944.
Reviewed By: MaskRay, melver, phosek
Differential Revision: https://reviews.llvm.org/D104810
Added:
llvm/test/Transforms/Inline/inline_noprofile.ll
Modified:
llvm/docs/LangRef.rst
llvm/include/llvm/IR/Attributes.td
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5bbcc1477c5d6..848ee2343b5e0 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1656,6 +1656,10 @@ example:
This attribute suppresses lazy symbol binding for the function. This
may make calls to the function faster, at the cost of extra program
startup time if the function is not called during program startup.
+``noprofile``
+ This function attribute prevents instrumentation based profiling, used for
+ coverage or profile based optimization, from being added to a function,
+ even when inlined.
``noredzone``
This attribute indicates that the code generator should not use a
red zone, even if the target-specific ABI normally permits it.
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 177471c69fafe..b3ea4f0b873c7 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -297,6 +297,7 @@ def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
def : CompatRule<"isEqual<SafeStackAttr>">;
def : CompatRule<"isEqual<ShadowCallStackAttr>">;
def : CompatRule<"isEqual<UseSampleProfileAttr>">;
+def : CompatRule<"isEqual<NoProfileAttr>">;
class MergeRule<string F> {
// The name of the function called to merge the attributes of the caller and
diff --git a/llvm/test/Transforms/Inline/inline_noprofile.ll b/llvm/test/Transforms/Inline/inline_noprofile.ll
new file mode 100644
index 0000000000000..dd023b20126fe
--- /dev/null
+++ b/llvm/test/Transforms/Inline/inline_noprofile.ll
@@ -0,0 +1,44 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=inline %s -S -pass-remarks-missed=inline 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-INLINE
+; RUN: opt -passes=always-inline %s -S | FileCheck %s
+
+; Test that we don't inline when caller and callee don't have matching
+; noprofile fn attrs.
+
+; CHECK-INLINE: profile not inlined into profile_caller because it should never be inlined (cost=never): conflicting attributes
+; CHECK-INLINE: noprofile not inlined into noprofile_caller because it should never be inlined (cost=never): conflicting attributes
+
+define i32 @profile() { ret i32 42 }
+define i32 @noprofile() noprofile { ret i32 43 }
+define i32 @profile_aa() alwaysinline { ret i32 44 }
+define i32 @noprofile_aa() noprofile alwaysinline { ret i32 45 }
+
+define i32 @profile_caller() noprofile {
+; CHECK-LABEL: @profile_caller(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @profile()
+; CHECK-NEXT: ret i32 44
+;
+ call i32 @profile()
+ %2 = call i32 @profile_aa()
+ ret i32 %2
+}
+
+define i32 @noprofile_caller() {
+; CHECK-LABEL: @noprofile_caller(
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @noprofile()
+; CHECK-NEXT: ret i32 45
+;
+ call i32 @noprofile()
+ %2 = call i32 @noprofile_aa()
+ ret i32 %2
+}
+
+; Test that we do inline when caller and callee don't have matching
+; noprofile fn attrs, when CallInst is alwaysinline.
+define i32 @aa_callsite() {
+; CHECK-INLINE-LABEL: @aa_callsite(
+; CHECK-INLINE-NEXT: ret i32 43
+;
+ %1 = call i32 @noprofile() alwaysinline
+ ret i32 %1
+}
More information about the llvm-commits
mailing list