[llvm-branch-commits] [llvm] d1a1d7a - [llvm][AArch64] Do not inline a function with different signing scheme. (#80642) (#82743)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 26 15:13:47 PST 2024
Author: Dani
Date: 2024-02-26T15:13:43-08:00
New Revision: d1a1d7afb1fbe7c2cf712a124a2f231ba22103f2
URL: https://github.com/llvm/llvm-project/commit/d1a1d7afb1fbe7c2cf712a124a2f231ba22103f2
DIFF: https://github.com/llvm/llvm-project/commit/d1a1d7afb1fbe7c2cf712a124a2f231ba22103f2.diff
LOG: [llvm][AArch64] Do not inline a function with different signing scheme. (#80642) (#82743)
f 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.
Added:
llvm/test/Transforms/Inline/inline-sign-return-address.ll
Modified:
llvm/include/llvm/IR/Attributes.td
llvm/lib/IR/Attributes.cpp
llvm/utils/TableGen/Attributes.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 864f87f3383891..d22eb76d2292d5 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -339,14 +339,26 @@ def UseSampleProfile : StrBoolAttr<"use-sample-profile">;
def DenormalFPMath : ComplexStrAttr<"denormal-fp-math", [FnAttr]>;
def DenormalFPMathF32 : ComplexStrAttr<"denormal-fp-math-f32", [FnAttr]>;
+// Attribute compatiblity rules are generated to check the attribute of the
+// caller and callee and decide whether inlining should be allowed. CompatRule
+// and child classes are used for the rule generation. CompatRule takes only a
+// compare function which could be templated with the attribute type.
+// CompatRuleStrAttr takes the compare function and the string attribute for
+// checking compatibility for inline substitution.
class CompatRule<string F> {
- // The name of the function called to check the attribute of the caller and
- // callee and decide whether inlining should be allowed. The function's
- // signature must match "bool(const Function&, const Function &)", where the
- // first parameter is the reference to the caller and the second parameter is
- // the reference to the callee. It must return false if the attributes of the
- // caller and callee are incompatible, and true otherwise.
+ // The function's signature must match "bool(const Function&, const
+ // Function&)", where the first parameter is the reference to the caller and
+ // the second parameter is the reference to the callee. It must return false
+ // if the attributes of the caller and callee are incompatible, and true
+ // otherwise.
string CompatFunc = F;
+ string AttrName = "";
+}
+
+class CompatRuleStrAttr<string F, string Attr> : CompatRule<F> {
+ // The checker function is extended with an third argument as the function
+ // attribute string "bool(const Function&, const Function&, const StringRef&)".
+ string AttrName = Attr;
}
def : CompatRule<"isEqual<SanitizeAddressAttr>">;
@@ -359,7 +371,9 @@ def : CompatRule<"isEqual<ShadowCallStackAttr>">;
def : CompatRule<"isEqual<UseSampleProfileAttr>">;
def : CompatRule<"isEqual<NoProfileAttr>">;
def : CompatRule<"checkDenormMode">;
-
+def : CompatRuleStrAttr<"isEqual", "sign-return-address">;
+def : CompatRuleStrAttr<"isEqual", "sign-return-address-key">;
+def : CompatRuleStrAttr<"isEqual", "branch-protection-pauth-lr">;
class MergeRule<string F> {
// The name of the function called to merge the attributes of the caller and
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index fd5160209506f2..19076771ff2eaf 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -2045,6 +2045,11 @@ static bool isEqual(const Function &Caller, const Function &Callee) {
Callee.getFnAttribute(AttrClass::getKind());
}
+static bool isEqual(const Function &Caller, const Function &Callee,
+ const StringRef &AttrName) {
+ return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
+}
+
/// Compute the logical AND of the attributes of the caller and the
/// callee.
///
diff --git a/llvm/test/Transforms/Inline/inline-sign-return-address.ll b/llvm/test/Transforms/Inline/inline-sign-return-address.ll
new file mode 100644
index 00000000000000..c4d85fa671a4f6
--- /dev/null
+++ b/llvm/test/Transforms/Inline/inline-sign-return-address.ll
@@ -0,0 +1,104 @@
+; Check the inliner doesn't inline a function with
diff erent sign return address schemes.
+; RUN: opt < %s -passes=inline -S | FileCheck %s
+
+define internal void @foo_all() #0 {
+ ret void
+}
+
+define internal void @foo_nonleaf() #1 {
+ ret void
+}
+
+define internal void @foo_none() #2 {
+ ret void
+}
+
+define internal void @foo_lr() #3 {
+ ret void
+}
+
+define internal void @foo_bkey() #4 {
+ ret void
+}
+
+define dso_local void @bar_all() #0 {
+; CHECK-LABEL: bar_all
+; CHECK-NOT: call void @foo_all()
+; CHECK-NEXT: call void @foo_nonleaf()
+; CHECK-NEXT: call void @foo_none()
+; CHECK-NEXT: call void @foo_lr()
+; CHECK-NEXT: call void @foo_bkey()
+ call void @foo_all()
+ call void @foo_nonleaf()
+ call void @foo_none()
+ call void @foo_lr()
+ call void @foo_bkey()
+ ret void
+}
+
+define dso_local void @bar_nonleaf() #1 {
+; CHECK-LABEL: bar_nonleaf
+; CHECK-NEXT: call void @foo_all()
+; CHECK-NOT: call void @foo_nonleaf()
+; CHECK-NEXT: call void @foo_none()
+; CHECK-NEXT: call void @foo_lr()
+; CHECK-NEXT: call void @foo_bkey()
+ call void @foo_all()
+ call void @foo_nonleaf()
+ call void @foo_none()
+ call void @foo_lr()
+ call void @foo_bkey()
+ ret void
+}
+
+define dso_local void @bar_none() #2 {
+; CHECK-LABEL: bar_none
+; CHECK-NEXT: call void @foo_all()
+; CHECK-NEXT: call void @foo_nonleaf()
+; CHECK-NOT: call void @foo_none()
+; CHECK-NEXT: call void @foo_lr()
+; CHECK-NEXT: call void @foo_bkey()
+ call void @foo_all()
+ call void @foo_nonleaf()
+ call void @foo_none()
+ call void @foo_lr()
+ call void @foo_bkey()
+ ret void
+}
+
+define dso_local void @bar_lr() #3 {
+; CHECK-LABEL: bar_lr
+; CHECK-NEXT: call void @foo_all()
+; CHECK-NEXT: call void @foo_nonleaf()
+; CHECK-NEXT: call void @foo_none()
+; CHECK-NOT: call void @foo_lr()
+; CHECK-NEXT: call void @foo_bkey()
+ call void @foo_all()
+ call void @foo_nonleaf()
+ call void @foo_none()
+ call void @foo_lr()
+ call void @foo_bkey()
+ ret void
+}
+
+define dso_local void @bar_bkey() #4 {
+; CHECK-LABEL: bar_bkey
+; CHECK-NEXT: call void @foo_all()
+; CHECK-NEXT: call void @foo_nonleaf()
+; CHECK-NEXT: call void @foo_none()
+; CHECK-NEXT: call void @foo_lr()
+; CHECK-NOT: call void @foo_bkey()
+ call void @foo_all()
+ call void @foo_nonleaf()
+ call void @foo_none()
+ call void @foo_lr()
+ call void @foo_bkey()
+ ret void
+}
+
+
+attributes #0 = { "branch-protection-pauth-lr"="false" "sign-return-address"="all" }
+attributes #1 = { "branch-protection-pauth-lr"="false" "sign-return-address"="non-leaf" }
+attributes #2 = { "branch-protection-pauth-lr"="false" "sign-return-address"="none" }
+attributes #3 = { "branch-protection-pauth-lr"="true" "sign-return-address"="non-leaf" }
+attributes #4 = { "branch-protection-pauth-lr"="true" "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }
\ No newline at end of file
diff --git a/llvm/utils/TableGen/Attributes.cpp b/llvm/utils/TableGen/Attributes.cpp
index 474042a3e9a331..db3c4decccb4cf 100644
--- a/llvm/utils/TableGen/Attributes.cpp
+++ b/llvm/utils/TableGen/Attributes.cpp
@@ -87,7 +87,11 @@ void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
for (auto *Rule : CompatRules) {
StringRef FuncName = Rule->getValueAsString("CompatFunc");
- OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
+ OS << " Ret &= " << FuncName << "(Caller, Callee";
+ StringRef AttrName = Rule->getValueAsString("AttrName");
+ if (!AttrName.empty())
+ OS << ", \"" << AttrName << "\"";
+ OS << ");\n";
}
OS << "\n";
More information about the llvm-branch-commits
mailing list