[clang] [llvm] [ARM][AArch64] Change module flags values. (PR #84804)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 11 10:59:49 PDT 2024


https://github.com/DanielKristofKiss created https://github.com/llvm/llvm-project/pull/84804

Module flags are used to indicate the feature to be propagated to the function. As now the frontend all attributes are accordingly let's help the auto merger to only do work when old and new bitcodes are merged.
This patch depends on frontend  #82819 #83277 and backed #83154.
Also on the #84494. 

>From 36544d98f20dad644591feaded013cca34b5a6f1 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 8 Mar 2024 15:06:28 +0100
Subject: [PATCH 1/5] [NFC][LLVM] Refactor Autoupgrade function attributes from
 Module attributes.

Refactoring #82763 to cache module attributes.
---
 llvm/lib/IR/AutoUpgrade.cpp | 71 +++++++++++++------------------------
 1 file changed, 24 insertions(+), 47 deletions(-)

diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 25992395e471b3..856b6d656fc891 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5185,62 +5185,39 @@ static bool isModuleAttributeSet(Module &M, const StringRef &ModAttr) {
   return Attr && Attr->getZExtValue();
 }
 
-// Copy an attribute from module to the function if exists.
-// First value of the pair is used when the module attribute is not zero
-// the second otherwise.
-static void
-CopyModuleAttributeToFunction(Function &F, StringRef FnAttrName,
-                              StringRef ModAttrName,
-                              std::pair<StringRef, StringRef> Values) {
-  if (F.hasFnAttribute(FnAttrName))
-    return;
-  F.addFnAttr(FnAttrName, isModuleAttributeSet(*F.getParent(), ModAttrName)
-                              ? Values.first
-                              : Values.second);
-}
-
-// Copy a boolean attribute from module to the function if exists.
-// Module attribute treated false if zero otherwise true.
-static void CopyModuleAttributeToFunction(Function &F, StringRef AttrName) {
-  CopyModuleAttributeToFunction(
-      F, AttrName, AttrName,
-      std::make_pair<StringRef, StringRef>("true", "false"));
-}
-
-// Copy an attribute from module to the function if exists.
-// First value of the pair is used when the module attribute is not zero
-// the second otherwise.
-static void
-CopyModuleAttributeToFunction(Function &F, StringRef AttrName,
-                              std::pair<StringRef, StringRef> Values) {
-  CopyModuleAttributeToFunction(F, AttrName, AttrName, Values);
-}
-
 void llvm::CopyModuleAttrToFunctions(Module &M) {
   Triple T(M.getTargetTriple());
   if (!T.isThumb() && !T.isARM() && !T.isAArch64())
     return;
 
+  StringRef SignTypeValue = "none";
+  if (isModuleAttributeSet(M, "sign-return-address"))
+    SignTypeValue = "non-leaf";
+  if (isModuleAttributeSet(M, "sign-return-address-all"))
+    SignTypeValue = "all";
+
+  StringRef BTEValue =
+      isModuleAttributeSet(M, "branch-target-enforcement") ? "true" : "false";
+  StringRef BPPLValue =
+      isModuleAttributeSet(M, "branch-protection-pauth-lr") ? "true" : "false";
+  StringRef GCSValue =
+      isModuleAttributeSet(M, "guarded-control-stack") ? "true" : "false";
+  StringRef SignKeyValue =
+      isModuleAttributeSet(M, "sign-return-address-with-bkey") ? "b_key" : "a_key";
+
   for (Function &F : M.getFunctionList()) {
     if (F.isDeclaration())
       continue;
+    auto SetFunctionAttrIfNotSet = [&](StringRef FnAttrName, StringRef Value) {
+      if (!F.hasFnAttribute(FnAttrName))
+        F.addFnAttr(FnAttrName, Value);
+    };
 
-    if (!F.hasFnAttribute("sign-return-address")) {
-      StringRef SignType = "none";
-      if (isModuleAttributeSet(M, "sign-return-address"))
-        SignType = "non-leaf";
-
-      if (isModuleAttributeSet(M, "sign-return-address-all"))
-        SignType = "all";
-
-      F.addFnAttr("sign-return-address", SignType);
-    }
-    CopyModuleAttributeToFunction(F, "branch-target-enforcement");
-    CopyModuleAttributeToFunction(F, "branch-protection-pauth-lr");
-    CopyModuleAttributeToFunction(F, "guarded-control-stack");
-    CopyModuleAttributeToFunction(
-        F, "sign-return-address-key",
-        std::make_pair<StringRef, StringRef>("b_key", "a_key"));
+    SetFunctionAttrIfNotSet("sign-return-address", SignTypeValue);
+    SetFunctionAttrIfNotSet("branch-target-enforcement", BTEValue);
+    SetFunctionAttrIfNotSet("branch-protection-pauth-lr", BPPLValue);
+    SetFunctionAttrIfNotSet("guarded-control-stack", GCSValue);
+    SetFunctionAttrIfNotSet("sign-return-address-key", SignKeyValue);
   }
 }
 

>From f7370edabd77d7574906702b8233e7fd59e540b7 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 8 Mar 2024 17:27:08 +0100
Subject: [PATCH 2/5] fixup! [NFC][LLVM] Refactor Autoupgrade function
 attributes from Module attributes.

---
 llvm/lib/IR/AutoUpgrade.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 856b6d656fc891..7801df7172dc4a 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5203,7 +5203,8 @@ void llvm::CopyModuleAttrToFunctions(Module &M) {
   StringRef GCSValue =
       isModuleAttributeSet(M, "guarded-control-stack") ? "true" : "false";
   StringRef SignKeyValue =
-      isModuleAttributeSet(M, "sign-return-address-with-bkey") ? "b_key" : "a_key";
+      isModuleAttributeSet(M, "sign-return-address-with-bkey") ? "b_key"
+                                                               : "a_key";
 
   for (Function &F : M.getFunctionList()) {
     if (F.isDeclaration())

>From 187a9d18f04bd73c1d60d4e1e24a8400a1fee249 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 8 Mar 2024 21:20:16 +0100
Subject: [PATCH 3/5] fixup! [NFC][LLVM] Refactor Autoupgrade function
 attributes from Module attributes.

---
 llvm/lib/IR/AutoUpgrade.cpp                   | 27 ++++++++++---------
 .../LTO/AArch64/link-sign-return-address.ll   |  4 +--
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 7801df7172dc4a..f1c1a9c2b03024 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5182,7 +5182,14 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
 static bool isModuleAttributeSet(Module &M, const StringRef &ModAttr) {
   const auto *Attr =
       mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(ModAttr));
-  return Attr && Attr->getZExtValue();
+  return Attr && Attr->isOne();
+}
+
+// Check if the function attribute is not present and set it.
+static void SetFunctionAttrIfNotSet(Function &F, StringRef FnAttrName,
+                                    StringRef Value) {
+  if (!F.hasFnAttribute(FnAttrName))
+    F.addFnAttr(FnAttrName, Value);
 }
 
 void llvm::CopyModuleAttrToFunctions(Module &M) {
@@ -5191,10 +5198,10 @@ void llvm::CopyModuleAttrToFunctions(Module &M) {
     return;
 
   StringRef SignTypeValue = "none";
-  if (isModuleAttributeSet(M, "sign-return-address"))
-    SignTypeValue = "non-leaf";
   if (isModuleAttributeSet(M, "sign-return-address-all"))
     SignTypeValue = "all";
+  else if (isModuleAttributeSet(M, "sign-return-address"))
+    SignTypeValue = "non-leaf";
 
   StringRef BTEValue =
       isModuleAttributeSet(M, "branch-target-enforcement") ? "true" : "false";
@@ -5209,16 +5216,12 @@ void llvm::CopyModuleAttrToFunctions(Module &M) {
   for (Function &F : M.getFunctionList()) {
     if (F.isDeclaration())
       continue;
-    auto SetFunctionAttrIfNotSet = [&](StringRef FnAttrName, StringRef Value) {
-      if (!F.hasFnAttribute(FnAttrName))
-        F.addFnAttr(FnAttrName, Value);
-    };
 
-    SetFunctionAttrIfNotSet("sign-return-address", SignTypeValue);
-    SetFunctionAttrIfNotSet("branch-target-enforcement", BTEValue);
-    SetFunctionAttrIfNotSet("branch-protection-pauth-lr", BPPLValue);
-    SetFunctionAttrIfNotSet("guarded-control-stack", GCSValue);
-    SetFunctionAttrIfNotSet("sign-return-address-key", SignKeyValue);
+    SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
+    SetFunctionAttrIfNotSet(F, "branch-target-enforcement", BTEValue);
+    SetFunctionAttrIfNotSet(F, "branch-protection-pauth-lr", BPPLValue);
+    SetFunctionAttrIfNotSet(F, "guarded-control-stack", GCSValue);
+    SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
   }
 }
 
diff --git a/llvm/test/LTO/AArch64/link-sign-return-address.ll b/llvm/test/LTO/AArch64/link-sign-return-address.ll
index c25857ceed7b40..6d940d2cbacb14 100644
--- a/llvm/test/LTO/AArch64/link-sign-return-address.ll
+++ b/llvm/test/LTO/AArch64/link-sign-return-address.ll
@@ -29,9 +29,9 @@ entry:
 !3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; CHECK-DUMP: <foo>:
-; CHECK-DUMP:     paciasp
+; CHECK-DUMP:     pacibsp
 ; CHECK-DUMP:     mov     w0, #0x2a
-; CHECK-DUMP:     autiasp
+; CHECK-DUMP:     autibsp
 ; CHECK-DUMP:     ret
 ; CHECK-DUMP: <main>:
 ; CHECK-DUMP-NOT:  paciasp

>From 5a062e9b9d4da12573d67fcf02f9a1baf7159115 Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Sat, 9 Mar 2024 15:55:41 +0100
Subject: [PATCH 4/5] Update the
 llvm/test/LTO/AArch64/link-branch-target-enforcement.ll too.

Foo is signed with the Bkey.
---
 llvm/test/LTO/AArch64/link-branch-target-enforcement.ll | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll b/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
index 74d9c86881d52c..8313d812e189a4 100644
--- a/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
+++ b/llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
@@ -30,9 +30,11 @@ entry:
 
 ; CHECK-NOT: linking module flags 'branch-target-enforcement': IDs have conflicting values in
 ; CHECK-DUMP: <main>:
+; CHECK-DUMP:      paciasp
+; CHECK-DUMP:      str
 ; CHECK-DUMP:      bl      0x8 <main+0x8>
 ; CHECK-DUMP: <foo>:
-; CHECK-DUMP:     paciasp
+; CHECK-DUMP:     pacibsp
 
 ; `main` doesn't support BTI while `foo` does, so in the binary
 ; we should see only PAC which is supported by both.

>From b89e0c7609d031c5f384733e92747b5a3ee09dbf Mon Sep 17 00:00:00 2001
From: Daniel Kiss <daniel.kiss at arm.com>
Date: Fri, 8 Mar 2024 15:22:30 +0100
Subject: [PATCH 5/5] [ARM][AArch64] Change module flags values.

Module flag used to indicate the feature to be propagated to the
function. As now the frontend emits all attributes accoringly let's
help the automerger to only do work when old and new bitcodes are
merged.
---
 clang/lib/CodeGen/CodeGenModule.cpp           | 19 +++++---
 .../CodeGen/aarch64-sign-return-address.c     | 12 ++---
 .../CodeGen/arm-branch-protection-attr-2.c    |  8 ++--
 .../arm-ignore-branch-protection-option.c     |  2 +-
 llvm/lib/IR/AutoUpgrade.cpp                   | 47 ++++++++++---------
 llvm/test/LTO/AArch64/Inputs/bar.ll           | 22 +++++++++
 .../LTO/AArch64/link-sign-return-address.ll   | 17 ++++++-
 llvm/test/Linker/link-arm-and-thumb.ll        |  7 ++-
 8 files changed, 90 insertions(+), 44 deletions(-)
 create mode 100644 llvm/test/LTO/AArch64/Inputs/bar.ll

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 967319bdfc4571..f0d391b0a34e08 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1145,22 +1145,29 @@ void CodeGenModule::Release() {
                               "tag-stack-memory-buildattr", 1);
 
   if (T.isARM() || T.isThumb() || T.isAArch64()) {
+    // Previously 1 is used and meant for the backed to derive the function
+    // attribute form it. 2 now means function attributes already set for all
+    // functions in this module, so no need to propagate those from the module
+    // flag. Value is only used in case of LTO module merge because the backend
+    // will see all required function attribute set already. Value is used
+    // before modules got merged. Any posive value means the feature is active
+    // and required binary markings need to be emit accordingly.
     if (LangOpts.BranchTargetEnforcement)
       getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
-                                1);
+                                2);
     if (LangOpts.BranchProtectionPAuthLR)
       getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
-                                1);
+                                2);
     if (LangOpts.GuardedControlStack)
-      getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1);
+      getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
     if (LangOpts.hasSignReturnAddress())
-      getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
+      getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2);
     if (LangOpts.isSignReturnAddressScopeAll())
       getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all",
-                                1);
+                                2);
     if (!LangOpts.isSignReturnAddressWithAKey())
       getModule().addModuleFlag(llvm::Module::Min,
-                                "sign-return-address-with-bkey", 1);
+                                "sign-return-address-with-bkey", 2);
   }
 
   if (CodeGenOpts.StackClashProtector)
diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c
index 8bc54b1a56c38c..35c56889e07071 100644
--- a/clang/test/CodeGen/aarch64-sign-return-address.c
+++ b/clang/test/CodeGen/aarch64-sign-return-address.c
@@ -22,17 +22,17 @@
 // NONE-NOT:  !"branch-target-enforcement"
 // ALL-NOT:   !"branch-target-enforcement"
 // PART-NOT:  !"branch-target-enforcement"
-// BTE:       !{i32 8, !"branch-target-enforcement", i32 1}
+// BTE:       !{i32 8, !"branch-target-enforcement", i32 2}
 // B-KEY-NOT: !"branch-target-enforcement"
 
 // NONE-NOT:  !"sign-return-address"
-// ALL:   !{i32 8, !"sign-return-address", i32 1}
-// PART:  !{i32 8, !"sign-return-address", i32 1}
+// ALL:   !{i32 8, !"sign-return-address", i32 2}
+// PART:  !{i32 8, !"sign-return-address", i32 2}
 // BTE-NOT:   !"sign-return-address"
-// B-KEY: !{i32 8, !"sign-return-address", i32 1}
+// B-KEY: !{i32 8, !"sign-return-address", i32 2}
 
 // NONE-NOT:  !"sign-return-address-all"
-// ALL:   !{i32 8, !"sign-return-address-all", i32 1}
+// ALL:   !{i32 8, !"sign-return-address-all", i32 2}
 // PART-NOT:  !"sign-return-address-all"
 // BTE-NOT:   !"sign-return-address-all"
 // B-KEY-NOT: !"sign-return-address-all"
@@ -41,6 +41,6 @@
 // ALL-NOT:   !"sign-return-address-with-bkey"
 // PART-NOT:  !"sign-return-address-with-bkey"
 // BTE-NOT:   !"sign-return-address-with-bkey"
-// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 1}
+// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 2}
 
 void foo() {}
diff --git a/clang/test/CodeGen/arm-branch-protection-attr-2.c b/clang/test/CodeGen/arm-branch-protection-attr-2.c
index 1f3c00873043e8..741c0026c4d05c 100644
--- a/clang/test/CodeGen/arm-branch-protection-attr-2.c
+++ b/clang/test/CodeGen/arm-branch-protection-attr-2.c
@@ -18,16 +18,16 @@
 // NONE-NOT: !"branch-target-enforcement"
 // PART-NOT: !"branch-target-enforcement"
 // ALL-NOT:  !"branch-target-enforcement"
-// BTE:      !{i32 8, !"branch-target-enforcement", i32 1}
+// BTE:      !{i32 8, !"branch-target-enforcement", i32 2}
 
 // NONE-NOT: !"sign-return-address"
-// PART:     !{i32 8, !"sign-return-address", i32 1}
-// ALL:      !{i32 8, !"sign-return-address", i32 1}
+// PART:     !{i32 8, !"sign-return-address", i32 2}
+// ALL:      !{i32 8, !"sign-return-address", i32 2}
 // BTE-NOT:  !"sign-return-address"
 
 // NONE-NOT: !"sign-return-address-all", i32 0}
 // PART-NOT: !"sign-return-address-all", i32 0}
-// ALL:      !{i32 8, !"sign-return-address-all", i32 1}
+// ALL:      !{i32 8, !"sign-return-address-all", i32 2}
 // BTE-NOT:  !"sign-return-address-all", i32 0}
 
 void foo() {}
diff --git a/clang/test/Frontend/arm-ignore-branch-protection-option.c b/clang/test/Frontend/arm-ignore-branch-protection-option.c
index 99a2accef3ae2f..45bdb37f5ed1a3 100644
--- a/clang/test/Frontend/arm-ignore-branch-protection-option.c
+++ b/clang/test/Frontend/arm-ignore-branch-protection-option.c
@@ -15,4 +15,4 @@ __attribute__((target("arch=cortex-m0"))) void f() {}
 // CHECK-NOT:  attributes { {{.*}} "branch-target-enforcement"
 
 /// Check that there are branch protection module attributes despite the warning.
-// CHECK: !{i32 8, !"branch-target-enforcement", i32 1}
+// CHECK: !{i32 8, !"branch-target-enforcement", i32 2}
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index f1c1a9c2b03024..3c97c60ec044d2 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -5178,8 +5178,8 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
     Arg.removeAttrs(AttributeFuncs::typeIncompatible(Arg.getType()));
 }
 
-// Check if the module attribute is present and not zero.
-static bool isModuleAttributeSet(Module &M, const StringRef &ModAttr) {
+// Check if the module attribute is present and set to one.
+static bool isModuleAttributeOne(Module &M, const StringRef &ModAttr) {
   const auto *Attr =
       mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(ModAttr));
   return Attr && Attr->isOne();
@@ -5197,31 +5197,36 @@ void llvm::CopyModuleAttrToFunctions(Module &M) {
   if (!T.isThumb() && !T.isARM() && !T.isAArch64())
     return;
 
-  StringRef SignTypeValue = "none";
-  if (isModuleAttributeSet(M, "sign-return-address-all"))
+  bool BTE = isModuleAttributeOne(M, "branch-target-enforcement");
+  bool BPPLR = isModuleAttributeOne(M, "branch-protection-pauth-lr");
+  bool GCS = isModuleAttributeOne(M, "guarded-control-stack");
+  bool SRA = isModuleAttributeOne(M, "sign-return-address");
+
+  if (!BTE && !BPPLR && !GCS && !SRA)
+    return;
+
+  StringRef SignTypeValue = "non-leaf";
+  if (SRA && isModuleAttributeOne(M, "sign-return-address-all"))
     SignTypeValue = "all";
-  else if (isModuleAttributeSet(M, "sign-return-address"))
-    SignTypeValue = "non-leaf";
-
-  StringRef BTEValue =
-      isModuleAttributeSet(M, "branch-target-enforcement") ? "true" : "false";
-  StringRef BPPLValue =
-      isModuleAttributeSet(M, "branch-protection-pauth-lr") ? "true" : "false";
-  StringRef GCSValue =
-      isModuleAttributeSet(M, "guarded-control-stack") ? "true" : "false";
-  StringRef SignKeyValue =
-      isModuleAttributeSet(M, "sign-return-address-with-bkey") ? "b_key"
-                                                               : "a_key";
+
+  StringRef SignKeyValue = "a_key";
+  if (SRA && isModuleAttributeOne(M, "sign-return-address-with-bkey"))
+    SignKeyValue = "b_key";
 
   for (Function &F : M.getFunctionList()) {
     if (F.isDeclaration())
       continue;
 
-    SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
-    SetFunctionAttrIfNotSet(F, "branch-target-enforcement", BTEValue);
-    SetFunctionAttrIfNotSet(F, "branch-protection-pauth-lr", BPPLValue);
-    SetFunctionAttrIfNotSet(F, "guarded-control-stack", GCSValue);
-    SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
+    if (SRA) {
+      SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
+      SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
+    }
+    if (BTE)
+      SetFunctionAttrIfNotSet(F, "branch-target-enforcement", "true");
+    if (BPPLR)
+      SetFunctionAttrIfNotSet(F, "branch-protection-pauth-lr", "true");
+    if (GCS)
+      SetFunctionAttrIfNotSet(F, "guarded-control-stack", "true");
   }
 }
 
diff --git a/llvm/test/LTO/AArch64/Inputs/bar.ll b/llvm/test/LTO/AArch64/Inputs/bar.ll
new file mode 100644
index 00000000000000..1f0712660ebdc5
--- /dev/null
+++ b/llvm/test/LTO/AArch64/Inputs/bar.ll
@@ -0,0 +1,22 @@
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+define dso_local void @bar() #0 {
+entry:
+  ret void
+}
+
+define dso_local void @baz() #1 {
+entry:
+  ret void
+}
+
+attributes #0 = { noinline nounwind optnone uwtable }
+attributes #1 = { noinline nounwind optnone uwtable "branch-target-enforcement"="true" }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 8, !"branch-target-enforcement", i32 2}
+!1 = !{i32 8, !"sign-return-address", i32 2}
+!2 = !{i32 8, !"sign-return-address-all", i32 2}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 2}
diff --git a/llvm/test/LTO/AArch64/link-sign-return-address.ll b/llvm/test/LTO/AArch64/link-sign-return-address.ll
index 6d940d2cbacb14..f929092d889d0e 100644
--- a/llvm/test/LTO/AArch64/link-sign-return-address.ll
+++ b/llvm/test/LTO/AArch64/link-sign-return-address.ll
@@ -3,10 +3,11 @@
 ;
 ; RUN: llvm-as %s -o %t1.bc
 ; RUN: llvm-as %p/Inputs/foo.ll -o %t2.bc
+; RUN: llvm-as %p/Inputs/bar.ll -o %t3.bc
 ; RUN: llvm-lto -exported-symbol main \
 ; RUN:          -exported-symbol foo \
 ; RUN:          -filetype=obj \
-; RUN:           %t2.bc %t1.bc \
+; RUN:           %t3.bc %t2.bc %t1.bc \
 ; RUN:           -o %t1.exe 2>&1
 ; RUN: llvm-objdump -d %t1.exe | FileCheck --check-prefix=CHECK-DUMP %s
 ; RUN: llvm-readelf -n %t1.exe | FileCheck --allow-empty --check-prefix=CHECK-PROP %s
@@ -15,10 +16,14 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 target triple = "aarch64-unknown-linux-gnu"
 
 declare i32 @foo();
+declare void @baz();
+declare void @bar();
 
 define i32 @main() {
 entry:
   %add = call i32 @foo()
+  call void @bar()
+  call void @baz()
   ret i32 %add
 }
 
@@ -28,6 +33,12 @@ entry:
 !2 = !{i32 8, !"sign-return-address-all", i32 0}
 !3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
+
+; CHECK-DUMP: <bar>:
+; CHECK-DUMP:     ret
+; CHECK-DUMP: <baz>:
+; CHECK-DUMP:     bti     c
+; CHECK-DUMP:     ret
 ; CHECK-DUMP: <foo>:
 ; CHECK-DUMP:     pacibsp
 ; CHECK-DUMP:     mov     w0, #0x2a
@@ -36,7 +47,9 @@ entry:
 ; CHECK-DUMP: <main>:
 ; CHECK-DUMP-NOT:  paciasp
 ; CHECK-DUMP:      str     x30,
-; CHECK-DUMP:      bl      0x14 <main+0x4>
+; CHECK-DUMP:      bl      0x20 <main+0x4>
+; CHECK-DUMP:      bl      0x0 <bar>
+; CHECK-DUMP:      bl      0x4 <baz>
 
 ; `main` doesn't support PAC sign-return-address while `foo` does, so in the binary
 ; we should not see anything.
diff --git a/llvm/test/Linker/link-arm-and-thumb.ll b/llvm/test/Linker/link-arm-and-thumb.ll
index 37bd8c37f8b5e5..9794ae79edf706 100644
--- a/llvm/test/Linker/link-arm-and-thumb.ll
+++ b/llvm/test/Linker/link-arm-and-thumb.ll
@@ -13,12 +13,11 @@ entry:
   ret i32 %add
 }
 
-; CHECK: define i32 @main() [[MAIN_ATTRS:#[0-9]+]]
+; CHECK: define i32 @main() {
 ; CHECK: define i32 @foo(i32 %a, i32 %b) [[ARM_ATTRS:#[0-9]+]]
 ; CHECK: define i32 @bar(i32 %a, i32 %b) [[THUMB_ATTRS:#[0-9]+]]
 
-; CHECK: attributes [[MAIN_ATTRS]] = { {{.*}} }
-; CHECK: attributes [[ARM_ATTRS]] = { {{.*}} "target-features"="-thumb-mode" }
-; CHECK: attributes [[THUMB_ATTRS]] = { {{.*}} "target-features"="+thumb-mode" }
+; CHECK: attributes [[ARM_ATTRS]] = { {{.*}}"target-features"="-thumb-mode" }
+; CHECK: attributes [[THUMB_ATTRS]] = { {{.*}}"target-features"="+thumb-mode" }
 
 ; STDERR-NOT: warning: Linking two modules of different target triples:



More information about the cfe-commits mailing list