danielkiss updated this revision to Diff 248222.
danielkiss marked an inline comment as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D75181/new/

https://reviews.llvm.org/D75181

Files:
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aarch64-branch-protection-attr.c
  clang/test/CodeGen/aarch64-sign-return-address.c
  clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp
  clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp
  llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
  llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
  llvm/lib/Target/AArch64/AArch64CallLowering.cpp
  llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
  llvm/lib/Target/AArch64/AArch64InstrInfo.td
  llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
  llvm/test/CodeGen/AArch64/branch-target-enforcement.mir
  llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
  llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
  llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll
  llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll

Index: llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
===================================================================
--- llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
+++ 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:
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll
===================================================================
--- /dev/null
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
+++ 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
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,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
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
@@ -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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
===================================================================
--- llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll
+++ 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
Index: llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
===================================================================
--- llvm/test/CodeGen/AArch64/machine-outliner-bti.mir
+++ 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
   }
Index: llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
===================================================================
--- llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll
+++ 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" }
Index: llvm/test/CodeGen/AArch64/branch-target-enforcement.mir
===================================================================
--- llvm/test/CodeGen/AArch64/branch-target-enforcement.mir
+++ 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
Index: llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
===================================================================
--- llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll
+++ 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}}
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ 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").getValueAsString() == "true" }]>;
+  def NotUseBTI : Predicate<[{ !(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
Index: llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -5859,7 +5859,10 @@
   NumBytesToCreateFrame += 4;
 
   bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) {
-    return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement");
+    return C.getMF()
+               ->getFunction()
+               .getFnAttribute("branch-target-enforcement")
+               .getValueAsString() == "true";
   });
 
   // Returns true if an instructions is safe to fix up, false otherwise.
Index: llvm/lib/Target/AArch64/AArch64CallLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ 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"))
+  if (CallerF.getFnAttribute("branch-target-enforcement").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")) {
+  if (F.getFnAttribute("branch-target-enforcement").getValueAsString() ==
+      "true") {
     LLVM_DEBUG(
         dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n");
     return false;
Index: llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
+++ llvm/lib/Target/AArch64/AArch64BranchTargets.cpp
@@ -58,8 +58,18 @@
 
 bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
   const Function &F = MF.getFunction();
-  if (!F.hasFnAttribute("branch-target-enforcement"))
-    return false;
+
+  // LLVM emmitted function won't have the attribute.
+  if (!F.hasFnAttribute("branch-target-enforcement")) {
+    // Fall back to the module flag, add BTI if the module is compiled with it.
+    if (!MF.getMMI().getModule()->getModuleFlag("branch-target-enforcement"))
+      return false;
+  } else {
+    // Explicitly requested to not generate BTI.
+    if (F.getFnAttribute("branch-target-enforcement").getValueAsString() ==
+        "false")
+      return false;
+  }
 
   LLVM_DEBUG(
       dbgs() << "********** AArch64 Branch Targets  **********\n"
Index: llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -187,19 +187,29 @@
     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;
+        return F.getFnAttribute("branch-target-enforcement")
+                   .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;
+        return F.getFnAttribute("branch-target-enforcement")
+                   .getValueAsString() == "true";
       })) {
     errs() << "warning: some functions compiled with BTI and some compiled "
               "without BTI\n"
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
@@ -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"
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,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]!
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
@@ -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"
 
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
@@ -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"
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -5106,38 +5106,53 @@
     if (!FD)
       return;
 
-    CodeGenOptions::SignReturnAddressScope Scope = CGM.getCodeGenOpts().getSignReturnAddress();
-    CodeGenOptions::SignReturnAddressKeyValue Key = CGM.getCodeGenOpts().getSignReturnAddressKey();
-    bool BranchTargetEnforcement = CGM.getCodeGenOpts().BranchTargetEnforcement;
     if (const auto *TA = FD->getAttr<TargetAttr>()) {
       ParsedTargetAttr Attr = TA->parse();
       if (!Attr.BranchProtection.empty()) {
         TargetInfo::BranchProtectionInfo BPI;
         StringRef Error;
+
+        CodeGenOptions::SignReturnAddressScope Scope =
+            CGM.getCodeGenOpts().getSignReturnAddress();
+        CodeGenOptions::SignReturnAddressKeyValue Key =
+            CGM.getCodeGenOpts().getSignReturnAddressKey();
+        bool BranchTargetEnforcement =
+            CGM.getCodeGenOpts().BranchTargetEnforcement;
+
         (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
                                                        BPI, Error);
         assert(Error.empty());
-        Scope = BPI.SignReturnAddr;
-        Key = BPI.SignKey;
-        BranchTargetEnforcement = BPI.BranchTargetEnforcement;
+        auto *Fn = cast<llvm::Function>(GV);
+
+        // Update flags only when differ from the codegen flags.
+        if (Scope != BPI.SignReturnAddr || Key != BPI.SignKey) {
+          Scope = BPI.SignReturnAddr;
+          Key = BPI.SignKey;
+          if (Scope != CodeGenOptions::SignReturnAddressScope::None) {
+            Fn->addFnAttr("sign-return-address",
+                          Scope == CodeGenOptions::SignReturnAddressScope::All
+                              ? "all"
+                              : "non-leaf");
+
+            Fn->addFnAttr("sign-return-address-key",
+                          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 != BPI.BranchTargetEnforcement) {
+          if (BPI.BranchTargetEnforcement)
+            Fn->addFnAttr("branch-target-enforcement", "true");
+          else
+            Fn->addFnAttr("branch-target-enforcement", "false");
+        }
       }
     }
-
-    auto *Fn = cast<llvm::Function>(GV);
-    if (Scope != CodeGenOptions::SignReturnAddressScope::None) {
-      Fn->addFnAttr("sign-return-address",
-                    Scope == CodeGenOptions::SignReturnAddressScope::All
-                        ? "all"
-                        : "non-leaf");
-
-      Fn->addFnAttr("sign-return-address-key",
-                    Key == CodeGenOptions::SignReturnAddressKeyValue::AKey
-                        ? "a_key"
-                        : "b_key");
-    }
-
-    if (BranchTargetEnforcement)
-      Fn->addFnAttr("branch-target-enforcement");
   }
   llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
                                    llvm::Value *Address) const override {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ 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"
Index: clang/lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ 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;
 }
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ 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) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to