Skip to content

Commit f2f3356

Browse files
BTI,GCS,PAC Module flag update.
Module flag is 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. Autoupgrade function attributes from Module attributes when needed.
1 parent e33db24 commit f2f3356

File tree

22 files changed

+468
-46
lines changed

22 files changed

+468
-46
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,22 +1176,29 @@ void CodeGenModule::Release() {
11761176
"tag-stack-memory-buildattr", 1);
11771177

11781178
if (T.isARM() || T.isThumb() || T.isAArch64()) {
1179+
// Previously 1 is used and meant for the backed to derive the function
1180+
// attribute form it. 2 now means function attributes already set for all
1181+
// functions in this module, so no need to propagate those from the module
1182+
// flag. Value is only used in case of LTO module merge because the backend
1183+
// will see all required function attribute set already. Value is used
1184+
// before modules got merged. Any posive value means the feature is active
1185+
// and required binary markings need to be emit accordingly.
11791186
if (LangOpts.BranchTargetEnforcement)
11801187
getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
1181-
1);
1188+
2);
11821189
if (LangOpts.BranchProtectionPAuthLR)
11831190
getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
1184-
1);
1191+
2);
11851192
if (LangOpts.GuardedControlStack)
1186-
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1);
1193+
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
11871194
if (LangOpts.hasSignReturnAddress())
1188-
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
1195+
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2);
11891196
if (LangOpts.isSignReturnAddressScopeAll())
11901197
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all",
1191-
1);
1198+
2);
11921199
if (!LangOpts.isSignReturnAddressWithAKey())
11931200
getModule().addModuleFlag(llvm::Module::Min,
1194-
"sign-return-address-with-bkey", 1);
1201+
"sign-return-address-with-bkey", 2);
11951202

11961203
if (getTriple().isOSLinux()) {
11971204
assert(getTriple().isOSBinFormatELF());

clang/test/CodeGen/aarch64-sign-return-address.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@
2222
// NONE-NOT: !"branch-target-enforcement"
2323
// ALL-NOT: !"branch-target-enforcement"
2424
// PART-NOT: !"branch-target-enforcement"
25-
// BTE: !{i32 8, !"branch-target-enforcement", i32 1}
25+
// BTE: !{i32 8, !"branch-target-enforcement", i32 2}
2626
// B-KEY-NOT: !"branch-target-enforcement"
2727

2828
// NONE-NOT: !"sign-return-address"
29-
// ALL: !{i32 8, !"sign-return-address", i32 1}
30-
// PART: !{i32 8, !"sign-return-address", i32 1}
29+
// ALL: !{i32 8, !"sign-return-address", i32 2}
30+
// PART: !{i32 8, !"sign-return-address", i32 2}
3131
// BTE-NOT: !"sign-return-address"
32-
// B-KEY: !{i32 8, !"sign-return-address", i32 1}
32+
// B-KEY: !{i32 8, !"sign-return-address", i32 2}
3333

3434
// NONE-NOT: !"sign-return-address-all"
35-
// ALL: !{i32 8, !"sign-return-address-all", i32 1}
35+
// ALL: !{i32 8, !"sign-return-address-all", i32 2}
3636
// PART-NOT: !"sign-return-address-all"
3737
// BTE-NOT: !"sign-return-address-all"
3838
// B-KEY-NOT: !"sign-return-address-all"
@@ -41,6 +41,6 @@
4141
// ALL-NOT: !"sign-return-address-with-bkey"
4242
// PART-NOT: !"sign-return-address-with-bkey"
4343
// BTE-NOT: !"sign-return-address-with-bkey"
44-
// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 1}
44+
// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 2}
4545

4646
void foo() {}

clang/test/CodeGen/arm-branch-protection-attr-2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@
1818
// NONE-NOT: !"branch-target-enforcement"
1919
// PART-NOT: !"branch-target-enforcement"
2020
// ALL-NOT: !"branch-target-enforcement"
21-
// BTE: !{i32 8, !"branch-target-enforcement", i32 1}
21+
// BTE: !{i32 8, !"branch-target-enforcement", i32 2}
2222

2323
// NONE-NOT: !"sign-return-address"
24-
// PART: !{i32 8, !"sign-return-address", i32 1}
25-
// ALL: !{i32 8, !"sign-return-address", i32 1}
24+
// PART: !{i32 8, !"sign-return-address", i32 2}
25+
// ALL: !{i32 8, !"sign-return-address", i32 2}
2626
// BTE-NOT: !"sign-return-address"
2727

2828
// NONE-NOT: !"sign-return-address-all", i32 0}
2929
// PART-NOT: !"sign-return-address-all", i32 0}
30-
// ALL: !{i32 8, !"sign-return-address-all", i32 1}
30+
// ALL: !{i32 8, !"sign-return-address-all", i32 2}
3131
// BTE-NOT: !"sign-return-address-all", i32 0}
3232

3333
void foo() {}

clang/test/Frontend/arm-ignore-branch-protection-option.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ __attribute__((target("arch=cortex-m0"))) void f() {}
1515
// CHECK-NOT: attributes { {{.*}} "branch-target-enforcement"
1616

1717
/// Check that there are branch protection module attributes despite the warning.
18-
// CHECK: !{i32 8, !"branch-target-enforcement", i32 1}
18+
// CHECK: !{i32 8, !"branch-target-enforcement", i32 2}

llvm/include/llvm/IR/AutoUpgrade.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ namespace llvm {
8989
/// info. Return true if module is modified.
9090
bool UpgradeDebugInfo(Module &M);
9191

92+
/// Copies module attributes to the functions in the module.
93+
void CopyModuleAttrToFunctions(Module &M);
94+
9295
/// Check whether a string looks like an old loop attachment tag.
9396
inline bool mayBeOldLoopAttachmentTag(StringRef Name) {
9497
return Name.starts_with("llvm.vectorizer.");

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
438438

439439
UpgradeModuleFlags(*M);
440440
UpgradeSectionAttributes(*M);
441+
CopyModuleAttrToFunctions(*M);
441442

442443
if (!Slots)
443444
return false;

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6986,6 +6986,8 @@ Error BitcodeReader::materializeModule() {
69866986

69876987
UpgradeARCRuntime(*TheModule);
69886988

6989+
CopyModuleAttrToFunctions(*TheModule);
6990+
69896991
return Error::success();
69906992
}
69916993

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,106 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
52965296
}
52975297
}
52985298

5299+
// Check if the module attribute is present and set to one.
5300+
static bool isModuleAttributeOne(Module &M, const StringRef &ModAttr) {
5301+
const auto *Attr =
5302+
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(ModAttr));
5303+
return Attr && Attr->isOne();
5304+
}
5305+
5306+
// Check if the module attribute is present and set to two.
5307+
static bool isModuleAttributeTwo(Module &M, const StringRef &ModAttr) {
5308+
const auto *Attr =
5309+
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(ModAttr));
5310+
return Attr && Attr->getZExtValue() == 2;
5311+
}
5312+
5313+
// Check if the function attribute is not present and set it.
5314+
static void SetFunctionAttrIfNotSet(Function &F, StringRef FnAttrName,
5315+
StringRef Value) {
5316+
if (!F.hasFnAttribute(FnAttrName))
5317+
F.addFnAttr(FnAttrName, Value);
5318+
}
5319+
5320+
// Check if the function attribute is not present and set it if needed.
5321+
// If the attribute is "false" then removes it.
5322+
// If the attribute is "true" resets it to a valueless attribute.
5323+
static void ConvertFunctionAttr(Function &F, bool Set, StringRef FnAttrName) {
5324+
if (!F.hasFnAttribute(FnAttrName)) {
5325+
if (Set)
5326+
F.addFnAttr(FnAttrName);
5327+
} else {
5328+
auto A = F.getFnAttribute(FnAttrName);
5329+
if ("false" == A.getValueAsString())
5330+
F.removeFnAttr(FnAttrName);
5331+
else if ("true" == A.getValueAsString()) {
5332+
F.removeFnAttr(FnAttrName);
5333+
F.addFnAttr(FnAttrName);
5334+
}
5335+
}
5336+
}
5337+
5338+
void llvm::CopyModuleAttrToFunctions(Module &M) {
5339+
Triple T(M.getTargetTriple());
5340+
if (!T.isThumb() && !T.isARM() && !T.isAArch64())
5341+
return;
5342+
5343+
if (isModuleAttributeTwo(M, "branch-target-enforcement"))
5344+
return;
5345+
if (isModuleAttributeTwo(M, "branch-protection-pauth-lr"))
5346+
return;
5347+
if (isModuleAttributeTwo(M, "guarded-control-stack"))
5348+
return;
5349+
if (isModuleAttributeTwo(M, "sign-return-address"))
5350+
return;
5351+
5352+
bool BTE = isModuleAttributeOne(M, "branch-target-enforcement");
5353+
bool BPPLR = isModuleAttributeOne(M, "branch-protection-pauth-lr");
5354+
bool GCS = isModuleAttributeOne(M, "guarded-control-stack");
5355+
bool SRA = isModuleAttributeOne(M, "sign-return-address");
5356+
5357+
StringRef SignTypeValue = "non-leaf";
5358+
if (SRA && isModuleAttributeOne(M, "sign-return-address-all"))
5359+
SignTypeValue = "all";
5360+
5361+
StringRef SignKeyValue = "a_key";
5362+
if (SRA && isModuleAttributeOne(M, "sign-return-address-with-bkey"))
5363+
SignKeyValue = "b_key";
5364+
5365+
for (Function &F : M.getFunctionList()) {
5366+
if (F.isDeclaration())
5367+
continue;
5368+
5369+
if (SRA) {
5370+
SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
5371+
SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
5372+
} else {
5373+
if (auto A = F.getFnAttribute("sign-return-address");
5374+
A.isValid() && "none" == A.getValueAsString()) {
5375+
F.removeFnAttr("sign-return-address");
5376+
F.removeFnAttr("sign-return-address-key");
5377+
}
5378+
}
5379+
ConvertFunctionAttr(F, BTE, "branch-target-enforcement");
5380+
ConvertFunctionAttr(F, BPPLR, "branch-protection-pauth-lr");
5381+
ConvertFunctionAttr(F, GCS, "guarded-control-stack");
5382+
}
5383+
5384+
if (BTE)
5385+
M.setModuleFlag(llvm::Module::Min, "branch-target-enforcement", 2);
5386+
if (BPPLR)
5387+
M.setModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr", 2);
5388+
if (GCS)
5389+
M.setModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
5390+
if (SRA) {
5391+
M.setModuleFlag(llvm::Module::Min, "sign-return-address", 2);
5392+
if (isModuleAttributeOne(M, "sign-return-address-all"))
5393+
M.setModuleFlag(llvm::Module::Min, "sign-return-address-all", 2);
5394+
if (isModuleAttributeOne(M, "sign-return-address-with-bkey"))
5395+
M.setModuleFlag(llvm::Module::Min, "sign-return-address-with-bkey", 2);
5396+
}
5397+
}
5398+
52995399
static bool isOldLoopArgument(Metadata *MD) {
53005400
auto *T = dyn_cast_or_null<MDTuple>(MD);
53015401
if (!T)

llvm/lib/Linker/IRMover.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,11 @@ Error IRLinker::run() {
16081608
// Loop over all of the linked values to compute type mappings.
16091609
computeTypeMapping();
16101610

1611+
// Convert module level attributes to function level attributes because
1612+
// after merging modules the attributes might change and would have different
1613+
// effect on the functions as the original module would have.
1614+
CopyModuleAttrToFunctions(*SrcM);
1615+
16111616
std::reverse(Worklist.begin(), Worklist.end());
16121617
while (!Worklist.empty()) {
16131618
GlobalValue *GV = Worklist.back();
@@ -1772,6 +1777,11 @@ IRMover::IRMover(Module &M) : Composite(M) {
17721777
for (const auto *MD : StructTypes.getVisitedMetadata()) {
17731778
SharedMDs[MD].reset(const_cast<MDNode *>(MD));
17741779
}
1780+
1781+
// Convert module level attributes to function level attributes because
1782+
// after merging modules the attributes might change and would have different
1783+
// effect on the functions as the original module would have.
1784+
CopyModuleAttrToFunctions(M);
17751785
}
17761786

17771787
Error IRMover::move(std::unique_ptr<Module> Src,

llvm/lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ void ARMAsmPrinter::emitAttributes() {
793793

794794
auto *BTIValue = mdconst::extract_or_null<ConstantInt>(
795795
SourceModule->getModuleFlag("branch-target-enforcement"));
796-
if (BTIValue && BTIValue->isOne()) {
796+
if (BTIValue && !BTIValue->isZero()) {
797797
// If "+pacbti" is used as an architecture extension,
798798
// Tag_BTI_extension is emitted in
799799
// ARMTargetStreamer::emitTargetAttributes().

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ bool LowerTypeTestsModule::hasBranchTargetEnforcement() {
12111211
// the module flags.
12121212
if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
12131213
M.getModuleFlag("branch-target-enforcement")))
1214-
HasBranchTargetEnforcement = (BTE->getZExtValue() != 0);
1214+
HasBranchTargetEnforcement = !BTE->isZero();
12151215
else
12161216
HasBranchTargetEnforcement = 0;
12171217
}
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
;; Test that module flags "branch-target-enforcement" and "sign-return-address" can be upgraded to
2-
;; are upgraded from Error to Min.
1+
;; Test that module flags "branch-target-enforcement" and "sign-return-address"
2+
;; can be upgraded to are upgraded from Error to Min and the value is changed 2
3+
;; as the module is converted to the semantic.
34

45
; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
56

7+
target triple = "aarch64-unknown-linux-gnu"
8+
69
!llvm.module.flags = !{!0, !1, !2, !3}
710

811
!0 = !{i32 1, !"branch-target-enforcement", i32 1}
912
!1 = !{i32 1, !"sign-return-address", i32 1}
1013
!2 = !{i32 1, !"sign-return-address-all", i32 1}
1114
!3 = !{i32 1, !"sign-return-address-with-bkey", i32 1}
1215

13-
;CHECK: !0 = !{i32 8, !"branch-target-enforcement", i32 1}
14-
;CHECK: !1 = !{i32 8, !"sign-return-address", i32 1}
15-
;CHECK: !2 = !{i32 8, !"sign-return-address-all", i32 1}
16-
;CHECK: !3 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
16+
;CHECK: !0 = !{i32 8, !"branch-target-enforcement", i32 2}
17+
;CHECK: !1 = !{i32 8, !"sign-return-address", i32 2}
18+
;CHECK: !2 = !{i32 8, !"sign-return-address-all", i32 2}
19+
;CHECK: !3 = !{i32 8, !"sign-return-address-with-bkey", i32 2}

llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,5 @@ attributes #1 = { minsize nofree norecurse nounwind optsize "sign-return-address
9494
!llvm.module.flags = !{!0, !1, !2}
9595

9696
!0 = !{i32 8, !"branch-target-enforcement", i32 0}
97-
!1 = !{i32 8, !"sign-return-address", i32 1}
97+
!1 = !{i32 8, !"sign-return-address", i32 2}
9898
!2 = !{i32 8, !"sign-return-address-all", i32 0}

llvm/test/LTO/AArch64/Inputs/foo.ll

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; This file contains the new semantic of the branch-target-enforcement, sign-return-address.
2+
; Used for test mixing a mixed link case and also verify the import too in llc.
3+
4+
; RUN: llc %s -o - | FileCheck %s
5+
6+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
7+
target triple = "aarch64-unknown-linux-gnu"
8+
9+
define dso_local void @bar() #0 {
10+
entry:
11+
ret void
12+
}
13+
; CHECK-LABEL: bar:
14+
; CHECK-NOT: hint
15+
; CHECK-NOT: bti
16+
; CHECK: ret
17+
18+
define dso_local void @baz() #1 {
19+
entry:
20+
ret void
21+
}
22+
23+
; CHECK-LABEL: baz:
24+
; CHECK: hint
25+
; CHECK: ret
26+
27+
attributes #0 = { noinline nounwind optnone uwtable }
28+
attributes #1 = { noinline nounwind optnone uwtable "branch-target-enforcement" }
29+
30+
!llvm.module.flags = !{!0, !1, !2, !3}
31+
32+
!0 = !{i32 8, !"branch-target-enforcement", i32 2}
33+
!1 = !{i32 8, !"sign-return-address", i32 2}
34+
!2 = !{i32 8, !"sign-return-address-all", i32 2}
35+
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 2}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; This file contains the previous semantic of the branch-target-enforcement, sign-return-address.
2+
; Used for test mixing a mixed link case and also verify the import too in llc.
3+
4+
; RUN: llc %s -o - | FileCheck %s
5+
6+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
7+
target triple = "aarch64-unknown-linux-gnu"
8+
9+
define i32 @foo() #0 {
10+
entry:
11+
ret i32 42
12+
}
13+
14+
; CHECK-LABEL: foo:
15+
; CHECK: hint #27
16+
; CHECK: mov
17+
; CHECK: hint #31
18+
; CHECK: ret
19+
20+
define i32 @fiz() #1 {
21+
entry:
22+
ret i32 43
23+
}
24+
25+
; CHECK-LABEL: fiz:
26+
; CHECK-NOT: hint
27+
; CHECK-NOT: bti
28+
; CHECK: ret
29+
30+
attributes #0 = { noinline nounwind optnone uwtable }
31+
attributes #1 = { noinline nounwind optnone uwtable "branch-target-enforcement"="false" "sign-return-address"="none" }
32+
33+
!llvm.module.flags = !{!0, !1, !2, !3}
34+
35+
!0 = !{i32 8, !"branch-target-enforcement", i32 1}
36+
!1 = !{i32 8, !"sign-return-address", i32 1}
37+
!2 = !{i32 8, !"sign-return-address-all", i32 1}
38+
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 1}

0 commit comments

Comments
 (0)