Skip to content

Commit 08201a9

Browse files
[llvm][AArch64] Do not inline a function with different signing scheme.
If the signing scheme is different that maybe the functions assumes different behaviours and dangerous to inline them without analysing them. This should be a rare case.
1 parent 3f4eb61 commit 08201a9

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,21 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
21102110
return InlineResult::failure("incompatible strictfp attributes");
21112111
}
21122112

2113+
// Do not inline function with a different signing scheme.
2114+
if (CalledFunc->getFnAttribute("sign-return-address") !=
2115+
Caller->getFnAttribute("sign-return-address")) {
2116+
return InlineResult::failure("incompatible sign return address attributes");
2117+
}
2118+
if (CalledFunc->getFnAttribute("sign-return-address-key") !=
2119+
Caller->getFnAttribute("sign-return-address-key")) {
2120+
return InlineResult::failure("incompatible signing keys attributes");
2121+
}
2122+
if (CalledFunc->getFnAttribute("branch-protection-pauth-lr") !=
2123+
Caller->getFnAttribute("branch-protection-pauth-lr")) {
2124+
return InlineResult::failure(
2125+
"incompatible sign return address modifier attributes");
2126+
}
2127+
21132128
// GC poses two hazards to inlining, which only occur when the callee has GC:
21142129
// 1. If the caller has no GC, then the callee's GC must be propagated to the
21152130
// caller.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
; Check the inliner doesn't inline a function with different sign return address schemes.
2+
; RUN: opt < %s -passes=inline -S | FileCheck %s
3+
4+
declare void @init(ptr)
5+
6+
define internal i32 @foo_all() #0 {
7+
ret i32 43
8+
}
9+
10+
define internal i32 @foo_nonleaf() #1 {
11+
ret i32 44
12+
}
13+
14+
define internal i32 @foo_none() #2 {
15+
ret i32 42
16+
}
17+
18+
define internal i32 @foo_lr() #3 {
19+
ret i32 45
20+
}
21+
22+
define internal i32 @foo_bkey() #4 {
23+
ret i32 46
24+
}
25+
26+
define dso_local i32 @bar_all() #0 {
27+
; CHECK-LABEL: bar_all
28+
; CHECK-NOT: call i32 @foo_all()
29+
; CHECK: call i32 @foo_nonleaf()
30+
; CHECK: call i32 @foo_none()
31+
; CHECK: call i32 @foo_lr()
32+
; CHECK: call i32 @foo_bkey()
33+
%1 = call i32 @foo_all()
34+
%2 = call i32 @foo_nonleaf()
35+
%3 = call i32 @foo_none()
36+
%4 = call i32 @foo_lr()
37+
%5 = call i32 @foo_bkey()
38+
%6 = add nsw i32 %1, %2
39+
%7 = add nsw i32 %6, %3
40+
%8 = add nsw i32 %7, %4
41+
%9 = add nsw i32 %8, %5
42+
ret i32 %9
43+
}
44+
45+
define dso_local i32 @bar_nonleaf() #1 {
46+
; CHECK-LABEL: bar_nonleaf
47+
; CHECK: call i32 @foo_all()
48+
; CHECK-NOT: call i32 @foo_nonleaf()
49+
; CHECK: call i32 @foo_none()
50+
; CHECK: call i32 @foo_lr()
51+
; CHECK: call i32 @foo_bkey()
52+
%1 = call i32 @foo_all()
53+
%2 = call i32 @foo_nonleaf()
54+
%3 = call i32 @foo_none()
55+
%4 = call i32 @foo_lr()
56+
%5 = call i32 @foo_bkey()
57+
%6 = add nsw i32 %1, %2
58+
%7 = add nsw i32 %6, %3
59+
%8 = add nsw i32 %7, %4
60+
%9 = add nsw i32 %8, %5
61+
ret i32 %9
62+
}
63+
64+
define dso_local i32 @bar_none() #2 {
65+
; CHECK-LABEL: bar_none
66+
; CHECK: call i32 @foo_all()
67+
; CHECK: call i32 @foo_nonleaf()
68+
; CHECK-NOT: call i32 @foo_none()
69+
; CHECK: call i32 @foo_lr()
70+
; CHECK: call i32 @foo_bkey()
71+
%1 = call i32 @foo_all()
72+
%2 = call i32 @foo_nonleaf()
73+
%3 = call i32 @foo_none()
74+
%4 = call i32 @foo_lr()
75+
%5 = call i32 @foo_bkey()
76+
%6 = add nsw i32 %1, %2
77+
%7 = add nsw i32 %6, %3
78+
%8 = add nsw i32 %7, %4
79+
%9 = add nsw i32 %8, %5
80+
ret i32 %9
81+
}
82+
83+
define dso_local i32 @bar_lr() #3 {
84+
; CHECK-LABEL: bar_lr
85+
; CHECK: call i32 @foo_all()
86+
; CHECK: call i32 @foo_nonleaf()
87+
; CHECK: call i32 @foo_none()
88+
; CHECK-NOT: call i32 @foo_lr()
89+
; CHECK: call i32 @foo_bkey()
90+
%1 = call i32 @foo_all()
91+
%2 = call i32 @foo_nonleaf()
92+
%3 = call i32 @foo_none()
93+
%4 = call i32 @foo_lr()
94+
%5 = call i32 @foo_bkey()
95+
%6 = add nsw i32 %1, %2
96+
%7 = add nsw i32 %6, %3
97+
%8 = add nsw i32 %7, %4
98+
%9 = add nsw i32 %8, %5
99+
ret i32 %9
100+
}
101+
102+
define dso_local i32 @bar_bkey() #4 {
103+
; CHECK-LABEL: bar_bkey
104+
; CHECK: call i32 @foo_all()
105+
; CHECK: call i32 @foo_nonleaf()
106+
; CHECK: call i32 @foo_none()
107+
; CHECK: call i32 @foo_lr()
108+
; CHECK-NOT: call i32 @foo_bkey()
109+
%1 = call i32 @foo_all()
110+
%2 = call i32 @foo_nonleaf()
111+
%3 = call i32 @foo_none()
112+
%4 = call i32 @foo_lr()
113+
%5 = call i32 @foo_bkey()
114+
%6 = add nsw i32 %1, %2
115+
%7 = add nsw i32 %6, %3
116+
%8 = add nsw i32 %7, %4
117+
%9 = add nsw i32 %8, %5
118+
ret i32 %9
119+
}
120+
121+
122+
attributes #0 = { "branch-protection-pauth-lr"="false" "sign-return-address"="all" }
123+
attributes #1 = { "branch-protection-pauth-lr"="false" "sign-return-address"="non-leaf" }
124+
attributes #2 = { "branch-protection-pauth-lr"="false" "sign-return-address"="none" }
125+
attributes #3 = { "branch-protection-pauth-lr"="true" "sign-return-address"="non-leaf" }
126+
attributes #4 = { "branch-protection-pauth-lr"="true" "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }

0 commit comments

Comments
 (0)