Index: clang/lib/CodeGen/CGDeclCXX.cpp =================================================================== --- clang/lib/CodeGen/CGDeclCXX.cpp +++ clang/lib/CodeGen/CGDeclCXX.cpp @@ -392,22 +392,6 @@ !isInSanitizerBlacklist(SanitizerKind::ShadowCallStack, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::ShadowCallStack); - auto RASignKind = getLangOpts().getSignReturnAddressScope(); - if (RASignKind != LangOptions::SignReturnAddressScopeKind::None) { - Fn->addFnAttr("sign-return-address", - RASignKind == LangOptions::SignReturnAddressScopeKind::All - ? "all" - : "non-leaf"); - auto RASignKey = getLangOpts().getSignReturnAddressKey(); - Fn->addFnAttr("sign-return-address-key", - RASignKey == LangOptions::SignReturnAddressKeyKind::AKey - ? "a_key" - : "b_key"); - } - - if (getLangOpts().BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); - return Fn; } Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -5398,40 +5398,60 @@ if (!FD) return; - LangOptions::SignReturnAddressScopeKind Scope = - CGM.getLangOpts().getSignReturnAddressScope(); - LangOptions::SignReturnAddressKeyKind Key = - CGM.getLangOpts().getSignReturnAddressKey(); - bool BranchTargetEnforcement = CGM.getLangOpts().BranchTargetEnforcement; + /* Here deal with flags that are different from the module flags */ if (const auto *TA = FD->getAttr()) { ParsedTargetAttr Attr = TA->parse(); if (!Attr.BranchProtection.empty()) { TargetInfo::BranchProtectionInfo BPI; StringRef Error; + (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, BPI, Error); assert(Error.empty()); - Scope = BPI.SignReturnAddr; - Key = BPI.SignKey; - BranchTargetEnforcement = BPI.BranchTargetEnforcement; - } - } - auto *Fn = cast(GV); - if (Scope != LangOptions::SignReturnAddressScopeKind::None) { - Fn->addFnAttr("sign-return-address", - Scope == LangOptions::SignReturnAddressScopeKind::All - ? "all" - : "non-leaf"); + auto *Fn = cast(GV); - Fn->addFnAttr("sign-return-address-key", - Key == LangOptions::SignReturnAddressKeyKind::AKey - ? "a_key" - : "b_key"); - } + if (BPI.SignReturnAddr == + LangOptions::SignReturnAddressScopeKind::None) { + /* This flag will be removed in the backend */ + Fn->addFnAttr("ignore-sign-return-address"); + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address"); + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address-key"); + } + // Update flags only when differ from the codegen flags. + else { + LangOptions::SignReturnAddressScopeKind Scope = + CGM.getLangOpts().getSignReturnAddressScope(); + LangOptions::SignReturnAddressKeyKind Key = + CGM.getLangOpts().getSignReturnAddressKey(); + if (Scope != BPI.SignReturnAddr || Key != BPI.SignKey) { + Fn->addFnAttr("sign-return-address", + BPI.SignReturnAddr == + LangOptions::SignReturnAddressScopeKind::All + ? "all" + : "non-leaf"); + + Fn->addFnAttr("sign-return-address-key", + BPI.SignKey == + LangOptions::SignReturnAddressKeyKind::AKey + ? "a_key" + : "b_key"); + } + } - if (BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); + if (CGM.getLangOpts().BranchTargetEnforcement && + !BPI.BranchTargetEnforcement) { + /* This flag will be removed in the backend */ + Fn->addFnAttr("ignore-branch-target-enforcement"); + } + if (!CGM.getLangOpts().BranchTargetEnforcement && + BPI.BranchTargetEnforcement) { + Fn->addFnAttr("branch-target-enforcement"); + } + } + } } }; Index: clang/test/CodeGen/aarch64-branch-protection-attr.c =================================================================== --- clang/test/CodeGen/aarch64-branch-protection-attr.c +++ clang/test/CodeGen/aarch64-branch-protection-attr.c @@ -1,8 +1,8 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang_cc1 -triple aarch64-unknown-unknown-eabi -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - \ +// RUN: %clang_cc1 -triple aarch64-unknown-unknown-eabi -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - | opt -S --aarch64-branch-protection \ // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=NO-OVERRIDE // RUN: %clang_cc1 -triple aarch64-unknown-unknown-eabi -emit-llvm -target-cpu generic -target-feature +v8.5a %s -o - \ -// RUN: -msign-return-address=non-leaf -msign-return-address-key=a_key -mbranch-target-enforce \ +// RUN: -msign-return-address=non-leaf -msign-return-address-key=a_key -mbranch-target-enforce | opt -S --aarch64-branch-protection \ // RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=OVERRIDE void missing() {} @@ -11,13 +11,13 @@ __attribute__ ((target("branch-protection=none"))) void none() {} -// NO-OVERRIDE: define void @none() #[[#NONE]] +// NO-OVERRIDE: define void @none() #[[#NONE:]] // OVERRIDE: define void @none() #[[#NONE:]] __attribute__ ((target("branch-protection=standard"))) void std() {} // NO-OVERRIDE: define void @std() #[[#STD:]] -// OVERRIDE: define void @std() #[[#STD]] +// OVERRIDE: define void @std() #[[#STD:]] __attribute__ ((target("branch-protection=bti"))) void btionly() {} @@ -36,8 +36,8 @@ __attribute__ ((target("branch-protection=bti+pac-ret"))) void pacbti1() {} -// NO-OVERRIDE: define void @pacbti1() #[[#PACBTI]] -// OVERRIDE: define void @pacbti1() #[[#PACBTI]] +// NO-OVERRIDE: define void @pacbti1() #[[#PACBTIL:]] +// OVERRIDE: define void @pacbti1() #[[#PACBTI:]] __attribute__ ((target("branch-protection=pac-ret+leaf"))) void leaf() {} @@ -56,8 +56,8 @@ __attribute__ ((target("branch-protection=pac-ret+leaf+b-key"))) void bkeyleaf1() {} -// NO-OVERRIDE: define void @bkeyleaf1() #[[#PACBKEYLEAF]] -// OVERRIDE: define void @bkeyleaf1() #[[#PACBKEYLEAF]] +// NO-OVERRIDE: define void @bkeyleaf1() #[[#PACBKEYLEAF:]] +// OVERRIDE: define void @bkeyleaf1() #[[#PACBKEYLEAF:]] __attribute__ ((target("branch-protection=pac-ret+leaf+bti"))) void btileaf() {} @@ -68,7 +68,7 @@ // CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#BTI]] = { {{.*}}"branch-target-enforcement" +// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement" // CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" @@ -78,4 +78,4 @@ // CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement" {{.*}} "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" Index: clang/test/CodeGen/aarch64-sign-return-address.c =================================================================== --- clang/test/CodeGen/aarch64-sign-return-address.c +++ clang/test/CodeGen/aarch64-sign-return-address.c @@ -10,18 +10,16 @@ // REQUIRES: aarch64-registered-target -// CHECK: @foo() #[[ATTR:[0-9]*]] -// -// NONE-NOT: "sign-return-address"={{.*}} +// NONE-NOT: "sign-return-address" -// PARTIAL: "sign-return-address"="non-leaf" +// PARTIAL: !"sign-return-address", !"non-leaf" -// ALL: "sign-return-address"="all" +// ALL: !"sign-return-address", !"all" -// BTE: "branch-target-enforcement" +// BTE: !"branch-target-enforcement" -// A-KEY: "sign-return-address-key"="a_key" +// A-KEY: !"sign-return-address-key", !"a_key" -// B-KEY: "sign-return-address-key"="b_key" +// B-KEY: !"sign-return-address-key", !"b_key" void foo() {} Index: clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp @@ -0,0 +1,42 @@ +// RUN: %clang -target aarch64-linux-android -mbranch-protection=none -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PAC +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+leaf -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PAC +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PACB +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key+leaf -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PACB +// RUN: %clang -target aarch64-linux-android -mbranch-protection=standard -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PAC +// RUN: %clang -target aarch64-linux-android -mbranch-protection=bti -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-BTI +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key+leaf+bti -c %s -o - | \ +// RUN: llvm-objdump -d --mattr=+bti --mattr=+pa - | FileCheck %s --check-prefix=CHECK-PACB + +void a(); +void d(); + +void c() { + try { + d(); + } catch (...) { + a(); + } +} + +// CHECK-NONE: 0000000000000000 <__clang_call_terminate>: +// CHECK-NONE-NEXT: str x30, [sp, #-16]! + +// CHECK-PAC: 0000000000000000 <__clang_call_terminate>: +// CHECK-PAC-NEXT: paciasp +// CHECK-PAC-NEXT: str x30, [sp, #-16]! + +// CHECK-PACB: 0000000000000000 <__clang_call_terminate>: +// CHECK-PACB-NEXT: pacibsp +// CHECK-PACB-NEXT: str x30, [sp, #-16]! + +// CHECK-BTI: 0000000000000000 <__clang_call_terminate>: +// CHECK-BTI-NEXT: bti c +// CHECK-BTI-NEXT: str x30, [sp, #-16]! Index: clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp =================================================================== --- clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp +++ clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp @@ -1,26 +1,26 @@ // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=none %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=standard %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY --check-prefix=CHECK-BTE +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY --check-prefix=CHECK-BTE // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-A-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+leaf %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-A-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-B-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-PARTIAL --check-prefix=CHECK-B-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=bti %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTE +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTE // RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -mbranch-protection=pac-ret+b-key+leaf+bti %s | \ -// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY --check-prefix=BTE +// RUN: opt -S --aarch64-branch-protection | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ALL --check-prefix=CHECK-B-KEY --check-prefix=BTE struct Foo { Foo() {} Index: llvm/lib/Target/AArch64/AArch64.h =================================================================== --- llvm/lib/Target/AArch64/AArch64.h +++ llvm/lib/Target/AArch64/AArch64.h @@ -47,6 +47,7 @@ FunctionPass *createAArch64A53Fix835769(); FunctionPass *createFalkorHWPFFixPass(); FunctionPass *createFalkorMarkStridedAccessesPass(); +ModulePass *createAArch64BranchProtectionPass(); FunctionPass *createAArch64BranchTargetsPass(); FunctionPass *createAArch64CleanupLocalDynamicTLSPass(); @@ -64,6 +65,7 @@ void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); void initializeAArch64AdvSIMDScalarPass(PassRegistry&); +void initializeAArch64BranchProtectionPass(PassRegistry &); void initializeAArch64BranchTargetsPass(PassRegistry&); void initializeAArch64CollectLOHPass(PassRegistry&); void initializeAArch64CondBrTuningPass(PassRegistry &); Index: llvm/lib/Target/AArch64/AArch64BranchTargets.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64BranchTargets.cpp +++ llvm/lib/Target/AArch64/AArch64BranchTargets.cpp @@ -26,9 +26,57 @@ using namespace llvm; #define DEBUG_TYPE "aarch64-branch-targets" +#define AARCH64_BRANCH_PROTECTION_NAME "AArch64 Branch Protection" #define AARCH64_BRANCH_TARGETS_NAME "AArch64 Branch Targets" namespace { + +struct AArch64BranchProtection : public ModulePass { + static char ID; + AArch64BranchProtection() : ModulePass(ID) { + initializeAArch64BranchProtectionPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + bool changed = false; + const bool addBti = M.getModuleFlag("branch-target-enforcement"); + const auto *sign_return_address = + dyn_cast_or_null(M.getModuleFlag("sign-return-address")); + const auto *sign_return_address_key = + dyn_cast_or_null(M.getModuleFlag("sign-return-address-key")); + + for (auto &F : M) { + if (F.isDeclaration()) + continue; + if (F.hasFnAttribute("ignore-branch-target-enforcement")) { + F.removeAttribute(llvm::AttributeList::FunctionIndex, + "ignore-branch-target-enforcement"); + changed = true; + } else if (addBti) { + F.addFnAttr("branch-target-enforcement"); + changed = true; + } + + if (F.hasFnAttribute("ignore-sign-return-address")) { + F.removeAttribute(llvm::AttributeList::FunctionIndex, + "ignore-sign-return-address"); + F.removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address"); + F.removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address-key"); + changed = true; + } else if (!F.hasFnAttribute("sign-return-address") && + sign_return_address) { + F.addFnAttr("sign-return-address", sign_return_address->getString()); + F.addFnAttr("sign-return-address-key", + sign_return_address_key->getString()); + changed = true; + } + } + return changed; + } +}; + class AArch64BranchTargets : public MachineFunctionPass { public: static char ID; @@ -42,10 +90,24 @@ }; } // end anonymous namespace +/// AArch64BranchProtection +INITIALIZE_PASS(AArch64BranchProtection, "aarch64-branch-protection", + AARCH64_BRANCH_PROTECTION_NAME, false, false) + +char AArch64BranchProtection::ID = 0; + +ModulePass *llvm::createAArch64BranchProtectionPass() { + return new AArch64BranchProtection(); +} + +/// AArch64BranchTargets char AArch64BranchTargets::ID = 0; -INITIALIZE_PASS(AArch64BranchTargets, "aarch64-branch-targets", - AARCH64_BRANCH_TARGETS_NAME, false, false) +INITIALIZE_PASS_BEGIN(AArch64BranchTargets, "aarch64-branch-targets", + AARCH64_BRANCH_TARGETS_NAME, false, false) +INITIALIZE_PASS_DEPENDENCY(AArch64BranchProtection) +INITIALIZE_PASS_END(AArch64BranchTargets, "aarch64-branch-targets", + AARCH64_BRANCH_TARGETS_NAME, false, false) void AArch64BranchTargets::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -118,8 +180,9 @@ auto MBBI = MBB.begin(); - // Skip the meta instuctions, those will be removed anyway. - for (; MBBI != MBB.end() && MBBI->isMetaInstruction(); ++MBBI) + // Skip the meta instructions, those will be removed anyway. + for (; MBBI != MBB.end() && (MBBI->isMetaInstruction() || MBBI->isPseudo()); + ++MBBI) ; // PACI[AB]SP are implicitly BTI JC, so no BTI instruction needed there. Index: llvm/lib/Target/AArch64/AArch64TargetMachine.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -33,6 +33,7 @@ #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/Metadata.h" #include "llvm/InitializePasses.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCTargetOptions.h" @@ -454,6 +455,9 @@ if (TM->getOptLevel() != CodeGenOpt::None && EnableAtomicTidy) addPass(createCFGSimplificationPass(1, true, true, false, true)); + // Sets up the branch protection attributes for functions that added so far. + addPass(createAArch64BranchProtectionPass()); + // Run LoopDataPrefetch // // Run this before LSR to remove the multiplies involved in computing the Index: llvm/test/CodeGen/AArch64/O0-pipeline.ll =================================================================== --- llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -16,6 +16,8 @@ ; CHECK-NEXT: Pre-ISel Intrinsic Lowering ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Expand Atomic instructions +; CHECK-NEXT: AArch64 Branch Protection +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Module Verifier ; CHECK-NEXT: Lower Garbage Collection Instructions ; CHECK-NEXT: Shadow Stack GC Lowering Index: llvm/test/CodeGen/AArch64/O3-pipeline.ll =================================================================== --- llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -23,6 +23,8 @@ ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Simplify the CFG +; CHECK-NEXT: AArch64 Branch Protection +; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information ; CHECK-NEXT: Lazy Branch Probability Analysis Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll @@ -8,9 +8,10 @@ ret i32 0 } -!llvm.module.flags = !{!0} +!llvm.module.flags = !{!0, !1} !0 = !{i32 4, !"sign-return-address", !"all"} +!1 = !{i32 4, !"sign-return-address-key", !"a_key"} ; PAC attribute present ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll @@ -8,10 +8,11 @@ ret i32 0 } -!llvm.module.flags = !{!0, !1} +!llvm.module.flags = !{!0, !1, !2} !0 = !{i32 4, !"branch-target-enforcement", i32 1} !1 = !{i32 4, !"sign-return-address", !"non-leaf"} +!2 = !{i32 4, !"sign-return-address-key", !"a_key"} ; Both attribute present ; ASM: .word 3221225472