[clang] [llvm] [Clang][ARM][AArch64] Alway emit protection attributes for functions. (PR #82819)

Daniel Kiss via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 27 07:56:53 PDT 2024


https://github.com/DanielKristofKiss updated https://github.com/llvm/llvm-project/pull/82819

>From df64bb1a12ea2b2a89151fa034a16cd641129347 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Mon, 22 Jan 2024 11:33:15 +0100
Subject: [PATCH] Emit attributes for functions always.

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.
---
 clang/include/clang/Basic/TargetInfo.h        | 44 +++++++++++++++++--
 clang/lib/CodeGen/Targets/AArch64.cpp         | 43 ++++++------------
 clang/lib/CodeGen/Targets/ARM.cpp             |  8 ++--
 .../CodeGen/aarch64-branch-protection-attr.c  | 26 +++++------
 .../CodeGen/aarch64-sign-return-address.c     | 12 +++--
 .../CodeGen/arm-branch-protection-attr-1.c    | 12 ++---
 .../CodeGen/arm-branch-protection-attr-2.c    | 13 ++++--
 .../test/Frontend/arm-branch-protection-lto.c | 24 ++++++++++
 .../SelectionDAG/SelectionDAGBuilder.cpp      | 12 +----
 llvm/lib/IR/Verifier.cpp                      | 20 ++++++++-
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |  6 +--
 .../AArch64/AArch64MachineFunctionInfo.cpp    | 37 ++--------------
 .../lib/Target/ARM/ARMMachineFunctionInfo.cpp | 22 +---------
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    |  6 ++-
 ...ranch-target-enforcement-indirect-calls.ll | 18 ++++----
 .../CodeGen/AArch64/bti-branch-relaxation.ll  |  2 +-
 llvm/test/CodeGen/AArch64/kcfi-bti.ll         |  7 +--
 ...machine-outliner-2fixup-blr-terminator.mir |  2 +-
 .../CodeGen/AArch64/machine-outliner-bti.mir  |  2 +-
 .../AArch64/machine-outliner-outline-bti.ll   |  4 +-
 .../AArch64/note-gnu-property-pac-bti-0.ll    |  2 +-
 .../AArch64/note-gnu-property-pac-bti-4.ll    |  4 +-
 .../AArch64/pacbti-llvm-generated-funcs-1.ll  |  4 +-
 .../AArch64/pacbti-llvm-generated-funcs-2.ll  | 10 ++---
 .../CodeGen/AArch64/pacbti-module-attrs.ll    | 12 ++---
 .../AArch64/patchable-function-entry-bti.ll   | 10 ++---
 .../CodeGen/AArch64/setjmp-bti-outliner.ll    | 15 +++----
 llvm/test/CodeGen/AArch64/setjmp-bti.ll       |  6 +--
 .../AArch64/sign-return-address-pauth-lr.ll   | 36 +++++++--------
 .../CodeGen/AArch64/sign-return-address.ll    |  8 ++--
 llvm/test/CodeGen/AArch64/wineh-bti.ll        |  7 +--
 llvm/test/CodeGen/AArch64/wineh-pac.ll        |  7 +--
 llvm/test/CodeGen/ARM/setjmp-bti-basic.ll     |  5 +--
 llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll  |  7 +--
 llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll  |  7 +--
 .../CodeGen/Thumb2/bti-indirect-branches.ll   |  9 ++--
 llvm/test/CodeGen/Thumb2/bti-outliner-1.ll    |  9 ++--
 llvm/test/CodeGen/Thumb2/bti-outliner-2.ll    | 12 ++---
 .../CodeGen/Thumb2/bti-outliner-cost-2.ll     |  6 +--
 .../test/CodeGen/Thumb2/bti-pac-replace-1.mir |  8 +---
 llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll |  7 +--
 llvm/test/CodeGen/Thumb2/jump-table-bti.ll    | 10 ++---
 llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll    |  6 +--
 .../Thumb2/pacbti-m-indirect-tail-call.ll     |  2 +-
 .../CodeGen/Thumb2/pacbti-m-outliner-1.ll     |  2 +-
 .../CodeGen/Thumb2/pacbti-m-outliner-3.ll     |  2 +-
 .../CodeGen/Thumb2/pacbti-m-outliner-4.ll     |  6 +--
 .../CodeGen/Thumb2/pacbti-m-outliner-5.ll     |  4 +-
 .../test/CodeGen/Thumb2/pacbti-m-overalign.ll |  2 +-
 .../test/CodeGen/Thumb2/pacbti-m-stack-arg.ll |  4 +-
 .../Thumb2/pacbti-m-unsupported-arch.ll       |  8 +---
 .../test/CodeGen/Thumb2/pacbti-m-varargs-1.ll |  4 +-
 .../test/CodeGen/Thumb2/pacbti-m-varargs-2.ll |  4 +-
 llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll      |  2 +-
 .../AArch64/link-branch-target-enforcement.ll |  2 +-
 .../Inline/inline-sign-return-address.ll      | 13 +++---
 .../LowerTypeTests/function-arm-thumb.ll      |  2 +-
 .../LowerTypeTests/function-thumb-bti.ll      |  4 +-
 .../Transforms/LowerTypeTests/function.ll     |  4 +-
 llvm/test/Verifier/branch-prot-attrs.ll       | 16 ++++++-
 60 files changed, 292 insertions(+), 316 deletions(-)
 create mode 100644 clang/test/Frontend/arm-branch-protection-lto.c

diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 9b0ae2102e098..1f208b40f92cb 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -32,7 +32,9 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Frontend/OpenMP/OMPGridValues.h"
+#include "llvm/IR/Attributes.h"
 #include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/VersionTuple.h"
@@ -1400,15 +1402,15 @@ class TargetInfo : public TransferrableTargetInfo,
     return true;
   }
 
-  struct BranchProtectionInfo {
+  class BranchProtectionInfo {
+  public:
     LangOptions::SignReturnAddressScopeKind SignReturnAddr;
     LangOptions::SignReturnAddressKeyKind SignKey;
     bool BranchTargetEnforcement;
     bool BranchProtectionPAuthLR;
     bool GuardedControlStack;
 
-    BranchProtectionInfo() = default;
-
+  protected:
     const char *getSignReturnAddrStr() const {
       switch (SignReturnAddr) {
       case LangOptions::SignReturnAddressScopeKind::None:
@@ -1430,6 +1432,42 @@ class TargetInfo : public TransferrableTargetInfo,
       }
       llvm_unreachable("Unexpected SignReturnAddressKeyKind");
     }
+
+  public:
+    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;
+    }
+
+    void setFnAttributes(llvm::Function &F) {
+      llvm::AttrBuilder FuncAttrs(F.getContext());
+      setFnAttributes(FuncAttrs);
+      F.addFnAttrs(FuncAttrs);
+    }
+
+    void setFnAttributes(llvm::AttrBuilder &FuncAttrs) {
+      if (SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
+        FuncAttrs.addAttribute("sign-return-address", getSignReturnAddrStr());
+        FuncAttrs.addAttribute("sign-return-address-key", getSignKeyStr());
+      }
+      if (BranchTargetEnforcement)
+        FuncAttrs.addAttribute("branch-target-enforcement");
+      if (BranchProtectionPAuthLR)
+        FuncAttrs.addAttribute("branch-protection-pauth-lr");
+      if (GuardedControlStack)
+        FuncAttrs.addAttribute("guarded-control-stack");
+    }
   };
 
   /// 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 8ebf3d9a51b50..3891f9fc8174b 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -120,37 +120,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());
-
-    auto *Fn = cast<llvm::Function>(GV);
-    Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
-
-    if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
-      Fn->addFnAttr("sign-return-address-key",
-                    BPI.SignKey == LangOptions::SignReturnAddressKeyKind::AKey
-                        ? "a_key"
-                        : "b_key");
+    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());
+      }
     }
-
-    Fn->addFnAttr("branch-target-enforcement",
-                  BPI.BranchTargetEnforcement ? "true" : "false");
-    Fn->addFnAttr("branch-protection-pauth-lr",
-                  BPI.BranchProtectionPAuthLR ? "true" : "false");
-    Fn->addFnAttr("guarded-control-stack",
-                  BPI.GuardedControlStack ? "true" : "false");
+    auto *Fn = cast<llvm::Function>(GV);
+    BPI.setFnAttributes(*Fn);
   }
 
   bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index f362e34f38dea..d449b97cdc685 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -152,9 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
               diag::warn_target_unsupported_branch_protection_attribute)
               << Arch;
         } else {
-          Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
-          Fn->addFnAttr("branch-target-enforcement",
-                        BPI.BranchTargetEnforcement ? "true" : "false");
+          BPI.setFnAttributes(*Fn);
         }
       } else if (CGM.getLangOpts().BranchTargetEnforcement ||
                  CGM.getLangOpts().hasSignReturnAddress()) {
@@ -167,6 +165,10 @@ 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());
+      BPI.setFnAttributes(*Fn);
     }
 
     const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
diff --git a/clang/test/CodeGen/aarch64-branch-protection-attr.c b/clang/test/CodeGen/aarch64-branch-protection-attr.c
index f0e1dcccd1e82..e7ae7fb1570c9 100644
--- a/clang/test/CodeGen/aarch64-branch-protection-attr.c
+++ b/clang/test/CodeGen/aarch64-branch-protection-attr.c
@@ -67,29 +67,29 @@ __attribute__ ((target("branch-protection=gcs")))
 void gcs() {}
 // CHECK: define{{.*}} void @gcs() #[[#GCS:]]
 
-// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none"
+// CHECK-DAG: attributes #[[#NONE]] = { {{.*}}
 
-// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
+// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" "guarded-control-stack" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
 
-// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="none"
+// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"
 
-// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
+// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
 
-// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
+// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key"
 
-// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
+// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
 
-// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="b_key"
+// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="b_key"
 
-// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key"
+// 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"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "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"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
+// CHECK-DAG: attributes #[[#PAUTHLR_BKEY]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="b_key"
 
-// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="false" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
+// CHECK-DAG: attributes #[[#PAUTHLR_LEAF]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"sign-return-address"="all" "sign-return-address-key"="a_key"
 
-// CHECK-DAG: attributes #[[#PAUTHLR_BTI]] = { {{.*}}"branch-protection-pauth-lr"="true" {{.*}}"branch-target-enforcement"="true" "guarded-control-stack"="false" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
+// CHECK-DAG: attributes #[[#PAUTHLR_BTI]] = { {{.*}} "branch-protection-pauth-lr" {{.*}}"branch-target-enforcement" {{.*}}"sign-return-address"="non-leaf" "sign-return-address-key"="a_key"
 
-// CHECK-DAG: attributes #[[#GCS]] = { {{.*}}"branch-target-enforcement"="false" "guarded-control-stack"="true" {{.*}} "sign-return-address"="none"
+// CHECK-DAG: attributes #[[#GCS]] = { {{.*}} "guarded-control-stack"
diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c
index 8bc54b1a56c38..11dd683a3d7e9 100644
--- a/clang/test/CodeGen/aarch64-sign-return-address.c
+++ b/clang/test/CodeGen/aarch64-sign-return-address.c
@@ -13,9 +13,15 @@
 
 // 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"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+
+// ALL:   attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
+// PART:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"="a_key"
+// B-KEY: attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"="b_key"
+// BTE:   attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+
 
 // Check module attributes
 
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-1.c b/clang/test/CodeGen/arm-branch-protection-attr-1.c
index 2a9cc600742f3..dd38cf347f04f 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-1.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-1.c
@@ -29,14 +29,14 @@ __attribute__((target("branch-protection=pac-ret+leaf"))) void leaf() {}
 __attribute__((target("branch-protection=pac-ret+leaf+bti"))) void btileaf() {}
 // CHECK: define{{.*}} void @btileaf() #[[#BTIPACLEAF:]]
 
-// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="none"
+// CHECK-DAG: attributes #[[#NONE]] = { {{.*}}
 
-// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="non-leaf"
+// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" {{.*}} "sign-return-address"="non-leaf"
 
-// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="none"
+// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"
 
-// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf"
+// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf"
 
-// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}}"sign-return-address"="all"
+// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "sign-return-address"="all"
 
-// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" {{.*}} "sign-return-address"="all"
+// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}} "branch-target-enforcement" {{.*}} "sign-return-address"="all"
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-2.c b/clang/test/CodeGen/arm-branch-protection-attr-2.c
index 1f3c00873043e..fad5dc0707fb9 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-2.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-2.c
@@ -5,13 +5,18 @@
 // 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 are 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"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address-key"
+// NONE-NOT:  attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+
+// ALL:   attributes #[[#ATTR]] = { {{.*}} "sign-return-address"="all"
+// PART:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address"="non-leaf"
+// BTE:   attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+
 
 // Check module attributes
 
diff --git a/clang/test/Frontend/arm-branch-protection-lto.c b/clang/test/Frontend/arm-branch-protection-lto.c
new file mode 100644
index 0000000000000..6309a040d70dc
--- /dev/null
+++ b/clang/test/Frontend/arm-branch-protection-lto.c
@@ -0,0 +1,24 @@
+// REQUIRES: arm-registered-target
+
+// RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN
+// RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang_cc1 -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL
+
+// RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN
+// RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang_cc1 -flto -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL
+
+// RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -msign-return-address=non-leaf %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=SIGN
+// RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce  %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=BTE
+// RUN: %clang_cc1 -flto=thin -triple=thumbv7m-unknown-unknown-eabi -mbranch-target-enforce -msign-return-address=all %s -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALL
+
+void foo() {}
+
+// Check there are branch protection function attributes.
+// CHECK-LABEL: @foo() #[[#ATTR:]]
+
+// SIGN-NOT: attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// SIGN: attributes #[[#ATTR]] = { {{.*}} "sign-return-address"="non-leaf"
+// BTE:  attributes #[[#ATTR]] = { {{.*}} "sign-return-address"
+// BTE:  attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"
+// ALL:  attributes #[[#ATTR]] = { {{.*}} "branch-target-enforcement"{{.*}} "sign-return-address"="all"
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index e45569bfa472e..8545209410053 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11971,17 +11971,7 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
         // table branch.
         if (FallthroughUnreachable) {
           Function &CurFunc = CurMF->getFunction();
-          bool HasBranchTargetEnforcement = false;
-          if (CurFunc.hasFnAttribute("branch-target-enforcement")) {
-            HasBranchTargetEnforcement =
-                CurFunc.getFnAttribute("branch-target-enforcement")
-                    .getValueAsBool();
-          } else {
-            HasBranchTargetEnforcement =
-                CurMF->getMMI().getModule()->getModuleFlag(
-                    "branch-target-enforcement");
-          }
-          if (!HasBranchTargetEnforcement)
+          if (!CurFunc.hasFnAttribute("branch-target-enforcement"))
             JTH->FallthroughUnreachable = true;
         }
 
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c98f61d555140..684dbe79076ac 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2359,15 +2359,33 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
     if (S != "a_key" && S != "b_key")
       CheckFailed("invalid value for 'sign-return-address-key' attribute: " + S,
                   V);
+    if (auto AA = Attrs.getFnAttr("sign-return-address"); !AA.isValid()) {
+      CheckFailed(
+          "'sign-return-address-key' present without `sign-return-address`");
+    }
   }
 
   if (auto A = Attrs.getFnAttr("branch-target-enforcement"); A.isValid()) {
     StringRef S = A.getValueAsString();
-    if (S != "true" && S != "false")
+    if (S != "" && S != "true" && S != "false")
       CheckFailed(
           "invalid value for 'branch-target-enforcement' attribute: " + S, V);
   }
 
+  if (auto A = Attrs.getFnAttr("branch-protection-pauth-lr"); A.isValid()) {
+    StringRef S = A.getValueAsString();
+    if (S != "" && S != "true" && S != "false")
+      CheckFailed(
+          "invalid value for 'branch-protection-pauth-lr' attribute: " + S, V);
+  }
+
+  if (auto A = Attrs.getFnAttr("guarded-control-stack"); A.isValid()) {
+    StringRef S = A.getValueAsString();
+    if (S != "" && S != "true" && S != "false")
+      CheckFailed("invalid value for 'guarded-control-stack' attribute: " + S,
+                  V);
+  }
+
   if (auto A = Attrs.getFnAttr("vector-function-abi-variant"); A.isValid()) {
     StringRef S = A.getValueAsString();
     const std::optional<VFInfo> Info = VFABI::tryDemangleForVFABI(S, FT);
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index da11539eab348..c3f9f4b49c766 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -264,17 +264,17 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
   unsigned Flags = 0;
   if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
           M.getModuleFlag("branch-target-enforcement")))
-    if (BTE->getZExtValue())
+    if (!BTE->isZero())
       Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
 
   if (const auto *GCS = mdconst::extract_or_null<ConstantInt>(
           M.getModuleFlag("guarded-control-stack")))
-    if (GCS->getZExtValue())
+    if (!GCS->isZero())
       Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
 
   if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
           M.getModuleFlag("sign-return-address")))
-    if (Sign->getZExtValue())
+    if (!Sign->isZero())
       Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
 
   uint64_t PAuthABIPlatform = -1;
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 957d7bc79b187..201e8047b3686 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -41,19 +41,8 @@ static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
   // The function should be signed in the following situations:
   // - sign-return-address=all
   // - sign-return-address=non-leaf and the functions spills the LR
-  if (!F.hasFnAttribute("sign-return-address")) {
-    const Module &M = *F.getParent();
-    if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
-            M.getModuleFlag("sign-return-address"))) {
-      if (Sign->getZExtValue()) {
-        if (const auto *All = mdconst::extract_or_null<ConstantInt>(
-                M.getModuleFlag("sign-return-address-all")))
-          return {true, All->getZExtValue()};
-        return {true, false};
-      }
-    }
+  if (!F.hasFnAttribute("sign-return-address"))
     return {false, false};
-  }
 
   StringRef Scope = F.getFnAttribute("sign-return-address").getValueAsString();
   if (Scope == "none")
@@ -68,9 +57,6 @@ static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
 
 static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
   if (!F.hasFnAttribute("sign-return-address-key")) {
-    if (const auto *BKey = mdconst::extract_or_null<ConstantInt>(
-            F.getParent()->getModuleFlag("sign-return-address-with-bkey")))
-      return BKey->getZExtValue();
     if (STI.getTargetTriple().isOSWindows())
       return true;
     return false;
@@ -93,24 +79,9 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
   // TODO: skip functions that have no instrumented allocas for optimization
   IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
 
-  // BTI/PAuthLR may be set either on the function or the module. Set Bool from
-  // either the function attribute or module attribute, depending on what is
-  // set.
-  // Note: the module attributed is numeric (0 or 1) but the function attribute
-  // is stringy ("true" or "false").
-  auto TryFnThenModule = [&](StringRef AttrName, bool &Bool) {
-    if (F.hasFnAttribute(AttrName)) {
-      const StringRef V = F.getFnAttribute(AttrName).getValueAsString();
-      assert(V.equals_insensitive("true") || V.equals_insensitive("false"));
-      Bool = V.equals_insensitive("true");
-    } else if (const auto *ModVal = mdconst::extract_or_null<ConstantInt>(
-                   F.getParent()->getModuleFlag(AttrName))) {
-      Bool = ModVal->getZExtValue();
-    }
-  };
-
-  TryFnThenModule("branch-target-enforcement", BranchTargetEnforcement);
-  TryFnThenModule("branch-protection-pauth-lr", BranchProtectionPAuthLR);
+  // BTI/PAuthLR are set on the function attribute.
+  BranchTargetEnforcement = F.hasFnAttribute("branch-target-enforcement");
+  BranchProtectionPAuthLR = F.hasFnAttribute("branch-protection-pauth-lr");
 
   // The default stack probe size is 4096 if the function has no
   // stack-probe-size attribute. This is a safe default because it is the
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
index 54207562dbaeb..3ec40b11ac870 100644
--- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp
@@ -30,33 +30,13 @@ static bool GetBranchTargetEnforcement(const Function &F,
   if (!Subtarget->isMClass() || !Subtarget->hasV7Ops())
     return false;
 
-  if (!F.hasFnAttribute("branch-target-enforcement")) {
-    if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
-            F.getParent()->getModuleFlag("branch-target-enforcement")))
-      return BTE->getZExtValue();
-    return false;
-  }
-
-  const StringRef BTIEnable =
-      F.getFnAttribute("branch-target-enforcement").getValueAsString();
-  assert(BTIEnable == "true" || BTIEnable == "false");
-  return BTIEnable == "true";
+  return F.hasFnAttribute("branch-target-enforcement");
 }
 
 // The pair returns values for the ARMFunctionInfo members
 // SignReturnAddress and SignReturnAddressAll respectively.
 static std::pair<bool, bool> GetSignReturnAddress(const Function &F) {
   if (!F.hasFnAttribute("sign-return-address")) {
-    const Module &M = *F.getParent();
-    if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
-            M.getModuleFlag("sign-return-address"))) {
-      if (Sign->getZExtValue()) {
-        if (const auto *All = mdconst::extract_or_null<ConstantInt>(
-                M.getModuleFlag("sign-return-address-all")))
-          return {true, All->getZExtValue()};
-        return {true, false};
-      }
-    }
     return {false, false};
   }
 
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 9a78c77f8f28d..0742b259c489c 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -1519,8 +1519,10 @@ void LowerTypeTestsModule::createJumpTable(
   // for the function to avoid double BTI. This is a no-op without
   // -mbranch-protection=.
   if (JumpTableArch == Triple::aarch64 || JumpTableArch == Triple::thumb) {
-    F->addFnAttr("branch-target-enforcement", "false");
-    F->addFnAttr("sign-return-address", "none");
+    if (F->hasFnAttribute("branch-target-enforcement"))
+      F->removeFnAttr("branch-target-enforcement");
+    if (F->hasFnAttribute("sign-return-address"))
+      F->removeFnAttr("sign-return-address");
   }
   if (JumpTableArch == Triple::riscv32 || JumpTableArch == Triple::riscv64) {
     // Make sure the jump table assembly is not modified by the assembler or
diff --git a/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll b/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
index 3d8a5976559ba..6739f36ea51c9 100644
--- a/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
+++ b/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
@@ -18,13 +18,13 @@ entry:
   ret void
 }
 
-define void @bti_enabled(ptr %p) "branch-target-enforcement"="true" {
+define void @bti_enabled(ptr %p) "branch-target-enforcement" {
 entry:
   tail call void %p()
 ; CHECK: br {{x16|x17}}
   ret void
 }
-define void @bti_enabled_force_x10(ptr %p) "branch-target-enforcement"="true" {
+define void @bti_enabled_force_x10(ptr %p) "branch-target-enforcement" {
 entry:
   %p_x10 = tail call ptr asm "", "={x10},{x10},~{lr}"(ptr %p)
   tail call void %p_x10()
@@ -34,13 +34,13 @@ entry:
 
 ; sign-return-address places no further restrictions on the tail-call register.
 
-define void @bti_enabled_pac_enabled(ptr %p) "branch-target-enforcement"="true" "sign-return-address"="all" {
+define void @bti_enabled_pac_enabled(ptr %p) "branch-target-enforcement" "sign-return-address"="all" {
 entry:
   tail call void %p()
 ; CHECK: br {{x16|x17}}
   ret void
 }
-define void @bti_enabled_pac_enabled_force_x10(ptr %p) "branch-target-enforcement"="true" "sign-return-address"="all" {
+define void @bti_enabled_pac_enabled_force_x10(ptr %p) "branch-target-enforcement" "sign-return-address"="all" {
 entry:
   %p_x10 = tail call ptr asm "", "={x10},{x10},~{lr}"(ptr %p)
   tail call void %p_x10()
@@ -52,13 +52,13 @@ entry:
 ; can't be changed because the hint instruction only uses that register, so the
 ; only choice for the tail-call function pointer is x17.
 
-define void @bti_enabled_pac_pc_enabled(ptr %p) "branch-target-enforcement"="true" "sign-return-address"="all" "branch-protection-pauth-lr"="true" {
+define void @bti_enabled_pac_pc_enabled(ptr %p) "branch-target-enforcement" "sign-return-address"="all" "branch-protection-pauth-lr" {
 entry:
   tail call void %p()
 ; CHECK: br x17
   ret void
 }
-define void @bti_enabled_pac_pc_enabled_force_x16(ptr %p) "branch-target-enforcement"="true" "sign-return-address"="all" "branch-protection-pauth-lr"="true" {
+define void @bti_enabled_pac_pc_enabled_force_x16(ptr %p) "branch-target-enforcement" "sign-return-address"="all" "branch-protection-pauth-lr" {
 entry:
   %p_x16 = tail call ptr asm "", "={x16},{x16},~{lr}"(ptr %p)
   tail call void %p_x16()
@@ -69,20 +69,20 @@ entry:
 ; PAuthLR by itself prevents x16 from being used, but any other
 ; non-callee-saved register can be used.
 
-define void @pac_pc_enabled(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr"="true" {
+define void @pac_pc_enabled(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr" {
 entry:
   tail call void %p()
 ; CHECK: br {{(x[0-9]|x1[0-578])$}}
   ret void
 }
-define void @pac_pc_enabled_force_x16(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr"="true" {
+define void @pac_pc_enabled_force_x16(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr" {
 entry:
   %p_x16 = tail call ptr asm "", "={x16},{x16},~{lr}"(ptr %p)
   tail call void %p_x16()
 ; CHECK: br {{(x[0-9]|x1[0-578])$}}
   ret void
 }
-define void @pac_pc_enabled_force_x17(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr"="true" {
+define void @pac_pc_enabled_force_x17(ptr %p) "sign-return-address"="all" "branch-protection-pauth-lr" {
 entry:
   %p_x17 = tail call ptr asm "", "={x17},{x17},~{lr}"(ptr %p)
   tail call void %p_x17()
diff --git a/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll b/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
index e3e7f42526f78..2e3b99fd8ef34 100644
--- a/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
+++ b/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
@@ -61,4 +61,4 @@ declare dso_local void @e(...) local_unnamed_addr #0
 
 declare dso_local i64 @llvm.aarch64.space(i32, i64) local_unnamed_addr #0
 
-attributes #0 = { nounwind "branch-target-enforcement"="true" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #0 = { nounwind "branch-target-enforcement" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/llvm/test/CodeGen/AArch64/kcfi-bti.ll b/llvm/test/CodeGen/AArch64/kcfi-bti.ll
index d3febb536824e..1ac894fa09015 100644
--- a/llvm/test/CodeGen/AArch64/kcfi-bti.ll
+++ b/llvm/test/CodeGen/AArch64/kcfi-bti.ll
@@ -3,7 +3,7 @@
 ; RUN: llc -mtriple=aarch64-- -verify-machineinstrs -stop-after=kcfi < %s | FileCheck %s --check-prefixes=MIR,KCFI
 
 ; ASM:       .word 12345678
-define void @f1(ptr noundef %x) !kcfi_type !2 {
+define void @f1(ptr noundef %x) #1 !kcfi_type !2 {
 ; ASM-LABEL: f1:
 ; ASM:       // %bb.0:
 ; ASM:         ldur w16, [x0, #-4]
@@ -30,7 +30,7 @@ define void @f1(ptr noundef %x) !kcfi_type !2 {
 }
 
 ; ASM:       .word 12345678
-define void @f2(ptr noundef %x) !kcfi_type !2 {
+define void @f2(ptr noundef %x)  #1 !kcfi_type !2 {
 ; ASM-LABEL: f2:
 ; ASM:       // %bb.0:
 ; ASM:         ldur w16, [x0, #-4]
@@ -58,7 +58,7 @@ define void @f2(ptr noundef %x) !kcfi_type !2 {
 }
 
 ; ASM-NOT: .word:
-define void @f3(ptr noundef %x) {
+define void @f3(ptr noundef %x) #1 {
 ; ASM-LABEL: f3:
 ; ASM:       // %bb.0:
 ; ASM:         ldur w9, [x16, #-4]
@@ -85,6 +85,7 @@ define void @f3(ptr noundef %x) {
 }
 
 attributes #0 = { returns_twice }
+attributes #1 = { "branch-target-enforcement" }
 
 !llvm.module.flags = !{!0, !1}
 !0 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-2fixup-blr-terminator.mir b/llvm/test/CodeGen/AArch64/machine-outliner-2fixup-blr-terminator.mir
index 958c28879710c..2111704c0898f 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-2fixup-blr-terminator.mir
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-2fixup-blr-terminator.mir
@@ -8,7 +8,7 @@
   define void @f2() #0 { ret void }
   define void @f3() #0 { ret void }
   define void @f4() #0 { ret void }
-  attributes #0 = { minsize noredzone "branch-target-enforcement"="true" }
+  attributes #0 = { minsize noredzone "branch-target-enforcement" }
 ...
 ---
 name: f1
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir b/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
index ac31440ed7b6b..177954fb5ade4 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
@@ -15,7 +15,7 @@
 --- |
   @g = hidden local_unnamed_addr global i32 0, align 4
 
-  define hidden void @bar(ptr nocapture %f) "branch-target-enforcement"="true" {
+  define hidden void @bar(ptr nocapture %f) "branch-target-enforcement" {
   entry:
     ret void
   }
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll b/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
index 7ff7213dbd668..75e80d3b25338 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
@@ -5,7 +5,7 @@
 
 @g = hidden global i32 0, align 4
 
-define hidden void @foo() minsize "branch-target-enforcement"="true" {
+define hidden void @foo() minsize "branch-target-enforcement" {
 entry:
 ; CHECK: hint #34
 ; CHECK: b       OUTLINED_FUNCTION_0
@@ -13,7 +13,7 @@ entry:
   ret void
 }
 
-define hidden void @bar() minsize "branch-target-enforcement"="true" {
+define hidden void @bar() minsize "branch-target-enforcement" {
 entry:
 ; CHECK: hint #34
 ; CHECK: b       OUTLINED_FUNCTION_0
diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
index c4b80c426050a..abc2a4f7bf57e 100644
--- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
@@ -4,7 +4,7 @@
 ; RUN:   llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
 @x = common dso_local global i32 0, align 4
 
-attributes #0 = { "branch-target-enforcement"="true" }
+attributes #0 = { "branch-target-enforcement" }
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
index fff698d2152ac..7f6683c414c57 100644
--- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
@@ -11,9 +11,9 @@ entry:
   ret i32 0
 }
 
-attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" }
+attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
 
-attributes #1 = { "branch-target-enforcement"="true" }
+attributes #1 = { "branch-target-enforcement" }
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
diff --git a/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-1.ll b/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-1.ll
index 4a2c17d8a6c4e..7ef5df51ea2ba 100644
--- a/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-1.ll
+++ b/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-1.ll
@@ -14,7 +14,7 @@ entry:
 declare void @__asan_init()
 declare void @__asan_version_mismatch_check_v8()
 
-define internal void @asan.module_ctor() {
+define internal void @asan.module_ctor() #0 {
   call void @__asan_init()
   call void @__asan_version_mismatch_check_v8()
   ret void
@@ -22,7 +22,7 @@ define internal void @asan.module_ctor() {
 ;; CHECK-LABEL: asan.module_ctor:
 ;; CHECK: hint #34
 
-attributes #0 = { noinline nounwind optnone sanitize_address uwtable "branch-target-enforcement"="true" }
+attributes #0 = { noinline nounwind optnone sanitize_address uwtable "branch-target-enforcement" }
 
 !llvm.module.flags = !{!0, !1, !2, !3, !4}
 
diff --git a/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll b/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
index 1515db46efc46..a4ea86c1387c0 100644
--- a/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
+++ b/llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
@@ -58,14 +58,10 @@ entry:
 ;; CHECK-NEXT: .cfi_negate_ra_state
 
 attributes #0 = { norecurse nounwind readnone "sign-return-address"="all" "sign-return-address-key"="b_key" }
-attributes #1 = { noinline }
-attributes #2 = { nofree noinline norecurse nounwind writeonly }
+attributes #1 = { noinline "sign-return-address"="all" "sign-return-address-key"="b_key" }
+attributes #2 = { nofree noinline norecurse nounwind writeonly "sign-return-address"="all" "sign-return-address-key"="b_key" }
 
-!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
+!llvm.module.flags = !{!0, !1}
 
 !0 = !{i32 2, !"Debug Info Version", i32 3}
 !1 = !{i32 1, !"wchar_size", i32 4}
-!2 = !{i32 8, !"branch-target-enforcement", i32 0}
-!3 = !{i32 8, !"sign-return-address", i32 1}
-!4 = !{i32 8, !"sign-return-address-all", i32 1}
-!5 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
diff --git a/llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll b/llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
index ba4772178211d..5ea5a7e3ebc6b 100644
--- a/llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
+++ b/llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
@@ -61,12 +61,12 @@ entry:
 ;; CHECK:       paciasp
 ;; CHECK:       retaa
 
-attributes #0 = { nounwind "branch-target-enforcement"="false" "sign-return-address"="none" }
-attributes #1 = { nounwind "branch-target-enforcement"="true"  "sign-return-address"="none" }
-attributes #2 = { nounwind "branch-target-enforcement"="false" "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" }
-attributes #3 = { nounwind "branch-target-enforcement"="false" "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }
-attributes #4 = { nounwind "branch-target-enforcement"="false" "sign-return-address"="all" "sign-return-address-key"="a_key" }
-attributes #5 = { nounwind }
+attributes #0 = { nounwind }
+attributes #1 = { nounwind "branch-target-enforcement" }
+attributes #2 = { nounwind "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" }
+attributes #3 = { nounwind "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }
+attributes #4 = { nounwind "sign-return-address"="all" "sign-return-address-key"="a_key" }
+attributes #5 = { nounwind "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" }
 
 !llvm.module.flags = !{!0, !1, !2, !3, !4}
 
diff --git a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
index 106f6bb856b6b..85f5f6fa4674a 100644
--- a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
+++ b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
@@ -1,6 +1,6 @@
 ; RUN: llc -mtriple=aarch64 -aarch64-min-jump-table-entries=4 %s -o - | FileCheck %s
 
-define void @f0() "patchable-function-entry"="0" "branch-target-enforcement"="true" {
+define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" {
 ; CHECK-LABEL: f0:
 ; CHECK-NEXT: .Lfunc_begin0:
 ; CHECK:      // %bb.0:
@@ -12,7 +12,7 @@ define void @f0() "patchable-function-entry"="0" "branch-target-enforcement"="tr
 
 ;; -fpatchable-function-entry=1 -mbranch-protection=bti
 ;; For M=0, place the label .Lpatch0 after the initial BTI.
-define void @f1() "patchable-function-entry"="1" "branch-target-enforcement"="true" {
+define void @f1() "patchable-function-entry"="1" "branch-target-enforcement" {
 ; CHECK-LABEL: f1:
 ; CHECK-NEXT: .Lfunc_begin1:
 ; CHECK-NEXT: .cfi_startproc
@@ -28,7 +28,7 @@ define void @f1() "patchable-function-entry"="1" "branch-target-enforcement"="tr
 }
 
 ;; -fpatchable-function-entry=2,1 -mbranch-protection=bti
-define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement"="true" {
+define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement" {
 ; CHECK-LABEL: .type f2_1, at function
 ; CHECK-NEXT: .Ltmp0:
 ; CHECK-NEXT:  nop
@@ -49,7 +49,7 @@ define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="
 
 ;; -fpatchable-function-entry=1 -mbranch-protection=bti
 ;; We add BTI c even when the function has internal linkage
-define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement"="true" {
+define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement" {
 ; CHECK-LABEL: f1i:
 ; CHECK-NEXT: .Lfunc_begin3:
 ; CHECK:      // %bb.0:
@@ -99,7 +99,7 @@ sw.bb4:
 ; CHECK-NEXT:   hint #34
 ; CHECK-NEXT:   nop
 ; CHECK-NEXT:   ret
-define void @sanitize_function(ptr noundef %x) "patchable-function-prefix"="1" "patchable-function-entry"="1" "branch-target-enforcement"="true" !func_sanitize !0 {
+define void @sanitize_function(ptr noundef %x) "patchable-function-prefix"="1" "patchable-function-entry"="1" "branch-target-enforcement" !func_sanitize !0 {
   ret void
 }
 
diff --git a/llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll b/llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
index 36fc2f5b31c14..1d7d9efeb9ff2 100644
--- a/llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
+++ b/llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
@@ -27,7 +27,7 @@
 ;   return 2 + a * (a + b) / (c + d);
 ; }
 
-define i32 @f(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) {
+define i32 @f(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) #0 {
 ; BTI-LABEL: f:
 ; BTI:         bl      OUTLINED_FUNCTION_1
 ; BTI-NEXT:    bl      setjmp
@@ -39,7 +39,7 @@ define i32 @f(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) {
 ; NOBTI-NEXT:   bl      OUTLINED_FUNCTION_1
 
 entry:
-  %call = call i32 @setjmp(ptr noundef null) #0
+  %call = call i32 @setjmp(ptr noundef null) #1
   %add = add nsw i32 %b, %a
   %mul = mul nsw i32 %add, %a
   %add1 = add nsw i32 %d, %c
@@ -50,7 +50,7 @@ entry:
 
 declare i32 @setjmp(ptr noundef) #0
 
-define i32 @g(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) {
+define i32 @g(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) #0 {
 ; BTI-LABEL: g:
 ; BTI:         bl      OUTLINED_FUNCTION_1
 ; BTI-NEXT:    bl      setjmp
@@ -62,7 +62,7 @@ define i32 @g(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) {
 ; NOBTI-NEXT:   bl      OUTLINED_FUNCTION_1
 
 entry:
-  %call = call i32 @setjmp(ptr noundef null) #0
+  %call = call i32 @setjmp(ptr noundef null) #1
   %add = add nsw i32 %b, %a
   %mul = mul nsw i32 %add, %a
   %add1 = add nsw i32 %d, %c
@@ -76,8 +76,5 @@ entry:
 ; NOBTI:       OUTLINED_FUNCTION_1:
 ; NOBTI-LABEL:   ret
 
-attributes #0 = { returns_twice }
-
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+attributes #0 = { "branch-target-enforcement" }
+attributes #1 = { returns_twice }
diff --git a/llvm/test/CodeGen/AArch64/setjmp-bti.ll b/llvm/test/CodeGen/AArch64/setjmp-bti.ll
index 79a6bafffc8d8..f869abf31b231 100644
--- a/llvm/test/CodeGen/AArch64/setjmp-bti.ll
+++ b/llvm/test/CodeGen/AArch64/setjmp-bti.ll
@@ -24,7 +24,7 @@
 ;   notsetjmp();
 ; }
 
-define void @bbb() {
+define void @bbb() #1 {
 ; BTI-LABEL: bbb:
 ; BTI:       bl setjmp
 ; BTI-NEXT:  hint #36
@@ -72,6 +72,4 @@ declare i32 @setjmp(ptr noundef) #0
 declare void @notsetjmp()
 
 attributes #0 = { returns_twice }
-
-!llvm.module.flags = !{!0}
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+attributes #1 = { "branch-target-enforcement" }
diff --git a/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll b/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll
index a78fa853d99dc..2db26d96524ec 100644
--- a/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll
+++ b/llvm/test/CodeGen/AArch64/sign-return-address-pauth-lr.ll
@@ -15,17 +15,15 @@
 ; sign-return-address.ll tests combinations of -mbranch-protection=none/pac-ret
 ; and whether +pauth-lr is present or not.
 
-; sign-return-address-pauth-lr.ll is identical, with the addition of this module
+; sign-return-address-pauth-lr.ll is identical, with the addition of the function
 ; attribute, which enables -mbranch-protection=pac-ret+pc, and therefore tests
 ; the remaining parameter combinations in the table:
-!llvm.module.flags = !{!1}
-!1 = !{i32 1, !"branch-protection-pauth-lr", i32 1}
 
 ; RUN: llc -mtriple=aarch64              < %s | FileCheck --check-prefixes=CHECK,COMPAT %s
 ; RUN: llc -mtriple=aarch64 -mattr=v8.3a < %s | FileCheck --check-prefixes=CHECK,V83A %s
 ; RUN: llc -mtriple=aarch64 -mattr=v9a -mattr=pauth-lr < %s | FileCheck --check-prefixes=PAUTHLR %s
 
-define i32 @leaf(i32 %x) {
+define i32 @leaf(i32 %x) "branch-protection-pauth-lr" {
 ; CHECK-LABEL: leaf:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ret
@@ -36,7 +34,7 @@ define i32 @leaf(i32 %x) {
   ret i32 %x
 }
 
-define i32 @leaf_sign_none(i32 %x) "sign-return-address"="none"  {
+define i32 @leaf_sign_none(i32 %x) "branch-protection-pauth-lr"   {
 ; CHECK-LABEL: leaf_sign_none:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ret
@@ -47,7 +45,7 @@ define i32 @leaf_sign_none(i32 %x) "sign-return-address"="none"  {
   ret i32 %x
 }
 
-define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
+define i32 @leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
 ; CHECK-LABEL: leaf_sign_non_leaf:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ret
@@ -58,7 +56,7 @@ define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
   ret i32 %x
 }
 
-define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
+define i32 @leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
 ; COMPAT-LABEL: leaf_sign_all:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -89,7 +87,7 @@ define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
   ret i32 %x
 }
 
-define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf"  {
+define i64 @leaf_clobbers_lr(i64 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
 ; COMPAT-LABEL: leaf_clobbers_lr:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -144,7 +142,7 @@ define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf"  {
 
 declare i32 @foo(i32)
 
-define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
+define i32 @non_leaf_sign_all(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
 ; COMPAT-LABEL: non_leaf_sign_all:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -191,7 +189,7 @@ define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
   ret i32 %call
 }
 
-define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
+define i32 @non_leaf_sign_non_leaf(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf"  {
 ; COMPAT-LABEL: non_leaf_sign_non_leaf:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -239,7 +237,7 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf"  {
 }
 
 ; Should not use the RETAA instruction.
-define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18"  {
+define i32 @non_leaf_scs(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="non-leaf" shadowcallstack "target-features"="+v8.3a,+reserve-x18"  {
 ; CHECK-LABEL: non_leaf_scs:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    str x30, [x18], #8
@@ -278,7 +276,7 @@ define i32 @non_leaf_scs(i32 %x) "sign-return-address"="non-leaf" shadowcallstac
   ret i32 %call
 }
 
-define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
+define i32 @leaf_sign_all_v83(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" {
 ; CHECK-LABEL: leaf_sign_all_v83:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    hint #39
@@ -300,7 +298,7 @@ define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-featur
 
 declare fastcc i64 @bar(i64)
 
-define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
+define fastcc void @spill_lr_and_tail_call(i64 %x) "branch-protection-pauth-lr" "sign-return-address"="all" {
 ; COMPAT-LABEL: spill_lr_and_tail_call:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -356,7 +354,7 @@ define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
   ret void
 }
 
-define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" {
+define i32 @leaf_sign_all_a_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="a_key" {
 ; COMPAT-LABEL: leaf_sign_all_a_key:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #39
@@ -387,7 +385,7 @@ define i32 @leaf_sign_all_a_key(i32 %x) "sign-return-address"="all" "sign-return
   ret i32 %x
 }
 
-define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" {
+define i32 @leaf_sign_all_b_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="b_key" {
 ; COMPAT-LABEL: leaf_sign_all_b_key:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    .cfi_b_key_frame
@@ -421,7 +419,7 @@ define i32 @leaf_sign_all_b_key(i32 %x) "sign-return-address"="all" "sign-return
   ret i32 %x
 }
 
-define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" {
+define i32 @leaf_sign_all_v83_b_key(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" {
 ; CHECK-LABEL: leaf_sign_all_v83_b_key:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    .cfi_b_key_frame
@@ -444,7 +442,7 @@ define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-
 }
 
 ; Note that BTI instruction is not needed before PACIASP.
-define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"="true"{
+define i32 @leaf_sign_all_a_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement" {
 ; COMPAT-LABEL: leaf_sign_all_a_key_bti:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #34
@@ -479,7 +477,7 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-re
 }
 
 ; Note that BTI instruction is not needed before PACIBSP.
-define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"="true"{
+define i32 @leaf_sign_all_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement" {
 ; COMPAT-LABEL: leaf_sign_all_b_key_bti:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #34
@@ -517,7 +515,7 @@ define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-re
 }
 
 ; Note that BTI instruction is not needed before PACIBSP.
-define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement"="true" {
+define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "branch-protection-pauth-lr" "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement" {
 ; CHECK-LABEL: leaf_sign_all_v83_b_key_bti:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    hint #34
diff --git a/llvm/test/CodeGen/AArch64/sign-return-address.ll b/llvm/test/CodeGen/AArch64/sign-return-address.ll
index 1481d4beb50d6..dafe0d71ceb5f 100644
--- a/llvm/test/CodeGen/AArch64/sign-return-address.ll
+++ b/llvm/test/CodeGen/AArch64/sign-return-address.ll
@@ -12,7 +12,7 @@ define i32 @leaf(i32 %x) {
   ret i32 %x
 }
 
-define i32 @leaf_sign_none(i32 %x) "sign-return-address"="none"  {
+define i32 @leaf_sign_none(i32 %x) {
 ; CHECK-LABEL: leaf_sign_none:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    ret
@@ -238,7 +238,7 @@ define i32 @leaf_sign_all_v83_b_key(i32 %x) "sign-return-address"="all" "target-
 }
 
 ; Note that BTI instruction is not needed before PACIASP.
-define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"="true"{
+define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="a_key" "branch-target-enforcement"{
 ; COMPAT-LABEL: leaf_sign_all_a_key_bti:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    hint #25
@@ -255,7 +255,7 @@ define i32 @leaf_sign_all_a_key_bti(i32 %x) "sign-return-address"="all" "sign-re
 }
 
 ; Note that BTI instruction is not needed before PACIBSP.
-define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"="true"{
+define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-return-address-key"="b_key" "branch-target-enforcement"{
 ; COMPAT-LABEL: leaf_sign_all_b_key_bti:
 ; COMPAT:       // %bb.0:
 ; COMPAT-NEXT:    .cfi_b_key_frame
@@ -274,7 +274,7 @@ define i32 @leaf_sign_all_b_key_bti(i32 %x) "sign-return-address"="all" "sign-re
 }
 
 ; Note that BTI instruction is not needed before PACIBSP.
-define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement"="true" {
+define i32 @leaf_sign_all_v83_b_key_bti(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" "sign-return-address-key"="b_key" "branch-target-enforcement" {
 ; CHECK-LABEL: leaf_sign_all_v83_b_key_bti:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    .cfi_b_key_frame
diff --git a/llvm/test/CodeGen/AArch64/wineh-bti.ll b/llvm/test/CodeGen/AArch64/wineh-bti.ll
index a73f4d219bc31..8b8960d37f9ef 100644
--- a/llvm/test/CodeGen/AArch64/wineh-bti.ll
+++ b/llvm/test/CodeGen/AArch64/wineh-bti.ll
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -mtriple=aarch64-windows -aarch64-min-jump-table-entries=4 | FileCheck %s
 
-define dso_local i32 @func(i32 %in) {
+define dso_local i32 @func(i32 %in) "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "branch-target-enforcement" {
 entry:
   call void asm sideeffect "", "~{x19}"()
   switch i32 %in, label %def [
@@ -27,11 +27,6 @@ lbl4:
   ret i32 8
 }
 
-!llvm.module.flags = !{!0, !1}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
-!1 = !{i32 8, !"sign-return-address", i32 1}
-
 ; CHECK-LABEL: func:
 ; CHECK-NEXT: .seh_proc func
 ; CHECK-NEXT: // %bb.0:
diff --git a/llvm/test/CodeGen/AArch64/wineh-pac.ll b/llvm/test/CodeGen/AArch64/wineh-pac.ll
index 85ef463c8c127..797dd10d7e49d 100644
--- a/llvm/test/CodeGen/AArch64/wineh-pac.ll
+++ b/llvm/test/CodeGen/AArch64/wineh-pac.ll
@@ -1,20 +1,17 @@
 ; RUN: llc < %s -mtriple=aarch64-windows | FileCheck %s
 
-define dso_local i32 @func(ptr %g, i32 %a) {
+define dso_local i32 @func(ptr %g, i32 %a) "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" {
 entry:
   tail call void %g() #2
   ret i32 %a
 }
 
-define dso_local i32 @func2(ptr %g, i32 %a) "target-features"="+v8.3a" {
+define dso_local i32 @func2(ptr %g, i32 %a) "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" "target-features"="+v8.3a" {
 entry:
   tail call void %g() #2
   ret i32 %a
 }
 
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"sign-return-address", i32 1}
 
 ; CHECK-LABEL: func:
 ; CHECK-NEXT: .seh_proc func
diff --git a/llvm/test/CodeGen/ARM/setjmp-bti-basic.ll b/llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
index 41ba125ae5c15..3b01e3e9327e4 100644
--- a/llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
+++ b/llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
@@ -18,7 +18,7 @@
 
 @buf = global [20 x i64] zeroinitializer, align 8
 
-define i32 @foo(i32 %x) {
+define i32 @foo(i32 %x)  "branch-target-enforcement" {
 ; BTI-LABEL: foo:
 ; BTI:       bl setjmp
 ; BTI-NEXT:  bti
@@ -45,6 +45,3 @@ declare i32 @setjmp(ptr) #0
 
 attributes #0 = { returns_twice }
 
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll b/llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
index 2ff1a6df1f1ac..048781694b7d6 100644
--- a/llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
+++ b/llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
@@ -24,7 +24,7 @@
 
 @buf = global [20 x i64] zeroinitializer, align 8
 
-define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) {
+define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) "branch-target-enforcement" {
 ; BTI-LABEL: f:
 ; BTI:       bl OUTLINED_FUNCTION_0
 ; BTI-NEXT:  bti
@@ -53,7 +53,7 @@ return:                                           ; preds = %entry, %if.end
   ret i32 %retval.0
 }
 
-define i32 @g(i32 %a, i32 %b, i32 %c, i32 %d) {
+define i32 @g(i32 %a, i32 %b, i32 %c, i32 %d) "branch-target-enforcement" {
 ; BTI-LABEL: g:
 ; BTI:       bl OUTLINED_FUNCTION_0
 ; BTI-NEXT:  bti
@@ -87,6 +87,3 @@ declare i32 @setjmp(ptr) #0
 
 attributes #0 = { returns_twice }
 
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll b/llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
index 1c89e60bc6a54..5fcbf6e741494 100644
--- a/llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
@@ -1,6 +1,6 @@
 ; RUN: llc < %s -mtriple=thumbv7m-arm-none-eabi | FileCheck %s
 
-define hidden i32 @linkage_external() local_unnamed_addr {
+define hidden i32 @linkage_external() local_unnamed_addr "branch-target-enforcement" {
 ; CHECK-LABEL: linkage_external:
 ; CHECK: bti
 ; CHECK-NEXT: movs r0, #1
@@ -9,7 +9,7 @@ entry:
   ret i32 1
 }
 
-define internal i32 @linkage_internal() unnamed_addr {
+define internal i32 @linkage_internal() unnamed_addr "branch-target-enforcement" {
 ; CHECK-LABEL: linkage_internal:
 ; CHECK: bti
 ; CHECK: movs r0, #2
@@ -17,6 +17,3 @@ define internal i32 @linkage_internal() unnamed_addr {
 entry:
   ret i32 2
 }
-
-!llvm.module.flags = !{!1}
-!1 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll b/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
index e541a9b944524..c6ffb92d60d8d 100644
--- a/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc < %s -mtriple=thumbv7m-arm-none-eabi | FileCheck %s
 
-define internal i32 @table_switch(i32 %x) {
+define internal i32 @table_switch(i32 %x) "branch-target-enforcement" {
 ; CHECK-LABEL: table_switch:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    bti
@@ -57,7 +57,7 @@ return:
 
 @computed_goto_cases = private unnamed_addr constant [2 x ptr] [ptr blockaddress(@computed_goto, %return), ptr blockaddress(@computed_goto, %case_1)], align 4
 
-define internal i32 @computed_goto(i32 %x) {
+define internal i32 @computed_goto(i32 %x) "branch-target-enforcement" {
 ; CHECK-LABEL: computed_goto:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    bti
@@ -92,7 +92,7 @@ declare void @may_throw()
 declare void @consume_exception(ptr)
 declare i32 @__gxx_personality_v0(...)
 
-define internal i32 @exception_handling(i32 %0) personality ptr @__gxx_personality_v0 {
+define internal i32 @exception_handling(i32 %0) "branch-target-enforcement" personality ptr @__gxx_personality_v0 {
 ; CHECK-LABEL: exception_handling:
 ; CHECK:       @ %bb.0:
 ; CHECK-NEXT:    bti
@@ -125,6 +125,3 @@ return:
   %retval.0 = phi i32 [ 1, %lpad ], [ 0, %entry ]
   ret i32 %retval.0
 }
-
-!llvm.module.flags = !{!1}
-!1 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/Thumb2/bti-outliner-1.ll b/llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
index 26005a44d8aaa..160fc6f24a237 100644
--- a/llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
@@ -60,7 +60,7 @@ entry:
   ret i32 %add3
 }
 
-define hidden i32 @y(i32 %p) local_unnamed_addr #1 {
+define hidden i32 @y(i32 %p) local_unnamed_addr #0 {
 ; CHECK-LABEL: y:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    ldr r0, .LCPI1_0
@@ -90,7 +90,7 @@ entry:
   ret i32 %add3
 }
 
-define hidden i32 @z(i32 %p) local_unnamed_addr #2 {
+define hidden i32 @z(i32 %p) local_unnamed_addr #1 {
 ; CHECK-LABEL: z:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    bti
@@ -127,9 +127,8 @@ entry:
   ret i32 %add3
 }
 
-attributes #0 = { minsize nofree norecurse nounwind optsize  }
-attributes #1 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="false" }
-attributes #2 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="true"  }
+attributes #0 = { minsize nofree norecurse nounwind optsize }
+attributes #1 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement" }
 
 !llvm.module.flags = !{!0}
 
diff --git a/llvm/test/CodeGen/Thumb2/bti-outliner-2.ll b/llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
index 5492b96439a61..60d591b0c2b2a 100644
--- a/llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
@@ -10,7 +10,7 @@
 @e = hidden global i32 0, align 4
 @f = hidden global i32 0, align 4
 
-define hidden i32 @x(i32 %p) local_unnamed_addr #0 {
+define hidden i32 @x(i32 %p) local_unnamed_addr #1 {
 entry:
   %0 = load volatile i32, ptr @a, align 4
   %1 = load volatile i32, ptr @b, align 4
@@ -30,7 +30,7 @@ entry:
 ; CHECK:       bti
 ; CHECK:       bl OUTLINED_FUNCTION_0
 
-define hidden i32 @y(i32 %p) local_unnamed_addr #1 {
+define hidden i32 @y(i32 %p) local_unnamed_addr #0 {
 entry:
   %0 = load volatile i32, ptr @a, align 4
   %1 = load volatile i32, ptr @b, align 4
@@ -50,7 +50,7 @@ entry:
 ; CHECK-NOT:   bti
 ; CHECK-NOT:   bl OUTLINED_FUNCTION
 
-define hidden i32 @z(i32 %p) local_unnamed_addr #2 {
+define hidden i32 @z(i32 %p) local_unnamed_addr #1 {
 entry:
   %0 = load volatile i32, ptr @a, align 4
   %1 = load volatile i32, ptr @b, align 4
@@ -74,9 +74,5 @@ entry:
 ; CHECK:       bti
 
 attributes #0 = { minsize nofree norecurse nounwind optsize  }
-attributes #1 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="false" }
-attributes #2 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement"="true"  }
+attributes #1 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement" }
 
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
diff --git a/llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll b/llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
index cf1d8170e37eb..25916e32a2c36 100644
--- a/llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
@@ -44,8 +44,4 @@ entry:
 
 ; CHECK-NOT: OUTLINED_FUNCTION
 
-attributes #0 = { minsize nofree norecurse nounwind optsize  }
-
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+attributes #0 = { minsize nofree norecurse nounwind optsize "branch-target-enforcement" }
diff --git a/llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir b/llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
index 609dc72e258f8..a043c42c8644c 100644
--- a/llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
+++ b/llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
@@ -3,7 +3,7 @@
   target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
   target triple = "thumbv8.1m.main-arm-unknown-eabi"
 
-  define hidden i32 @_Z1fi(i32 %x) {
+  define hidden i32 @_Z1fi(i32 %x) "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "branch-target-enforcement" {
   entry:
     %add = add nsw i32 %x, 1
     %call = tail call i32 @_Z1gi(i32 %add)
@@ -13,12 +13,6 @@
 
   declare dso_local i32 @_Z1gi(i32)
 
-  !llvm.module.flags = !{!0, !1, !2}
-
-  !0 = !{i32 8, !"branch-target-enforcement", i32 1}
-  !1 = !{i32 8, !"sign-return-address", i32 1}
-  !2 = !{i32 8, !"sign-return-address-all", i32 0}
-
 ...
 ---
 name:            _Z1fi
diff --git a/llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll b/llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
index ee497433551f9..c309d992b95a5 100644
--- a/llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
+++ b/llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
@@ -3,7 +3,7 @@
 target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
 target triple = "thumbv8.1m.main-arm-unknown-eabi"
 
-define hidden i32 @_Z1fi(i32 %x) {
+define hidden i32 @_Z1fi(i32 %x) "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" "branch-target-enforcement" {
 entry:
   %add = add nsw i32 %x, 1
   %call = tail call i32 @_Z1gi(i32 %add)
@@ -13,11 +13,6 @@ entry:
 
 declare dso_local i32 @_Z1gi(i32)
 
-!llvm.module.flags = !{!0, !1, !2}
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
-!1 = !{i32 8, !"sign-return-address", i32 1}
-!2 = !{i32 8, !"sign-return-address-all", i32 0}
-
 ; Check the function starts with `pacbti` and correct unwind info is emitted
 ; CHECK-LABEL: _Z1fi:
 ; ...
diff --git a/llvm/test/CodeGen/Thumb2/jump-table-bti.ll b/llvm/test/CodeGen/Thumb2/jump-table-bti.ll
index b54bffc837e0e..cdb47b4fda724 100644
--- a/llvm/test/CodeGen/Thumb2/jump-table-bti.ll
+++ b/llvm/test/CodeGen/Thumb2/jump-table-bti.ll
@@ -6,25 +6,25 @@
 ;; Expect to see a range check whenever there is BTI, and not where there
 ;; isn't.
 
-; RUN: sed s/SPACE/4/ %s | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB
+; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB
 ; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB
 ; RUN: sed s/SPACE/4/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB
 ; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB
 
-; RUN: sed s/SPACE/400/ %s | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH
+; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH
 ; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH
 ; RUN: sed s/SPACE/400/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH
 ; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH
 
-; RUN: sed s/SPACE/400000/ %s | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV
+; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV
 ; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV
 ; RUN: sed s/SPACE/400000/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV
 ; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV
 
 declare i32 @llvm.arm.space(i32, i32)
 
-attributes #0 = { "branch-target-enforcement"="false" }
-attributes #1 = { "branch-target-enforcement"="true"  }
+attributes #0 = { norecurse }
+attributes #1 = { norecurse "branch-target-enforcement" }
 
 define ptr @test_jumptable(ptr %src, ptr %dst) {
 entry:
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
index 0376d2164bd08..0ae46cb8879ee 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
@@ -15,7 +15,7 @@ target triple = "thumbv8m.main-none-none-eabi"
 ;     return 1 + g(x - 1);
 ; }
 
-define hidden i32 @f0(i32 %x) local_unnamed_addr {
+define hidden i32 @f0(i32 %x) local_unnamed_addr "sign-return-address"="non-leaf" {
 entry:
   %sub = add nsw i32 %x, -1
   %call = tail call i32 @g(i32 %sub)
@@ -92,8 +92,8 @@ entry:
 
 declare dso_local i32 @g(i32) local_unnamed_addr
 
-attributes #0 = { "cmse_nonsecure_entry" "target-features"="+8msecext,+armv8.1-m.main"}
-attributes #1 = { "cmse_nonsecure_entry" "target-features"="+8msecext,+armv8-m.main,+fp-armv8d16"}
+attributes #0 = { "sign-return-address"="non-leaf" "cmse_nonsecure_entry" "target-features"="+8msecext,+armv8.1-m.main"}
+attributes #1 = { "sign-return-address"="non-leaf" "cmse_nonsecure_entry" "target-features"="+8msecext,+armv8-m.main,+fp-armv8d16"}
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
index 9fbc52e0b39f7..4dfac252e2314 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
@@ -28,7 +28,7 @@ entry:
 
 declare dso_local i32 @g(i32) local_unnamed_addr #0
 
-attributes #0 = { nounwind }
+attributes #0 = { nounwind "sign-return-address"="non-leaf"}
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
index 0b6d318348e3b..23924b2fb2f8c 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
@@ -116,7 +116,7 @@ entry:
 ; CHECK-NOT: r12
 ; CHECK: bx lr
 
-attributes #0 = { minsize nofree norecurse nounwind optsize uwtable}
+attributes #0 = { minsize nofree norecurse nounwind optsize uwtable "sign-return-address"="non-leaf"}
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
index f2cdd4a94b918..1b13e06546f15 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
@@ -136,7 +136,7 @@ return:                                           ; preds = %entry, %if.end
 ; CHECK-NEXT:  aut   r12, lr, sp
 ; CHECK-NEXT:  bx    lr
 
-attributes #0 = { minsize noinline norecurse nounwind optsize readnone uwtable }
+attributes #0 = { minsize noinline norecurse nounwind optsize readnone uwtable "sign-return-address"="non-leaf" }
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
index ffc29534df700..38c23977b623f 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
@@ -164,9 +164,9 @@ return:                                           ; preds = %entry, %if.end
 ; CHECK-NOT: aut
 ; CHECK:        b    _Z1hii
 
-attributes #0 = { minsize noinline optsize "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind }
-attributes #2 = { noreturn }
+attributes #0 = { minsize noinline optsize "sign-return-address"="non-leaf" "denormal-fp-math"="preserve-sign,preserve-sign" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+armv7-m,+hwdiv,+thumb-mode" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind "sign-return-address"="non-leaf" }
+attributes #2 = { noreturn "sign-return-address"="non-leaf" }
 
 
 !llvm.module.flags = !{!0, !1, !2}
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
index 6bfaf3bb520a0..053d6a1d01800 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
@@ -88,8 +88,8 @@ entry:
   ret i32 %add7
 }
 
-attributes #0 = { minsize nofree norecurse nounwind optsize }
-attributes #1 = { minsize nofree norecurse nounwind optsize "sign-return-address"="none" }
+attributes #0 = { minsize nofree norecurse nounwind optsize "sign-return-address"="non-leaf" }
+attributes #1 = { minsize nofree norecurse nounwind optsize }
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
index 371b703453fff..5dce6752c065e 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
@@ -14,7 +14,7 @@ target triple = "thumbv8.1m.main-arm-none-eabi"
 ;   return s;
 ; }
 
-define hidden i32 @_Z1fv() local_unnamed_addr {
+define hidden i32 @_Z1fv() local_unnamed_addr "sign-return-address"="non-leaf" {
 entry:
   %a = alloca [4 x i32], align 32
   %call = call i32 @_Z1giPi(i32 4, ptr nonnull %a)
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-stack-arg.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-stack-arg.ll
index c8c9a45b0c9c2..cae38b5e4a5a1 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-stack-arg.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-stack-arg.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
 ; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s
 
-define i32 @test_leaf(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %x) {
+define i32 @test_leaf(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %x) "sign-return-address"="all" {
 ; CHECK-LABEL: test_leaf:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    pac r12, lr, sp
@@ -15,7 +15,7 @@ entry:
   ret i32 %x
 }
 
-define i32 @test_non_leaf(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %x) {
+define i32 @test_non_leaf(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %x) "sign-return-address"="all" {
 ; CHECK-LABEL: test_non_leaf:
 ; CHECK:       @ %bb.0: @ %entry
 ; CHECK-NEXT:    pac r12, lr, sp
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
index b9daac7d18f7b..6561bac14177b 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
@@ -22,10 +22,4 @@ entry:
 ; CHECK-PACBTI:       pacbti
 declare dso_local i32 @g(i32)
 
-attributes #0 = { noinline nounwind }
-
-!llvm.module.flags = !{!0, !1, !2}
-
-!0 = !{i32 8, !"branch-target-enforcement", i32 1}
-!1 = !{i32 8, !"sign-return-address", i32 1}
-!2 = !{i32 8, !"sign-return-address-all", i32 0}
+attributes #0 = { noinline nounwind "sign-return-address"="non-leaf" "branch-target-enforcement" }
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
index 0cee42d137fb4..d027c9e8c7b54 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
@@ -64,8 +64,8 @@ for.body:                                         ; preds = %for.body.lr.ph, %fo
 declare void @llvm.va_start(ptr) #1
 declare void @llvm.va_end(ptr) #1
 
-attributes #0 = { nounwind optsize}
-attributes #1 = { nounwind }
+attributes #0 = { nounwind optsize "sign-return-address"="non-leaf" }
+attributes #1 = { nounwind "sign-return-address"="non-leaf" }
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
index 3c36b6913581b..8019cd5b6109e 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
@@ -82,8 +82,8 @@ declare void @llvm.va_end(ptr) #1
 
 declare dso_local i32 @_Z1gi(i32) local_unnamed_addr
 
-attributes #0 = { optsize }
-attributes #1 = { nounwind }
+attributes #0 = { optsize "sign-return-address"="non-leaf"}
+attributes #1 = { nounwind "sign-return-address"="non-leaf"}
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
index 853a56d41af88..c1d17a7587be0 100644
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
+++ b/llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
@@ -116,7 +116,7 @@ for.body.epil.2:                                  ; preds = %for.body.epil.1
 
 declare dso_local i32 @g(i32, ptr) local_unnamed_addr #0
 
-attributes #0 = { nounwind }
+attributes #0 = { nounwind "sign-return-address"="non-leaf"}
 
 !llvm.module.flags = !{!0, !1, !2}
 
diff --git a/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll b/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
index ccf8cf67ede6d..b3c9828cb645a 100644
--- a/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
+++ b/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
@@ -16,7 +16,7 @@ target triple = "aarch64-unknown-linux-gnu"
 
 declare i32 @foo();
 
-define i32 @main() {
+define i32 @main() "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" {
 entry:
   %add = call i32 @foo()
   ret i32 %add
diff --git a/llvm/test/Transforms/Inline/inline-sign-return-address.ll b/llvm/test/Transforms/Inline/inline-sign-return-address.ll
index c4d85fa671a4f..fc929ffb12b27 100644
--- a/llvm/test/Transforms/Inline/inline-sign-return-address.ll
+++ b/llvm/test/Transforms/Inline/inline-sign-return-address.ll
@@ -9,7 +9,7 @@ define internal void @foo_nonleaf() #1 {
   ret void
 }
 
-define internal void @foo_none() #2 {
+define internal void @foo_none() {
   ret void
 }
 
@@ -51,7 +51,7 @@ define dso_local void @bar_nonleaf() #1 {
   ret void
 }
 
-define dso_local void @bar_none() #2 {
+define dso_local void @bar_none()  {
 ; CHECK-LABEL: bar_none
 ; CHECK-NEXT:    call void @foo_all()
 ; CHECK-NEXT:    call void @foo_nonleaf()
@@ -97,8 +97,7 @@ define dso_local void @bar_bkey() #4 {
 }
 
 
-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
+attributes #0 = { "sign-return-address"="all" }
+attributes #1 = { "sign-return-address"="non-leaf" }
+attributes #3 = { "branch-protection-pauth-lr" "sign-return-address"="non-leaf" }
+attributes #4 = { "branch-protection-pauth-lr" "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" }
diff --git a/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll b/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll
index c482a20f9513a..736a06c98003a 100644
--- a/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll
@@ -46,4 +46,4 @@ define void @addrtaken() {
 ; CHECK-NEXT: }
 
 ; CHECK-DAG: attributes #[[AA]] = { naked noinline "target-features"="-thumb-mode" }
-; CHECK-DAG: attributes #[[AT]] = { naked noinline "branch-target-enforcement"="false" "sign-return-address"="none" "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
+; CHECK-DAG: attributes #[[AT]] = { naked noinline "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
diff --git a/llvm/test/Transforms/LowerTypeTests/function-thumb-bti.ll b/llvm/test/Transforms/LowerTypeTests/function-thumb-bti.ll
index c1308931c7816..d8f96cabcde75 100644
--- a/llvm/test/Transforms/LowerTypeTests/function-thumb-bti.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function-thumb-bti.ll
@@ -43,5 +43,5 @@ define i1 @foo(ptr %p) {
 ; BTI:   call void asm sideeffect "bti\0Ab.w $0\0Abti\0Ab.w $1\0A", "s,s"(ptr @f.cfi, ptr @g.cfi)
 ; NOBTI: call void asm sideeffect "b.w $0\0Ab.w $1\0A", "s,s"(ptr @f.cfi, ptr @g.cfi)
 
-; BTI: attributes [[ATTRS]] = { naked noinline "branch-target-enforcement"="false" "sign-return-address"="none" "target-features"="+thumb-mode,+pacbti" }
-; NOBTI: attributes [[ATTRS]] = { naked noinline "branch-target-enforcement"="false" "sign-return-address"="none" "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
+; BTI: attributes [[ATTRS]] = { naked noinline "target-features"="+thumb-mode,+pacbti" }
+; NOBTI: attributes [[ATTRS]] = { naked noinline "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
diff --git a/llvm/test/Transforms/LowerTypeTests/function.ll b/llvm/test/Transforms/LowerTypeTests/function.ll
index a858aace834d6..1504d6a47847e 100644
--- a/llvm/test/Transforms/LowerTypeTests/function.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function.ll
@@ -112,8 +112,8 @@ define i1 @foo(ptr %p) {
 ; X86-LINUX: attributes #[[ATTR]] = { naked nocf_check noinline }
 ; X86-WIN32: attributes #[[ATTR]] = { nocf_check noinline }
 ; ARM: attributes #[[ATTR]] = { naked noinline
-; THUMB: attributes #[[ATTR]] = { naked noinline "branch-target-enforcement"="false" "sign-return-address"="none" "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
-; THUMBV6M: attributes #[[ATTR]] = { naked noinline "branch-target-enforcement"="false" "sign-return-address"="none" "target-features"="+thumb-mode" }
+; THUMB: attributes #[[ATTR]] = { naked noinline "target-cpu"="cortex-a8" "target-features"="+thumb-mode" }
+; THUMBV6M: attributes #[[ATTR]] = { naked noinline "target-features"="+thumb-mode" }
 ; RISCV: attributes #[[ATTR]] = { naked noinline "target-features"="-c,-relax" }
 ; LOONGARCH64: attributes #[[ATTR]] = { naked noinline }
 
diff --git a/llvm/test/Verifier/branch-prot-attrs.ll b/llvm/test/Verifier/branch-prot-attrs.ll
index aa0fad6b258ec..3c34345fd3b2c 100644
--- a/llvm/test/Verifier/branch-prot-attrs.ll
+++ b/llvm/test/Verifier/branch-prot-attrs.ll
@@ -8,6 +8,10 @@ define void @g() #1 {
   ret void
 }
 
+define void @h() #2 {
+  ret void
+}
+
 attributes #0 = {
 ; CHECK:  invalid value for 'sign-return-address' attribute: non-loaf
   "sign-return-address"="non-loaf"
@@ -22,4 +26,14 @@ attributes #1 = {
 ; CHECK: invalid value for 'sign-return-address-key' attribute: B_Key
   "sign-return-address-key"="B_Key"
 ; CHECK:   invalid value for 'branch-target-enforcement' attribute: True
-  "branch-target-enforcement"="True" }
+  "branch-target-enforcement"="True"
+; CHECK:   invalid value for 'branch-protection-pauth-lr' attribute: Yes
+  "branch-protection-pauth-lr"="Yes"
+; CHECK:   invalid value for 'guarded-control-stack' attribute: True
+  "guarded-control-stack"="True"
+  }
+
+attributes #2 = {
+; CHECK:  'sign-return-address-key' present without `sign-return-address`
+  "sign-return-address-key"="a_key"
+  }



More information about the cfe-commits mailing list