diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1823,6 +1823,23 @@ std::tie(Var, Value) = Attr.split('='); FuncAttrs.addAttribute(Var, Value); } + + if (CodeGenOpts.BranchTargetEnforcement) { + FuncAttrs.addAttribute("branch-target-enforcement", "true"); + } + + auto RASignKind = CodeGenOpts.getSignReturnAddress(); + if (RASignKind != CodeGenOptions::SignReturnAddressScope::None) { + FuncAttrs.addAttribute( + "sign-return-address", + RASignKind == CodeGenOptions::SignReturnAddressScope::All ? "all" + : "non-leaf"); + auto RASignKey = CodeGenOpts.getSignReturnAddressKey(); + FuncAttrs.addAttribute( + "sign-return-address-key", + RASignKey == CodeGenOptions::SignReturnAddressKeyValue::AKey ? "a_key" + : "b_key"); + } } void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) { diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -406,7 +406,7 @@ } if (getCodeGenOpts().BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); + Fn->addFnAttr("branch-target-enforcement", "true"); return Fn; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -583,6 +583,27 @@ 1); } + if (CodeGenOpts.BranchTargetEnforcement) { + getModule().addModuleFlag(llvm::Module::Override, + "branch-target-enforcement", 1); + } + + CodeGenOptions::SignReturnAddressScope Scope = + CodeGenOpts.getSignReturnAddress(); + if (Scope != CodeGenOptions::SignReturnAddressScope::None) { + getModule().addModuleFlag( + llvm::Module::Override, "sign-return-address", + Scope == CodeGenOptions::SignReturnAddressScope::All + ? llvm::MDString::get(VMContext, "all") + : llvm::MDString::get(VMContext, "non-leaf")); + getModule().addModuleFlag( + llvm::Module::Override, "sign-return-address-key", + CodeGenOpts.getSignReturnAddressKey() == + CodeGenOptions::SignReturnAddressKeyValue::AKey + ? llvm::MDString::get(VMContext, "a_key") + : llvm::MDString::get(VMContext, "b_key")); + } + if (LangOpts.CUDAIsDevice && getTriple().isNVPTX()) { // Indicate whether __nvvm_reflect should be configured to flush denormal // floating point values to 0. (This corresponds to its "__CUDA_FTZ" diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5134,10 +5134,17 @@ Key == CodeGenOptions::SignReturnAddressKeyValue::AKey ? "a_key" : "b_key"); + } else { + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address"); + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address-key"); } if (BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); + Fn->addFnAttr("branch-target-enforcement", "true"); + else + Fn->addFnAttr("branch-target-enforcement", "false"); } llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override { diff --git a/clang/test/CodeGen/aarch64-branch-protection-attr.c b/clang/test/CodeGen/aarch64-branch-protection-attr.c --- a/clang/test/CodeGen/aarch64-branch-protection-attr.c +++ b/clang/test/CodeGen/aarch64-branch-protection-attr.c @@ -64,18 +64,18 @@ // NO-OVERRIDE: define void @btileaf() #[[#BTIPACLEAF:]] // OVERRIDE: define void @btileaf() #[[#BTIPACLEAF:]] -// CHECK-DAG: attributes #[[#NONE]] +// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" -// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "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"="true" -// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "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"="true" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c --- a/clang/test/CodeGen/aarch64-sign-return-address.c +++ b/clang/test/CodeGen/aarch64-sign-return-address.c @@ -18,7 +18,7 @@ // ALL: "sign-return-address"="all" -// BTE: "branch-target-enforcement" +// BTE: "branch-target-enforcement"="true" // A-KEY: "sign-return-address-key"="a_key" diff --git a/clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp b/clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp @@ -0,0 +1,34 @@ +// RUN: %clang -target aarch64-linux-android -mbranch-protection=none -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+leaf -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key+leaf -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=standard -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTI +// RUN: %clang -target aarch64-linux-android -mbranch-protection=bti -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --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 - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTI + +void a(); +void d(); + +void c() { + try { + d(); + } catch (...) { + a(); + } +} + +// CHECK-BTI: 0000000000000000 __clang_call_terminate: +// CHECK-BTI-NEXT: bti c +// CHECK-BTI-NEXT: str x30, [sp, #-16]! + +// CHECK-NONE: 0000000000000000 __clang_call_terminate: +// CHECK-NONE-NEXT: str x30, [sp, #-16]! diff --git a/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp b/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp --- a/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp +++ b/clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp @@ -38,4 +38,4 @@ // CHECK-ALL: "sign-return-address"="all" // CHECK-A-KEY: "sign-return-address-key"="a_key" // CHECK-B-KEY: "sign-return-address-key"="b_key" -// CHECK-BTE: "branch-target-enforcement" +// CHECK-BTE: "branch-target-enforcement"="true" diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -187,19 +187,31 @@ return; // Assemble feature flags that may require creation of a note section. - unsigned Flags = ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI | - ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + unsigned Flags = 0; + if (M.getModuleFlag("branch-target-enforcement")) + Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + if (M.getModuleFlag("sign-return-address")) + Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC; if (any_of(M, [](const Function &F) { - return !F.isDeclaration() && - !F.hasFnAttribute("branch-target-enforcement"); + if (F.isDeclaration()) + return false; + if (!F.hasFnAttribute("branch-target-enforcement")) + return false; + Attribute A = F.getFnAttribute("branch-target-enforcement"); + return !A.isStringAttribute() || A.getValueAsString() == "false"; })) { Flags &= ~ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; } if ((Flags & ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI) == 0 && any_of(M, [](const Function &F) { - return F.hasFnAttribute("branch-target-enforcement"); + if (F.isDeclaration()) + return false; + if (!F.hasFnAttribute("branch-target-enforcement")) + return false; + Attribute A = F.getFnAttribute("branch-target-enforcement"); + return A.isStringAttribute() && A.getValueAsString() == "true"; })) { errs() << "warning: some functions compiled with BTI and some compiled " "without BTI\n" diff --git a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp --- a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp +++ b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp @@ -58,7 +58,13 @@ bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) { const Function &F = MF.getFunction(); - if (!F.hasFnAttribute("branch-target-enforcement")) + + Attribute A = F.getFnAttribute("branch-target-enforcement"); + if (A.isStringAttribute() && A.getValueAsString() == "false") + return false; + + if (!F.hasFnAttribute("branch-target-enforcement") && + !MF.getMMI().getModule()->getModuleFlag("branch-target-enforcement")) return false; LLVM_DEBUG( diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -762,7 +762,8 @@ // When BTI is enabled, we need to use TCRETURNriBTI to make sure that we use // x16 or x17. - if (CallerF.hasFnAttribute("branch-target-enforcement")) + Attribute A = CallerF.getFnAttribute("branch-target-enforcement"); + if (A.isStringAttribute() && A.getValueAsString() == "true") return AArch64::TCRETURNriBTI; return AArch64::TCRETURNri; @@ -782,7 +783,8 @@ // TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64 // register class. Until we can do that, we should fall back here. - if (F.hasFnAttribute("branch-target-enforcement")) { + Attribute A = F.getFnAttribute("branch-target-enforcement"); + if (A.isStringAttribute() && A.getValueAsString() == "true") { LLVM_DEBUG( dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n"); return false; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5859,7 +5859,9 @@ NumBytesToCreateFrame += 4; bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) { - return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement"); + Attribute A = + C.getMF()->getFunction().getFnAttribute("branch-target-enforcement"); + return A.isStringAttribute() && A.getValueAsString() == "true"; }); // Returns true if an instructions is safe to fix up, false otherwise. diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -570,8 +570,8 @@ // Avoid generating STRQro if it is slow, unless we're optimizing for code size. def UseSTRQro : Predicate<"!Subtarget->isSTRQroSlow() || shouldOptForSize(MF)">; - def UseBTI : Predicate<[{ MF->getFunction().hasFnAttribute("branch-target-enforcement") }]>; - def NotUseBTI : Predicate<[{ !MF->getFunction().hasFnAttribute("branch-target-enforcement") }]>; + def UseBTI : Predicate<[{ MF->getFunction().getFnAttribute("branch-target-enforcement").isStringAttribute() && (MF->getFunction().getFnAttribute("branch-target-enforcement").getValueAsString() == "true") }]>; + def NotUseBTI : Predicate<[{ !(MF->getFunction().getFnAttribute("branch-target-enforcement").isStringAttribute() && (MF->getFunction().getFnAttribute("branch-target-enforcement").getValueAsString() == "true")) }]>; // Toggles patterns which aren't beneficial in GlobalISel when we aren't // optimizing. This allows us to selectively use patterns without impacting diff --git a/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll b/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll --- a/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll +++ b/llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll @@ -20,7 +20,7 @@ ret void } -define void @bti_enabled(void ()* %p) "branch-target-enforcement" { +define void @bti_enabled(void ()* %p) "branch-target-enforcement"="true" { entry: tail call void %p() ; CHECK: br {{x16|x17}} diff --git a/llvm/test/CodeGen/AArch64/branch-target-enforcement.mir b/llvm/test/CodeGen/AArch64/branch-target-enforcement.mir --- a/llvm/test/CodeGen/AArch64/branch-target-enforcement.mir +++ b/llvm/test/CodeGen/AArch64/branch-target-enforcement.mir @@ -3,29 +3,29 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-arm-none-eabi" - define hidden i32 @simple_external() "branch-target-enforcement" { + define hidden i32 @simple_external() "branch-target-enforcement"="true" { entry: ret i32 0 } - define internal i32 @simple_internal() "branch-target-enforcement" { + define internal i32 @simple_internal() "branch-target-enforcement"="true" { entry: ret i32 0 } - define hidden i32 @ptr_auth() "branch-target-enforcement" { + define hidden i32 @ptr_auth() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 } - define hidden i32 @ptr_auth_b() "branch-target-enforcement" { + define hidden i32 @ptr_auth_b() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 } - define hidden i32 @jump_table(i32 %a) "branch-target-enforcement" { + define hidden i32 @jump_table(i32 %a) "branch-target-enforcement"="true" { entry: switch i32 %a, label %sw.epilog [ i32 1, label %sw.bb @@ -61,7 +61,7 @@ @label_address.addr = internal unnamed_addr global i8* blockaddress(@label_address, %return), align 8 - define hidden i32 @label_address() "branch-target-enforcement" { + define hidden i32 @label_address() "branch-target-enforcement"="true" { entry: %0 = load i8*, i8** @label_address.addr, align 8 indirectbr i8* %0, [label %return, label %lab2] @@ -79,7 +79,7 @@ ret i32 %merge2 } - define hidden i32 @label_address_entry() "branch-target-enforcement" { + define hidden i32 @label_address_entry() "branch-target-enforcement"="true" { entry: %0 = load i8*, i8** @label_address.addr, align 8 indirectbr i8* %0, [label %return, label %lab2] @@ -97,7 +97,7 @@ ret i32 %merge2 } - define hidden i32 @debug_ptr_auth() "branch-target-enforcement" { + define hidden i32 @debug_ptr_auth() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 diff --git a/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll b/llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll --- 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 i64 @llvm.aarch64.space(i32, i64) local_unnamed_addr #0 -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" } +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" } diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir b/llvm/test/CodeGen/AArch64/machine-outliner-bti.mir --- 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(void ()* nocapture %f) "branch-target-enforcement" { + define hidden void @bar(void ()* nocapture %f) "branch-target-enforcement"="true" { 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 --- 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" { +define hidden void @foo() minsize "branch-target-enforcement"="true" { entry: ; CHECK: hint #34 ; CHECK: b OUTLINED_FUNCTION_0 @@ -13,10 +13,10 @@ ret void } -define hidden void @bar() minsize "branch-target-enforcement" { +define hidden void @bar() minsize "branch-target-enforcement"="true" { entry: ; CHECK: hint #34 ; CHECK: b OUTLINED_FUNCTION_0 store volatile i32 1, i32* @g, align 4 ret void -} +} \ No newline at end of file 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 --- 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,12 @@ ; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ @x = common dso_local global i32 0, align 4 -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"all"} ; Both attributes present in a file with no functions. ; ASM: .word 3221225472 diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll @@ -8,7 +8,11 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; BTI attribute present ; ASM: .word 3221225472 diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll @@ -10,6 +10,10 @@ attributes #0 = { "sign-return-address"="all" } +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"sign-return-address", !"all"} + ; PAC attribute present ; ASM: .word 3221225472 ; ASM-NEXT: .word 4 diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll @@ -8,7 +8,12 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"non-leaf"} ; Both attribute present ; ASM: .word 3221225472 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 --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll @@ -13,9 +13,13 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } -attributes #1 = { "branch-target-enforcement" } +attributes #1 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; Only the common atttribute (BTI) ; ASM: .word 3221225472 diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll @@ -13,9 +13,15 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } + +attributes #1 = { "branch-target-enforcement"="false" "sign-return-address"="all" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"all"} -attributes #1 = { "sign-return-address"="all" } ; Only the common atttribute (PAC) ; ASM: warning: not setting BTI in feature flags diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll @@ -17,6 +17,11 @@ attributes #1 = { "sign-return-address"="none" } +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"sign-return-address", !"non-leaf"} + + ; No common attribute, no note section ; ASM-NOT: .note.gnu.property ; OBJ-NOT: .note.gnu.property diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll @@ -13,9 +13,13 @@ ret i32 0 } -attributes #0 = { "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="false" "sign-return-address"="non-leaf" } -attributes #1 = { "branch-target-enforcement" } +attributes #1 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; No common attribute, no note section ; ASM: warning: not setting BTI in feature flags diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll --- a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll @@ -11,7 +11,11 @@ declare dso_local i32 @g() -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; Declarations don't prevent setting BTI ; ASM: .word 3221225472 diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=aarch64-linux %s -o - | \ +; RUN: FileCheck %s --check-prefix=ASM +; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \ +; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ + +define dso_local i32 @f() #0 { +entry: + ret i32 0 +} + +define dso_local i32 @g() { +entry: + ret i32 0 +} + +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} + +; Only the common atttribute (BTI) +; ASM: .word 3221225472 +; ASM-NEXT: .word 4 +; ASM-NEXT .word 1 + +; OBJ: Properties: aarch64 feature: BTI diff --git a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll --- 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 %s -o - | FileCheck %s -define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" { +define void @f0() "patchable-function-entry"="0" "branch-target-enforcement"="true" { ; CHECK-LABEL: f0: ; CHECK-NEXT: .Lfunc_begin0: ; CHECK: // %bb.0: @@ -12,7 +12,7 @@ ;; -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" { +define void @f1() "patchable-function-entry"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: f1: ; CHECK-NEXT: .Lfunc_begin1: ; CHECK-NEXT: .cfi_startproc @@ -28,7 +28,7 @@ } ;; -fpatchable-function-entry=2,1 -mbranch-protection=bti -define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement" { +define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: .type f2_1,@function ; CHECK-NEXT: .Ltmp0: ; CHECK-NEXT: nop @@ -50,7 +50,7 @@ ;; -fpatchable-function-entry=1 -mbranch-protection=bti ;; For M=0, don't create .Lpatch0 if the initial instruction is not BTI, ;; even if other basic blocks may have BTI. -define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement" { +define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: f1i: ; CHECK-NEXT: .Lfunc_begin3: ; CHECK: // %bb.0: