[clang] [Arm][AArch64][Clang] Respect function's branch protection attributes. (PR #101978)
Daniel Kiss via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 9 05:39:34 PDT 2024
https://github.com/DanielKristofKiss updated https://github.com/llvm/llvm-project/pull/101978
>From 4afadb9122c982c63f2b067661548a2c063590a5 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Mon, 5 Aug 2024 13:01:06 +0200
Subject: [PATCH 1/2] [Arm][AArch64][Clang] Respect function's branch
protection attributes.
Default attributes assigned to all functions according to the command line
parameters. Some functions might have their own attributes and we need to set
or remove attributes accordingly.
---
clang/lib/CodeGen/TargetInfo.cpp | 25 ++++++++++++++++---
clang/lib/CodeGen/TargetInfo.h | 3 +++
.../CodeGen/aarch64-branch-protection-attr.c | 13 +++++++++-
.../CodeGen/arm-branch-protection-attr-1.c | 6 +++++
4 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 38faa50cf19cf2..ec05db0ecfac58 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -209,9 +209,28 @@ llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
void TargetCodeGenInfo::setBranchProtectionFnAttributes(
const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) {
- llvm::AttrBuilder FuncAttrs(F.getContext());
- setBranchProtectionFnAttributes(BPI, FuncAttrs);
- F.addFnAttrs(FuncAttrs);
+ if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
+ F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
+ F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr());
+ } else {
+ if (F.hasFnAttribute("sign-return-address"))
+ F.removeFnAttr("sign-return-address");
+ if (F.hasFnAttribute("sign-return-address-key"))
+ F.removeFnAttr("sign-return-address-key");
+ }
+
+ auto AddRemoveAttributeAsSet = [&](bool Set, const StringRef &ModAttr) {
+ if (Set)
+ F.addFnAttr(ModAttr);
+ else if (F.hasFnAttribute(ModAttr))
+ F.removeFnAttr(ModAttr);
+ };
+
+ AddRemoveAttributeAsSet(BPI.BranchTargetEnforcement,
+ "branch-target-enforcement");
+ AddRemoveAttributeAsSet(BPI.BranchProtectionPAuthLR,
+ "branch-protection-pauth-lr");
+ AddRemoveAttributeAsSet(BPI.GuardedControlStack, "guarded-control-stack");
}
void TargetCodeGenInfo::setBranchProtectionFnAttributes(
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 8f17c053f4783f..639717bd9580d0 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -418,10 +418,13 @@ class TargetCodeGenInfo {
return nullptr;
}
+ // Set the Branch Protection Attributes of the Function accordingly to the
+ // BPI. Might remove attributes if contradicts with the pass request.
static void
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
llvm::Function &F);
+ // Add the Branch Protection Attributes of the FuncAttrs.
static void
setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
llvm::AttrBuilder &FuncAttrs);
diff --git a/clang/test/CodeGen/aarch64-branch-protection-attr.c b/clang/test/CodeGen/aarch64-branch-protection-attr.c
index e7ae7fb1570c95..c66bce1bee6d36 100644
--- a/clang/test/CodeGen/aarch64-branch-protection-attr.c
+++ b/clang/test/CodeGen/aarch64-branch-protection-attr.c
@@ -1,6 +1,18 @@
// REQUIRES: aarch64-registered-target
// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - \
// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mbranch-target-enforce %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mguarded-control-stack %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -msign-return-address=non-leaf -msign-return-address-key=a_key %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -msign-return-address=all -msign-return-address-key=b_key %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mbranch-protection-pauth-lr -msign-return-address=all -msign-return-address-key=a_key %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple aarch64 -emit-llvm -target-cpu generic -target-feature +v8.5a -mguarded-control-stack -mbranch-target-enforce -mbranch-protection-pauth-lr -msign-return-address=all -msign-return-address-key=a_key %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
__attribute__ ((target("branch-protection=none")))
void none() {}
@@ -83,7 +95,6 @@ void gcs() {}
// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}} "branch-target-enforcement" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
-
// CHECK-DAG: attributes #[[#PAUTHLR]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-1.c b/clang/test/CodeGen/arm-branch-protection-attr-1.c
index dd38cf347f04fc..5ca6a1a4d13b40 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-1.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-1.c
@@ -1,6 +1,12 @@
// REQUIRES: arm-registered-target
// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -emit-llvm %s -o - \
// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -msign-return-address=all -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all -emit-llvm %s -o - \
+// RUN: | FileCheck %s --check-prefix=CHECK
__attribute__((target("branch-protection=none"))) void none() {}
// CHECK: define{{.*}} void @none() #[[#NONE:]]
>From 01fad084489d70d5903c5af0d322b1f318c2966a Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 9 Aug 2024 14:39:12 +0200
Subject: [PATCH 2/2] Address review comments
---
clang/lib/CodeGen/CGCall.cpp | 2 +-
clang/lib/CodeGen/TargetInfo.cpp | 7 ++++++-
clang/lib/CodeGen/TargetInfo.h | 4 ++--
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index f333b20d86ad7f..ee24dd48fd9f84 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2010,7 +2010,7 @@ static void getTrivialDefaultFunctionAttributes(
}
TargetInfo::BranchProtectionInfo BPI(LangOpts);
- TargetCodeGenInfo::setBranchProtectionFnAttributes(BPI, FuncAttrs);
+ TargetCodeGenInfo::initBranchProtectionFnAttributes(BPI, FuncAttrs);
}
/// Merges `target-features` from \TargetOpts and \F, and sets the result in
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index ec05db0ecfac58..64a9a5554caf72 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -209,6 +209,9 @@ llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
void TargetCodeGenInfo::setBranchProtectionFnAttributes(
const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) {
+ // Called on already created and initialized function where attributes already
+ // set from command line attributes but some might need to be removed as the
+ // actual BPI is different.
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr());
@@ -233,8 +236,10 @@ void TargetCodeGenInfo::setBranchProtectionFnAttributes(
AddRemoveAttributeAsSet(BPI.GuardedControlStack, "guarded-control-stack");
}
-void TargetCodeGenInfo::setBranchProtectionFnAttributes(
+void TargetCodeGenInfo::initBranchProtectionFnAttributes(
const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs) {
+ // Only used for initializing attributes in the AttrBuilder, which will not
+ // contain any of these attributes so no need to remove anything.
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
FuncAttrs.addAttribute("sign-return-address", BPI.getSignReturnAddrStr());
FuncAttrs.addAttribute("sign-return-address-key", BPI.getSignKeyStr());
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 156e624d494da3..0244ca006d498b 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -431,8 +431,8 @@ class TargetCodeGenInfo {
// Add the Branch Protection Attributes of the FuncAttrs.
static void
- setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
- llvm::AttrBuilder &FuncAttrs);
+ initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI,
+ llvm::AttrBuilder &FuncAttrs);
protected:
static std::string qualifyWindowsLibrary(StringRef Lib);
More information about the cfe-commits
mailing list