Skip to content

Commit 3999dca

Browse files
[Inline] prevent inlining on noprofile mismatch
Similar to commit bc044a8 ("[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
1 parent aaba371 commit 3999dca

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

llvm/docs/LangRef.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,10 @@ example:
16561656
This attribute suppresses lazy symbol binding for the function. This
16571657
may make calls to the function faster, at the cost of extra program
16581658
startup time if the function is not called during program startup.
1659+
``noprofile``
1660+
This function attribute prevents instrumentation based profiling, used for
1661+
coverage or profile based optimization, from being added to a function,
1662+
even when inlined.
16591663
``noredzone``
16601664
This attribute indicates that the code generator should not use a
16611665
red zone, even if the target-specific ABI normally permits it.

llvm/include/llvm/IR/Attributes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
297297
def : CompatRule<"isEqual<SafeStackAttr>">;
298298
def : CompatRule<"isEqual<ShadowCallStackAttr>">;
299299
def : CompatRule<"isEqual<UseSampleProfileAttr>">;
300+
def : CompatRule<"isEqual<NoProfileAttr>">;
300301

301302
class MergeRule<string F> {
302303
// The name of the function called to merge the attributes of the caller and
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt -passes=inline %s -S -pass-remarks-missed=inline 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-INLINE
3+
; RUN: opt -passes=always-inline %s -S | FileCheck %s
4+
5+
; Test that we don't inline when caller and callee don't have matching
6+
; noprofile fn attrs.
7+
8+
; CHECK-INLINE: profile not inlined into profile_caller because it should never be inlined (cost=never): conflicting attributes
9+
; CHECK-INLINE: noprofile not inlined into noprofile_caller because it should never be inlined (cost=never): conflicting attributes
10+
11+
define i32 @profile() { ret i32 42 }
12+
define i32 @noprofile() noprofile { ret i32 43 }
13+
define i32 @profile_aa() alwaysinline { ret i32 44 }
14+
define i32 @noprofile_aa() noprofile alwaysinline { ret i32 45 }
15+
16+
define i32 @profile_caller() noprofile {
17+
; CHECK-LABEL: @profile_caller(
18+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @profile()
19+
; CHECK-NEXT: ret i32 44
20+
;
21+
call i32 @profile()
22+
%2 = call i32 @profile_aa()
23+
ret i32 %2
24+
}
25+
26+
define i32 @noprofile_caller() {
27+
; CHECK-LABEL: @noprofile_caller(
28+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @noprofile()
29+
; CHECK-NEXT: ret i32 45
30+
;
31+
call i32 @noprofile()
32+
%2 = call i32 @noprofile_aa()
33+
ret i32 %2
34+
}
35+
36+
; Test that we do inline when caller and callee don't have matching
37+
; noprofile fn attrs, when CallInst is alwaysinline.
38+
define i32 @aa_callsite() {
39+
; CHECK-INLINE-LABEL: @aa_callsite(
40+
; CHECK-INLINE-NEXT: ret i32 43
41+
;
42+
%1 = call i32 @noprofile() alwaysinline
43+
ret i32 %1
44+
}

0 commit comments

Comments
 (0)