Skip to content

Commit e3c65cc

Browse files
[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.
1 parent e0596b2 commit e3c65cc

File tree

8 files changed

+111
-44
lines changed

8 files changed

+111
-44
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

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

11731173
if (T.isARM() || T.isThumb() || T.isAArch64()) {
1174+
// Previously 1 is used and meant for the backed to derive the function
1175+
// attribute form it. 2 now means function attributes already set for all
1176+
// functions in this module, so no need to propagate those from the module
1177+
// flag. Value is only used in case of LTO module merge because the backend
1178+
// will see all required function attribute set already. Value is used
1179+
// before modules got merged. Any posive value means the feature is active
1180+
// and required binary markings need to be emit accordingly.
11741181
if (LangOpts.BranchTargetEnforcement)
11751182
getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
1176-
1);
1183+
2);
11771184
if (LangOpts.BranchProtectionPAuthLR)
11781185
getModule().addModuleFlag(llvm::Module::Min, "branch-protection-pauth-lr",
1179-
1);
1186+
2);
11801187
if (LangOpts.GuardedControlStack)
1181-
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 1);
1188+
getModule().addModuleFlag(llvm::Module::Min, "guarded-control-stack", 2);
11821189
if (LangOpts.hasSignReturnAddress())
1183-
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 1);
1190+
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address", 2);
11841191
if (LangOpts.isSignReturnAddressScopeAll())
11851192
getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all",
1186-
1);
1193+
2);
11871194
if (!LangOpts.isSignReturnAddressWithAKey())
11881195
getModule().addModuleFlag(llvm::Module::Min,
1189-
"sign-return-address-with-bkey", 1);
1196+
"sign-return-address-with-bkey", 2);
11901197
}
11911198

11921199
if (CodeGenOpts.StackClashProtector)

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}

lld/test/ELF/lto/aarch64_inline.ll

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
; RUN: split-file %s %t
77
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -unified-lto %t/foo.s -o %t/foo.o
8+
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -unified-lto %t/bar.s -o %t/bar.o
89
; RUN: opt -thinlto-bc -thinlto-split-lto-unit -unified-lto %t/main.s -o %t/main.o
9-
; RUN: ld.lld -O2 --lto=thin --entry=main %t/main.o %t/foo.o -o %t/exe
10+
; RUN: ld.lld -O2 --lto=thin --entry=main %t/main.o %t/foo.o %t/bar.o -o %t/exe
1011
; RUN: llvm-objdump -d %t/exe | FileCheck %s
1112

1213

1314
; CHECK-LABEL: <main>:
1415
; CHECK-NEXT: pacibsp
15-
; CHECK-NEXT: mov w0, #0x22
16+
; CHECK-NEXT: mov w0, #0x23
1617
; CHECK-NEXT: autibsp
1718
; CHECK-NEXT: ret
1819

@@ -32,16 +33,35 @@ attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memor
3233
!2 = !{i32 8, !"sign-return-address-all", i32 1}
3334
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
3435

36+
;--- bar.s
37+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
38+
target triple = "aarch64-unknown-linux-gnu"
39+
40+
define dso_local noundef i32 @bar() local_unnamed_addr #0 {
41+
entry:
42+
ret i32 1
43+
}
44+
45+
attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) "branch-target-enforcement"="true" "sign-return-address"="all" "sign-return-address-key"="b_key" }
46+
!llvm.module.flags = !{!0, !1, !2, !3 }
47+
!0 = !{i32 8, !"branch-target-enforcement", i32 2}
48+
!1 = !{i32 8, !"sign-return-address", i32 2}
49+
!2 = !{i32 8, !"sign-return-address-all", i32 2}
50+
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 2}
51+
3552
;--- main.s
3653
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
3754
target triple = "aarch64-unknown-linux-gnu"
3855

3956
declare i32 @foo();
57+
declare i32 @bar();
4058

4159
define i32 @main() {
4260
entry:
4361
%1 = call i32 @foo()
44-
ret i32 %1
62+
%2 = call i32 @bar()
63+
%3 = add i32 %1, %2
64+
ret i32 %3
4565
}
4666

4767
!llvm.module.flags = !{!0, !1, !2, !3 }

llvm/lib/IR/AutoUpgrade.cpp

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5178,11 +5178,11 @@ void llvm::UpgradeFunctionAttributes(Function &F) {
51785178
Arg.removeAttrs(AttributeFuncs::typeIncompatible(Arg.getType()));
51795179
}
51805180

5181-
// Check if the module attribute is present and not zero.
5182-
static bool isModuleAttributeSet(Module &M, const StringRef &ModAttr) {
5181+
// Check if the module attribute is present and set to one.
5182+
static bool isModuleAttributeOne(Module &M, const StringRef &ModAttr) {
51835183
const auto *Attr =
51845184
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(ModAttr));
5185-
return Attr && !Attr->isZero();
5185+
return Attr && Attr->isOne();
51865186
}
51875187

51885188
// Check if the function attribute is not present and set it.
@@ -5197,31 +5197,36 @@ void llvm::CopyModuleAttrToFunctions(Module &M) {
51975197
if (!T.isThumb() && !T.isARM() && !T.isAArch64())
51985198
return;
51995199

5200-
StringRef SignTypeValue = "none";
5201-
if (isModuleAttributeSet(M, "sign-return-address-all"))
5200+
bool BTE = isModuleAttributeOne(M, "branch-target-enforcement");
5201+
bool BPPLR = isModuleAttributeOne(M, "branch-protection-pauth-lr");
5202+
bool GCS = isModuleAttributeOne(M, "guarded-control-stack");
5203+
bool SRA = isModuleAttributeOne(M, "sign-return-address");
5204+
5205+
if (!BTE && !BPPLR && !GCS && !SRA)
5206+
return;
5207+
5208+
StringRef SignTypeValue = "non-leaf";
5209+
if (SRA && isModuleAttributeOne(M, "sign-return-address-all"))
52025210
SignTypeValue = "all";
5203-
else if (isModuleAttributeSet(M, "sign-return-address"))
5204-
SignTypeValue = "non-leaf";
5205-
5206-
StringRef BTEValue =
5207-
isModuleAttributeSet(M, "branch-target-enforcement") ? "true" : "false";
5208-
StringRef BPPLValue =
5209-
isModuleAttributeSet(M, "branch-protection-pauth-lr") ? "true" : "false";
5210-
StringRef GCSValue =
5211-
isModuleAttributeSet(M, "guarded-control-stack") ? "true" : "false";
5212-
StringRef SignKeyValue =
5213-
isModuleAttributeSet(M, "sign-return-address-with-bkey") ? "b_key"
5214-
: "a_key";
5211+
5212+
StringRef SignKeyValue = "a_key";
5213+
if (SRA && isModuleAttributeOne(M, "sign-return-address-with-bkey"))
5214+
SignKeyValue = "b_key";
52155215

52165216
for (Function &F : M.getFunctionList()) {
52175217
if (F.isDeclaration())
52185218
continue;
52195219

5220-
SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
5221-
SetFunctionAttrIfNotSet(F, "branch-target-enforcement", BTEValue);
5222-
SetFunctionAttrIfNotSet(F, "branch-protection-pauth-lr", BPPLValue);
5223-
SetFunctionAttrIfNotSet(F, "guarded-control-stack", GCSValue);
5224-
SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
5220+
if (SRA) {
5221+
SetFunctionAttrIfNotSet(F, "sign-return-address", SignTypeValue);
5222+
SetFunctionAttrIfNotSet(F, "sign-return-address-key", SignKeyValue);
5223+
}
5224+
if (BTE)
5225+
SetFunctionAttrIfNotSet(F, "branch-target-enforcement", "true");
5226+
if (BPPLR)
5227+
SetFunctionAttrIfNotSet(F, "branch-protection-pauth-lr", "true");
5228+
if (GCS)
5229+
SetFunctionAttrIfNotSet(F, "guarded-control-stack", "true");
52255230
}
52265231
}
52275232

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
2+
target triple = "aarch64-unknown-linux-gnu"
3+
4+
define dso_local void @bar() #0 {
5+
entry:
6+
ret void
7+
}
8+
9+
define dso_local void @baz() #1 {
10+
entry:
11+
ret void
12+
}
13+
14+
attributes #0 = { noinline nounwind optnone uwtable }
15+
attributes #1 = { noinline nounwind optnone uwtable "branch-target-enforcement"="true" }
16+
17+
!llvm.module.flags = !{!0, !1, !2, !3}
18+
19+
!0 = !{i32 8, !"branch-target-enforcement", i32 2}
20+
!1 = !{i32 8, !"sign-return-address", i32 2}
21+
!2 = !{i32 8, !"sign-return-address-all", i32 2}
22+
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 2}

llvm/test/LTO/AArch64/link-sign-return-address.ll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
;
44
; RUN: llvm-as %s -o %t1.bc
55
; RUN: llvm-as %p/Inputs/foo.ll -o %t2.bc
6+
; RUN: llvm-as %p/Inputs/bar.ll -o %t3.bc
67
; RUN: llvm-lto -exported-symbol main \
78
; RUN: -exported-symbol foo \
89
; RUN: -filetype=obj \
9-
; RUN: %t2.bc %t1.bc \
10+
; RUN: %t3.bc %t2.bc %t1.bc \
1011
; RUN: -o %t1.exe 2>&1
1112
; RUN: llvm-objdump -d %t1.exe | FileCheck --check-prefix=CHECK-DUMP %s
1213
; 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"
1516
target triple = "aarch64-unknown-linux-gnu"
1617

1718
declare i32 @foo();
19+
declare void @baz();
20+
declare void @bar();
1821

1922
define i32 @main() {
2023
entry:
2124
%add = call i32 @foo()
25+
call void @bar()
26+
call void @baz()
2227
ret i32 %add
2328
}
2429

@@ -28,6 +33,12 @@ entry:
2833
!2 = !{i32 8, !"sign-return-address-all", i32 0}
2934
!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
3035

36+
37+
; CHECK-DUMP: <bar>:
38+
; CHECK-DUMP: ret
39+
; CHECK-DUMP: <baz>:
40+
; CHECK-DUMP: bti c
41+
; CHECK-DUMP: ret
3142
; CHECK-DUMP: <foo>:
3243
; CHECK-DUMP: pacibsp
3344
; CHECK-DUMP: mov w0, #0x2a
@@ -36,7 +47,9 @@ entry:
3647
; CHECK-DUMP: <main>:
3748
; CHECK-DUMP-NOT: paciasp
3849
; CHECK-DUMP: str x30,
39-
; CHECK-DUMP: bl 0x14 <main+0x4>
50+
; CHECK-DUMP: bl 0x20 <main+0x4>
51+
; CHECK-DUMP: bl 0x0 <bar>
52+
; CHECK-DUMP: bl 0x4 <baz>
4053

4154
; `main` doesn't support PAC sign-return-address while `foo` does, so in the binary
4255
; we should not see anything.

0 commit comments

Comments
 (0)