-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang][ARM][AArch64] Alway emit protection attributes for functions. #82819
Conversation
@llvm/pr-subscribers-llvm-selectiondag @llvm/pr-subscribers-clang Author: Dani (DanielKristofKiss) ChangesBranch protection, sign return address, guarded control stack attributes are The inliner might inline functions with different set of flags as it doesn't consider In case of LTO build the module flags get merged with the Patch is 52.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/82819.diff 12 Files Affected:
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 48e9cec482755c..5eaf34ea581f32 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1369,13 +1369,35 @@ class TargetInfo : public TransferrableTargetInfo,
}
struct BranchProtectionInfo {
- LangOptions::SignReturnAddressScopeKind SignReturnAddr =
- LangOptions::SignReturnAddressScopeKind::None;
- LangOptions::SignReturnAddressKeyKind SignKey =
- LangOptions::SignReturnAddressKeyKind::AKey;
- bool BranchTargetEnforcement = false;
- bool BranchProtectionPAuthLR = false;
- bool GuardedControlStack = false;
+ LangOptions::SignReturnAddressScopeKind SignReturnAddr;
+ LangOptions::SignReturnAddressKeyKind SignKey;
+ bool BranchTargetEnforcement;
+ bool BranchProtectionPAuthLR;
+ bool GuardedControlStack;
+
+ BranchProtectionInfo() = default;
+
+ BranchProtectionInfo(const LangOptions &LangOpts) {
+ SignReturnAddr =
+ LangOpts.hasSignReturnAddress()
+ ? (LangOpts.isSignReturnAddressScopeAll()
+ ? LangOptions::SignReturnAddressScopeKind::All
+ : LangOptions::SignReturnAddressScopeKind::NonLeaf)
+ : LangOptions::SignReturnAddressScopeKind::None;
+ SignKey = LangOpts.isSignReturnAddressWithAKey()
+ ? LangOptions::SignReturnAddressKeyKind::AKey
+ : LangOptions::SignReturnAddressKeyKind::BKey;
+ BranchTargetEnforcement = LangOpts.BranchTargetEnforcement;
+ BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
+ GuardedControlStack = LangOpts.GuardedControlStack;
+ }
+
+ const char *getSignReturnAddrStr() const {
+ static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
+ assert(static_cast<unsigned>(SignReturnAddr) <= 2 &&
+ "Unexpected SignReturnAddressScopeKind");
+ return SignReturnAddrStr[static_cast<int>(SignReturnAddr)];
+ }
};
/// Determine if the Architecture in this TargetInfo supports branch
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 94f8e7be2ee6eb..f0c3513a0cece0 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -109,24 +109,20 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
if (!FD)
return;
- const auto *TA = FD->getAttr<TargetAttr>();
- if (TA == nullptr)
- return;
-
- ParsedTargetAttr Attr =
- CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
- if (Attr.BranchProtection.empty())
- return;
-
- TargetInfo::BranchProtectionInfo BPI;
- StringRef Error;
- (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
- Attr.CPU, BPI, Error);
- assert(Error.empty());
-
+ TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
+
+ if (const auto *TA = FD->getAttr<TargetAttr>()) {
+ ParsedTargetAttr Attr =
+ CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
+ if (!Attr.BranchProtection.empty()) {
+ StringRef Error;
+ (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
+ Attr.CPU, BPI, Error);
+ assert(Error.empty());
+ }
+ }
auto *Fn = cast<llvm::Function>(GV);
- static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
- Fn->addFnAttr("sign-return-address", SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
Fn->addFnAttr("sign-return-address-key",
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index d7d175ff1724f7..b816f6c6677994 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -152,13 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
diag::warn_target_unsupported_branch_protection_attribute)
<< Arch;
} else {
- static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
- assert(static_cast<unsigned>(BPI.SignReturnAddr) <= 2 &&
- "Unexpected SignReturnAddressScopeKind");
- Fn->addFnAttr(
- "sign-return-address",
- SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
-
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
Fn->addFnAttr("branch-target-enforcement",
BPI.BranchTargetEnforcement ? "true" : "false");
}
@@ -173,6 +167,13 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
diag::warn_target_unsupported_branch_protection_attribute)
<< Attr.CPU;
}
+ } else if (CGM.getTarget().isBranchProtectionSupportedArch(
+ CGM.getTarget().getTargetOpts().CPU)) {
+ TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
+
+ Fn->addFnAttr("branch-target-enforcement",
+ BPI.BranchTargetEnforcement ? "true" : "false");
}
const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
diff --git a/clang/test/CodeGen/aarch64-cpu-supports-target.c b/clang/test/CodeGen/aarch64-cpu-supports-target.c
index e023944b24e53a..c0dd79701409f6 100644
--- a/clang/test/CodeGen/aarch64-cpu-supports-target.c
+++ b/clang/test/CodeGen/aarch64-cpu-supports-target.c
@@ -47,6 +47,6 @@ int test_versions() {
else
return code();
}
-// CHECK: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-// CHECK: attributes #1 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon" }
-// CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
+// CHECK: attributes #0 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" }
+// CHECK: attributes #1 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+neon" }
+// CHECK: attributes #2 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c
index 8bc54b1a56c38c..c7821e9dfc1214 100644
--- a/clang/test/CodeGen/aarch64-sign-return-address.c
+++ b/clang/test/CodeGen/aarch64-sign-return-address.c
@@ -7,15 +7,33 @@
// RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=B-KEY
// RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK-LTO
+
// REQUIRES: aarch64-registered-target
-// Check there are no branch protection function attributes
+// Branch protection function attributes are always expected.
// CHECK-LABEL: @foo() #[[#ATTR:]]
+// CHECK-LTO-LABEL: @foo() #[[#ATTR:]]
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// CHECK: attributes #[[#ATTR]] = { {{.*}} "branch-protection-pauth-lr"{{.*}}"branch-target-enforcement"{{.*}}"guarded-control-stack"{{.*}}"sign-return-address"
+// CHECK-LTO: attributes #[[#ATTR]] = { {{.*}} "branch-protection-pauth-lr"{{.*}}"branch-target-enforcement"{{.*}}"guarded-control-stack"{{.*}}"sign-return-address"
// Check module attributes
diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp b/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
index fdd2de11365dd4..2ad0855399173a 100644
--- a/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
+++ b/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
@@ -278,18 +278,18 @@ int test_variadic_template() __arm_inout("za") {
preserves_za_decl);
}
-// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[NORMAL_DECL]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_ENABLED_DECL]] = { "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_new_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[NORMAL_DEF]] = { mustprogress noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind "aarch64_pstate_sm_enabled" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[NORMAL_DECL]] = { {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_ENABLED_DECL]] = { "aarch64_pstate_sm_enabled" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_preserves_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_new_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[NORMAL_DEF]] = { mustprogress noinline nounwind {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
// CHECK: attributes #[[SM_ENABLED_CALL]] = { "aarch64_pstate_sm_enabled" }
// CHECK: attributes #[[SM_COMPATIBLE_CALL]] = { "aarch64_pstate_sm_compatible" }
// CHECK: attributes #[[SM_BODY_CALL]] = { "aarch64_pstate_sm_body" }
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-2.c b/clang/test/CodeGen/arm-branch-protection-attr-2.c
index 1f3c00873043e8..7b3b7c415d25cb 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-2.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-2.c
@@ -5,13 +5,11 @@
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=PART
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
-// Check there are no branch protection function attributes
+// Check there is branch protection function attributes
// CHECK-LABEL: @foo() #[[#ATTR:]]
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// CHECK: attributes #[[#ATTR]] = { {{.*}} {{.*}} "branch-target-enforcement"{{.*}}"sign-return-address"
// Check module attributes
diff --git a/clang/test/CodeGen/attr-target-clones-aarch64.c b/clang/test/CodeGen/attr-target-clones-aarch64.c
index 5ea3f4a9b0b112..34df8309142411 100644
--- a/clang/test/CodeGen/attr-target-clones-aarch64.c
+++ b/clang/test/CodeGen/attr-target-clones-aarch64.c
@@ -414,23 +414,23 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
// CHECK-NOFMV-NEXT: ret i32 [[ADD5]]
//
//.
-// CHECK: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon" }
-// CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2" }
-// CHECK: attributes #[[ATTR2:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-// CHECK: attributes #[[ATTR3:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sha2" }
-// CHECK: attributes #[[ATTR4:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+mte,+neon,+sha2" }
-// CHECK: attributes #[[ATTR5:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" }
-// CHECK: attributes #[[ATTR6:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+dotprod,+fp-armv8,+neon" }
-// CHECK: attributes #[[ATTR7:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rand" }
-// CHECK: attributes #[[ATTR8:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+predres,+rcpc" }
-// CHECK: attributes #[[ATTR9:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+wfxt" }
-// CHECK: attributes #[[ATTR10:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" }
-// CHECK: attributes #[[ATTR11:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+complxnum,+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-bitperm" }
-// CHECK: attributes #[[ATTR12:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti" }
-// CHECK: attributes #[[ATTR13:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sb,+sve" }
+// CHECK: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon" }
+// CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2" }
+// CHECK: attributes #[[ATTR2:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="non...
[truncated]
|
@llvm/pr-subscribers-clang-codegen Author: Dani (DanielKristofKiss) ChangesBranch protection, sign return address, guarded control stack attributes are The inliner might inline functions with different set of flags as it doesn't consider In case of LTO build the module flags get merged with the Patch is 52.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/82819.diff 12 Files Affected:
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 48e9cec482755c..5eaf34ea581f32 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1369,13 +1369,35 @@ class TargetInfo : public TransferrableTargetInfo,
}
struct BranchProtectionInfo {
- LangOptions::SignReturnAddressScopeKind SignReturnAddr =
- LangOptions::SignReturnAddressScopeKind::None;
- LangOptions::SignReturnAddressKeyKind SignKey =
- LangOptions::SignReturnAddressKeyKind::AKey;
- bool BranchTargetEnforcement = false;
- bool BranchProtectionPAuthLR = false;
- bool GuardedControlStack = false;
+ LangOptions::SignReturnAddressScopeKind SignReturnAddr;
+ LangOptions::SignReturnAddressKeyKind SignKey;
+ bool BranchTargetEnforcement;
+ bool BranchProtectionPAuthLR;
+ bool GuardedControlStack;
+
+ BranchProtectionInfo() = default;
+
+ BranchProtectionInfo(const LangOptions &LangOpts) {
+ SignReturnAddr =
+ LangOpts.hasSignReturnAddress()
+ ? (LangOpts.isSignReturnAddressScopeAll()
+ ? LangOptions::SignReturnAddressScopeKind::All
+ : LangOptions::SignReturnAddressScopeKind::NonLeaf)
+ : LangOptions::SignReturnAddressScopeKind::None;
+ SignKey = LangOpts.isSignReturnAddressWithAKey()
+ ? LangOptions::SignReturnAddressKeyKind::AKey
+ : LangOptions::SignReturnAddressKeyKind::BKey;
+ BranchTargetEnforcement = LangOpts.BranchTargetEnforcement;
+ BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
+ GuardedControlStack = LangOpts.GuardedControlStack;
+ }
+
+ const char *getSignReturnAddrStr() const {
+ static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
+ assert(static_cast<unsigned>(SignReturnAddr) <= 2 &&
+ "Unexpected SignReturnAddressScopeKind");
+ return SignReturnAddrStr[static_cast<int>(SignReturnAddr)];
+ }
};
/// Determine if the Architecture in this TargetInfo supports branch
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index 94f8e7be2ee6eb..f0c3513a0cece0 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -109,24 +109,20 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
if (!FD)
return;
- const auto *TA = FD->getAttr<TargetAttr>();
- if (TA == nullptr)
- return;
-
- ParsedTargetAttr Attr =
- CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
- if (Attr.BranchProtection.empty())
- return;
-
- TargetInfo::BranchProtectionInfo BPI;
- StringRef Error;
- (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
- Attr.CPU, BPI, Error);
- assert(Error.empty());
-
+ TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
+
+ if (const auto *TA = FD->getAttr<TargetAttr>()) {
+ ParsedTargetAttr Attr =
+ CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
+ if (!Attr.BranchProtection.empty()) {
+ StringRef Error;
+ (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
+ Attr.CPU, BPI, Error);
+ assert(Error.empty());
+ }
+ }
auto *Fn = cast<llvm::Function>(GV);
- static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
- Fn->addFnAttr("sign-return-address", SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
Fn->addFnAttr("sign-return-address-key",
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index d7d175ff1724f7..b816f6c6677994 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -152,13 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
diag::warn_target_unsupported_branch_protection_attribute)
<< Arch;
} else {
- static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
- assert(static_cast<unsigned>(BPI.SignReturnAddr) <= 2 &&
- "Unexpected SignReturnAddressScopeKind");
- Fn->addFnAttr(
- "sign-return-address",
- SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]);
-
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
Fn->addFnAttr("branch-target-enforcement",
BPI.BranchTargetEnforcement ? "true" : "false");
}
@@ -173,6 +167,13 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
diag::warn_target_unsupported_branch_protection_attribute)
<< Attr.CPU;
}
+ } else if (CGM.getTarget().isBranchProtectionSupportedArch(
+ CGM.getTarget().getTargetOpts().CPU)) {
+ TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
+ Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
+
+ Fn->addFnAttr("branch-target-enforcement",
+ BPI.BranchTargetEnforcement ? "true" : "false");
}
const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
diff --git a/clang/test/CodeGen/aarch64-cpu-supports-target.c b/clang/test/CodeGen/aarch64-cpu-supports-target.c
index e023944b24e53a..c0dd79701409f6 100644
--- a/clang/test/CodeGen/aarch64-cpu-supports-target.c
+++ b/clang/test/CodeGen/aarch64-cpu-supports-target.c
@@ -47,6 +47,6 @@ int test_versions() {
else
return code();
}
-// CHECK: attributes #0 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-// CHECK: attributes #1 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+neon" }
-// CHECK: attributes #2 = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
+// CHECK: attributes #0 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" }
+// CHECK: attributes #1 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+neon" }
+// CHECK: attributes #2 = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c
index 8bc54b1a56c38c..c7821e9dfc1214 100644
--- a/clang/test/CodeGen/aarch64-sign-return-address.c
+++ b/clang/test/CodeGen/aarch64-sign-return-address.c
@@ -7,15 +7,33 @@
// RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=B-KEY
// RUN: %clang -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=none %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK-LTO
+// RUN: %clang -flto=thin -target aarch64-none-elf -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK-LTO
+
// REQUIRES: aarch64-registered-target
-// Check there are no branch protection function attributes
+// Branch protection function attributes are always expected.
// CHECK-LABEL: @foo() #[[#ATTR:]]
+// CHECK-LTO-LABEL: @foo() #[[#ATTR:]]
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// CHECK: attributes #[[#ATTR]] = { {{.*}} "branch-protection-pauth-lr"{{.*}}"branch-target-enforcement"{{.*}}"guarded-control-stack"{{.*}}"sign-return-address"
+// CHECK-LTO: attributes #[[#ATTR]] = { {{.*}} "branch-protection-pauth-lr"{{.*}}"branch-target-enforcement"{{.*}}"guarded-control-stack"{{.*}}"sign-return-address"
// Check module attributes
diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp b/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
index fdd2de11365dd4..2ad0855399173a 100644
--- a/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
+++ b/clang/test/CodeGen/aarch64-sme-intrinsics/aarch64-sme-attrs.cpp
@@ -278,18 +278,18 @@ int test_variadic_template() __arm_inout("za") {
preserves_za_decl);
}
-// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[NORMAL_DECL]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_ENABLED_DECL]] = { "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_new_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
-// CHECK: attributes #[[NORMAL_DEF]] = { mustprogress noinline nounwind "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind "aarch64_pstate_sm_enabled" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[NORMAL_DECL]] = { {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_ENABLED_DECL]] = { "aarch64_pstate_sm_enabled" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_PRESERVED_DECL]] = { "aarch64_preserves_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[ZA_NEW]] = { mustprogress noinline nounwind "aarch64_new_za" {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
+// CHECK: attributes #[[NORMAL_DEF]] = { mustprogress noinline nounwind {{.*}} "no-trapping-math"="true" {{.*}} "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" }
// CHECK: attributes #[[SM_ENABLED_CALL]] = { "aarch64_pstate_sm_enabled" }
// CHECK: attributes #[[SM_COMPATIBLE_CALL]] = { "aarch64_pstate_sm_compatible" }
// CHECK: attributes #[[SM_BODY_CALL]] = { "aarch64_pstate_sm_body" }
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-2.c b/clang/test/CodeGen/arm-branch-protection-attr-2.c
index 1f3c00873043e8..7b3b7c415d25cb 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-2.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-2.c
@@ -5,13 +5,11 @@
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | FileCheck %s --check-prefix=CHECK --check-prefix=PART
// RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main -S -emit-llvm -o - -mbranch-protection=bti %s | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
-// Check there are no branch protection function attributes
+// Check there is branch protection function attributes
// CHECK-LABEL: @foo() #[[#ATTR:]]
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
-// CHECK-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// CHECK: attributes #[[#ATTR]] = { {{.*}} {{.*}} "branch-target-enforcement"{{.*}}"sign-return-address"
// Check module attributes
diff --git a/clang/test/CodeGen/attr-target-clones-aarch64.c b/clang/test/CodeGen/attr-target-clones-aarch64.c
index 5ea3f4a9b0b112..34df8309142411 100644
--- a/clang/test/CodeGen/attr-target-clones-aarch64.c
+++ b/clang/test/CodeGen/attr-target-clones-aarch64.c
@@ -414,23 +414,23 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default"))
// CHECK-NOFMV-NEXT: ret i32 [[ADD5]]
//
//.
-// CHECK: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon" }
-// CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2" }
-// CHECK: attributes #[[ATTR2:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
-// CHECK: attributes #[[ATTR3:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+sha2" }
-// CHECK: attributes #[[ATTR4:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+mte,+neon,+sha2" }
-// CHECK: attributes #[[ATTR5:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon" }
-// CHECK: attributes #[[ATTR6:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+crc,+dotprod,+fp-armv8,+neon" }
-// CHECK: attributes #[[ATTR7:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+neon,+rand" }
-// CHECK: attributes #[[ATTR8:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+predres,+rcpc" }
-// CHECK: attributes #[[ATTR9:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-aes,+wfxt" }
-// CHECK: attributes #[[ATTR10:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon" }
-// CHECK: attributes #[[ATTR11:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+complxnum,+fp-armv8,+fullfp16,+neon,+sve,+sve2,+sve2-bitperm" }
-// CHECK: attributes #[[ATTR12:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bti" }
-// CHECK: attributes #[[ATTR13:[0-9]+]] = { noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sb,+sve" }
+// CHECK: attributes #[[ATTR0:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+lse,+neon" }
+// CHECK: attributes #[[ATTR1:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="none" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve,+sve2" }
+// CHECK: attributes #[[ATTR2:[0-9]+]] = { noinline nounwind optnone "branch-protection-pauth-lr"="false" "branch-target-enforcement"="false" "guarded-control-stack"="false" "no-trapping-math"="true" "sign-return-address"="non...
[truncated]
|
RFC as I'm not sure the right approach is to emit that many attribute always. |
// CHECK-LABEL: @_ZN7MyClassIfsE7foo_tmlEv( | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 | ||
// CHECK-NEXT: store ptr [[THIS:%.*]], ptr [[THIS_ADDR]], align 8 | ||
// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 | ||
// CHECK-NEXT: ret i32 3 | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded changes?
//. | ||
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} | ||
// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} | ||
//. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded //.
here and elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used 'utils/update_cc_test_checks.py` to updated these tests.
f455e20
to
eef710d
Compare
This handles the synthetic function in clang: #83277 |
struct BranchProtectionInfo { | ||
LangOptions::SignReturnAddressScopeKind SignReturnAddr = | ||
LangOptions::SignReturnAddressScopeKind::None; | ||
LangOptions::SignReturnAddressKeyKind SignKey = | ||
LangOptions::SignReturnAddressKeyKind::AKey; | ||
bool BranchTargetEnforcement = false; | ||
bool BranchProtectionPAuthLR = false; | ||
bool GuardedControlStack = false; | ||
LangOptions::SignReturnAddressScopeKind SignReturnAddr; | ||
LangOptions::SignReturnAddressKeyKind SignKey; | ||
bool BranchTargetEnforcement; | ||
bool BranchProtectionPAuthLR; | ||
bool GuardedControlStack; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider if it's feasible making this a class and having the constructors and methods be public.
d27a156
to
9e844b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still has "foo"="true" style function attributes, which are problematic. Is the plan to change that?
Can be changed to just "foo" just makes the function/module attribute importer more complicated to handle the old IR. |
9e844b9
to
5973486
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'm not sure I understand the goal here. For return-address signing, each function can make its own choice about whether to sign; the function that's doing the signing is the same function that does the auth, so it doesn't directly impact any other function. For branch target enforcement, though, everything needs to agree that branch targets are supposed to be enforced, or else the process crashes. So there's no point to modifying whether it's enabled for a single function. |
You are right in case of user space application but in some other use cases it is desired to keep the function properties because the executable is loaded differently (higher EL's). |
Hmm... so basically, the program is partitioned into parts with branch enforcement disabled, and parts with branch enforcement enabled, and there's some defined transition between the two? So in this case, the metadata is nonsense, and you want to ignore it. I guess that makes sense. This means missed optimizations for the case where the program can't mess with the BTI-enabled state, though: if you build a library with BTI enabled and link it into a program with BTI disabled, LTO becomes severely restricted. I guess that might be rare enough it doesn't matter. |
Branch protection, sign return address, guarded control stack flags are only emitted as module flags if not specified per function. The inliner might inline functions with different set of flags as it doesn't see the flags. In case of LTO build the module flags get merged with the `min` rule which means if one of the modules is not build with PAC/BTI then the features will be turned off on all functions due to the functions takes the branch-protection and sign-return-address features from the module flags. The sign-return-address is function level option therefore it is expected functions from files that are compiled with -mbranch-protection=pac-ret to be protected but in LTO case this might not happen. This patch adds the flags to functions in case of an LTO build therefore they don't need to rely on the module flag.
f459bf1
to
df64bb1
Compare
I'm planning to merge this and subsequent patches this week, please let me know if you any more concerns. Thanks! |
Module flags represent the original intention. Depends on #82819
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/1938 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/153/builds/2482 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/60/builds/2096 Here is the relevant piece of the build log for the reference:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/1993 Here is the relevant piece of the build log for the reference:
|
In addition to the test failures, this apparently also breaks building lldb on windows and Mac: Please check if that's something real or if my bots are being silly before relanding. |
…#82819) So far branch protection, sign return address, guarded control stack attributes are only emitted as module flags to indicate the functions need to be generated with those features. The problem is in case of an LTO build the module flags are merged with the `min` rule which means if one of the module is not build with sign return address then the features will be turned off for all functions. Due to the functions take the branch-protection and sign-return-address features from the module flags. The sign-return-address is function level option therefore it is expected functions from files that is compiled with -mbranch-protection=pac-ret to be protected. The inliner might inline functions with different set of flags as it doesn't consider the module flags. This patch adds the attributes to all functions and drops the checking of the module flags for the code generation. Module flag is still used for generating the ELF markers. Also drops the "true"/"false" values from the branch-protection-enforcement, branch-protection-pauth-lr, guarded-control-stack attributes as presence of the attribute means it is on absence means off and no other option. Releand with test fixes.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/1714 Here is the relevant piece of the build log for the reference:
|
Module flags represent the original intention. Depends on #82819 Reland as it was but reland needed as dependent patch relanded.
#82819 made the lookup here ambiguous.
#include "llvm/IR/DerivedTypes.h" | ||
#include "llvm/IR/Function.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please move the implementation out of line, so that these headers don't get included here? This has a significant impact on clang build times.
(Or possibly this shouldn't be in Basic/TargetInfo at all? I'm not familiar with clang layering, but this sounds more like CodeGen/TargetInfo than Basic/TargetInfo to me.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed here #98329
It looks like there's still a failure related to this patch on current main AFAICT (MSAN finds a use of uninitialized value): https://lab.llvm.org/buildbot/#/builders/169/builds/852/steps/12/logs/stdio
|
Thanks, already noticed and addressed here: #98307 |
…llvm#82819) So far branch protection, sign return address, guarded control stack attributes are only emitted as module flags to indicate the functions need to be generated with those features. The problem is in case of an LTO build the module flags are merged with the `min` rule which means if one of the module is not build with sign return address then the features will be turned off for all functions. Due to the functions take the branch-protection and sign-return-address features from the module flags. The sign-return-address is function level option therefore it is expected functions from files that is compiled with -mbranch-protection=pac-ret to be protected. The inliner might inline functions with different set of flags as it doesn't consider the module flags. This patch adds the attributes to all functions and drops the checking of the module flags for the code generation. Module flag is still used for generating the ELF markers. Also drops the "true"/"false" values from the branch-protection-enforcement, branch-protection-pauth-lr, guarded-control-stack attributes as presence of the attribute means it is on absence means off and no other option.
Module flags represent the original intention. Depends on llvm#82819
…llvm#82819) So far branch protection, sign return address, guarded control stack attributes are only emitted as module flags to indicate the functions need to be generated with those features. The problem is in case of an LTO build the module flags are merged with the `min` rule which means if one of the module is not build with sign return address then the features will be turned off for all functions. Due to the functions take the branch-protection and sign-return-address features from the module flags. The sign-return-address is function level option therefore it is expected functions from files that is compiled with -mbranch-protection=pac-ret to be protected. The inliner might inline functions with different set of flags as it doesn't consider the module flags. This patch adds the attributes to all functions and drops the checking of the module flags for the code generation. Module flag is still used for generating the ELF markers. Also drops the "true"/"false" values from the branch-protection-enforcement, branch-protection-pauth-lr, guarded-control-stack attributes as presence of the attribute means it is on absence means off and no other option. Releand with test fixes.
Module flags represent the original intention. Depends on llvm#82819 Reland as it was but reland needed as dependent patch relanded.
llvm#82819 made the lookup here ambiguous.
So far branch protection, sign return address, guarded control stack attributes are
only emitted as module flags to indicate the functions need to be generated with
those features.
The problem is in case of an LTO build the module flags are merged with the
min
rule which means if one of the module is not build with sign return address then the features
will be turned off for all functions. Due to the functions take the branch-protection and
sign-return-address features from the module flags. The sign-return-address is
function level option therefore it is expected functions from files that is
compiled with -mbranch-protection=pac-ret to be protected.
The inliner might inline functions with different set of flags as it doesn't consider
the module flags.
This patch adds the attributes to all functions and drops the checking of the module flags
for the code generation.
Module flag is still used for generating the ELF markers.
Also drops the "true"/"false" values from the branch-protection-enforcement,
branch-protection-pauth-lr, guarded-control-stack attributes as presence of the
attribute means it is on absence means off and no other option.