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 @@ -908,6 +908,12 @@ if (CodeGenOpts.NoPLT) getModule().setRtLibUseGOT(); + if (getTriple().isOSBinFormatELF() && + CodeGenOpts.DirectAccessExternalData != + getModule().getDirectAccessExternalData()) { + getModule().setDirectAccessExternalData( + CodeGenOpts.DirectAccessExternalData); + } if (CodeGenOpts.UnwindTables) getModule().setUwtable(llvm::UWTableKind(CodeGenOpts.UnwindTables)); diff --git a/clang/test/CodeGen/dso-local-executable.c b/clang/test/CodeGen/dso-local-executable.c --- a/clang/test/CodeGen/dso-local-executable.c +++ b/clang/test/CodeGen/dso-local-executable.c @@ -36,6 +36,8 @@ // STATIC-DAG: define dso_local ptr @zed() // STATIC-DAG: declare dso_local void @import_func() +// STATIC-NOT: !"direct-access-external-data" + /// If -fno-direct-access-external-data is set, drop dso_local from global variable /// declarations. // RUN: %clang_cc1 -triple x86_64 -emit-llvm %s -mrelocation-model static -fno-direct-access-external-data -o - | FileCheck --check-prefix=STATIC-INDIRECT %s @@ -49,6 +51,8 @@ // STATIC-INDIRECT-DAG: define dso_local ptr @zed() // STATIC-INDIRECT-DAG: declare void @foo() +// STATIC-INDIRECT: ![[#]] = !{i32 7, !"direct-access-external-data", i32 0} + // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck --check-prefix=PIE %s // PIE: @baz = dso_local global i32 42 // PIE-NEXT: @import_var = external global i32 @@ -60,6 +64,8 @@ // PIE-DAG: define dso_local ptr @zed() // PIE-DAG: declare void @import_func() +// PIE-NOT: !"direct-access-external-data" + // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT %s // PIE-DIRECT: @baz = dso_local global i32 42 // PIE-DIRECT-NEXT: @import_var = external dso_local global i32 @@ -71,6 +77,8 @@ // PIE-DIRECT-DAG: define dso_local ptr @zed() // PIE-DIRECT-DAG: declare void @import_func() +// PIE-DIRECT: ![[#]] = !{i32 7, !"direct-access-external-data", i32 1} + // RUN: %clang_cc1 -triple x86_64 -emit-llvm -mrelocation-model static -fno-plt %s -o - | FileCheck --check-prefix=NOPLT %s // NOPLT: @baz = dso_local global i32 42 // NOPLT-NEXT: @import_var = external dso_local global i32 diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -945,6 +945,11 @@ /// Set that PLT should be avoid for RTLib calls. void setRtLibUseGOT(); + /// Get/set whether referencing global variables can use direct access + /// relocations on ELF targets. + bool getDirectAccessExternalData() const; + void setDirectAccessExternalData(bool Value); + /// Get/set whether synthesized functions should get the uwtable attribute. UWTableKind getUwtable() const; void setUwtable(UWTableKind Kind); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1977,7 +1977,7 @@ "__stack_chk_guard"); // FreeBSD has "__stack_chk_guard" defined externally on libc.so - if (TM.getRelocationModel() == Reloc::Static && + if (M.getDirectAccessExternalData() && !TM.getTargetTriple().isWindowsGNUEnvironment() && !TM.getTargetTriple().isOSFreeBSD()) GV->setDSOLocal(true); diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -672,6 +672,17 @@ addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1); } +bool Module::getDirectAccessExternalData() const { + auto *Val = cast_or_null(getModuleFlag("direct-access-external-data")); + if (Val) + return cast(Val->getValue())->getZExtValue() > 0; + return getPICLevel() == PICLevel::NotPIC; +} + +void Module::setDirectAccessExternalData(bool Value) { + addModuleFlag(ModFlagBehavior::Max, "direct-access-external-data", Value); +} + UWTableKind Module::getUwtable() const { if (auto *Val = cast_or_null(getModuleFlag("uwtable"))) return UWTableKind(cast(Val->getValue())->getZExtValue()); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -3074,6 +3074,7 @@ GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GuardSymb, nullptr, GlobalValue::NotThreadLocal, AddressSpace); + GV->setDSOLocal(M->getDirectAccessExternalData()); } return GV; } diff --git a/llvm/test/CodeGen/AArch64/arm64_32.ll b/llvm/test/CodeGen/AArch64/arm64_32.ll --- a/llvm/test/CodeGen/AArch64/arm64_32.ll +++ b/llvm/test/CodeGen/AArch64/arm64_32.ll @@ -759,3 +759,6 @@ } declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1) + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/AArch64/stack-guard-sve.ll b/llvm/test/CodeGen/AArch64/stack-guard-sve.ll --- a/llvm/test/CodeGen/AArch64/stack-guard-sve.ll +++ b/llvm/test/CodeGen/AArch64/stack-guard-sve.ll @@ -337,3 +337,6 @@ attributes #0 = { ssp "frame-pointer"="non-leaf" } attributes #1 = { sspstrong "frame-pointer"="non-leaf" } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"direct-access-external-data", i32 1} diff --git a/llvm/test/CodeGen/AArch64/stack-guard-vaarg.ll b/llvm/test/CodeGen/AArch64/stack-guard-vaarg.ll --- a/llvm/test/CodeGen/AArch64/stack-guard-vaarg.ll +++ b/llvm/test/CodeGen/AArch64/stack-guard-vaarg.ll @@ -36,3 +36,6 @@ declare void @llvm.lifetime.end(i64, ptr nocapture) attributes #0 = { noinline nounwind optnone ssp } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"direct-access-external-data", i32 1} diff --git a/llvm/test/CodeGen/AArch64/stack_guard_remat.ll b/llvm/test/CodeGen/AArch64/stack_guard_remat.ll --- a/llvm/test/CodeGen/AArch64/stack_guard_remat.ll +++ b/llvm/test/CodeGen/AArch64/stack_guard_remat.ll @@ -1,14 +1,16 @@ -; RUN: llc < %s -mtriple=arm64-apple-ios -relocation-model=pic -no-integrated-as | FileCheck %s -check-prefix=DARWIN -; RUN: llc < %s -mtriple=arm64-apple-ios -relocation-model=static -no-integrated-as | FileCheck %s -check-prefix=DARWIN -; RUN: llc < %s -mtriple=aarch64-linux-gnu -relocation-model=pic -no-integrated-as | FileCheck %s -check-prefix=PIC-LINUX -; RUN: llc < %s -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as | FileCheck %s -check-prefix=STATIC-LARGE -; RUN: llc < %s -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as | FileCheck %s -check-prefix=STATIC-SMALL +; RUN: rm -rf %t && split-file %s %t && cd %t +; RUN: cat a.ll pic.ll > b.ll +; RUN: llc < b.ll -mtriple=arm64-apple-ios -relocation-model=pic -no-integrated-as | FileCheck %s -check-prefix=DARWIN +; RUN: llc < b.ll -mtriple=arm64-apple-ios -relocation-model=static -no-integrated-as | FileCheck %s -check-prefix=DARWIN +; RUN: llc < b.ll -mtriple=aarch64-linux-gnu -relocation-model=pic -no-integrated-as | FileCheck %s -check-prefix=PIC-LINUX +; RUN: llc < a.ll -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as | FileCheck %s -check-prefix=STATIC-LARGE +; RUN: llc < a.ll -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as | FileCheck %s -check-prefix=STATIC-SMALL -; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK -; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=static -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK -; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=PIC-LINUX,FALLBACK -; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-LARGE,FALLBACK -; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-SMALL,FALLBACK +; RUN: llc < b.ll -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK +; RUN: llc < b.ll -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-apple-ios -relocation-model=static -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=DARWIN,FALLBACK +; RUN: llc < b.ll -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=pic -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=PIC-LINUX,FALLBACK +; RUN: llc < a.ll -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=large -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-LARGE,FALLBACK +; RUN: llc < a.ll -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=aarch64-linux-gnu -relocation-model=static -code-model=small -no-integrated-as 2>&1 | FileCheck %s -check-prefixes=STATIC-SMALL,FALLBACK ; DARWIN: foo2 ; DARWIN: adrp [[R0:x[0-9]+]], ___stack_chk_guard@GOTPAGE @@ -33,6 +35,7 @@ ; FALLBACK-NOT: remark:{{.*}}llvm.lifetime.end ; FALLBACK-NOT: remark:{{.*}}llvm.lifetime.start +;--- a.ll define i32 @test_stack_guard_remat() #0 { entry: %a1 = alloca [256 x i32], align 4 @@ -52,3 +55,7 @@ declare void @llvm.lifetime.end.p0(i64, ptr nocapture) attributes #0 = { nounwind sspstrong "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +;--- pic.ll +!llvm.module.flags = !{!0} +!0 = !{i32 8, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/ARM/expand-pseudos.ll b/llvm/test/CodeGen/ARM/expand-pseudos.ll --- a/llvm/test/CodeGen/ARM/expand-pseudos.ll +++ b/llvm/test/CodeGen/ARM/expand-pseudos.ll @@ -28,3 +28,6 @@ } attributes #0 = { ssp } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/ARM/stack-guard-rwpi.ll b/llvm/test/CodeGen/ARM/stack-guard-rwpi.ll --- a/llvm/test/CodeGen/ARM/stack-guard-rwpi.ll +++ b/llvm/test/CodeGen/ARM/stack-guard-rwpi.ll @@ -26,3 +26,6 @@ } declare dso_local i32 @baz(ptr) + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/ARM/stack_guard_remat.ll b/llvm/test/CodeGen/ARM/stack_guard_remat.ll --- a/llvm/test/CodeGen/ARM/stack_guard_remat.ll +++ b/llvm/test/CodeGen/ARM/stack_guard_remat.ll @@ -66,3 +66,6 @@ declare void @llvm.lifetime.end.p0(i64, ptr nocapture) attributes #0 = { nounwind ssp "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/Inputs/stack-guard-reassign.ll b/llvm/test/CodeGen/Inputs/stack-guard-reassign.ll --- a/llvm/test/CodeGen/Inputs/stack-guard-reassign.ll +++ b/llvm/test/CodeGen/Inputs/stack-guard-reassign.ll @@ -19,3 +19,6 @@ declare i32 @puts(i8*) attributes #0 = { noinline nounwind optnone ssp } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"direct-access-external-data", i32 1} diff --git a/llvm/test/CodeGen/PowerPC/stack-guard-oob.ll b/llvm/test/CodeGen/PowerPC/stack-guard-oob.ll --- a/llvm/test/CodeGen/PowerPC/stack-guard-oob.ll +++ b/llvm/test/CodeGen/PowerPC/stack-guard-oob.ll @@ -419,3 +419,6 @@ } attributes #0 = { sspstrong } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"direct-access-external-data", i32 1} diff --git a/llvm/test/CodeGen/Thumb/stack_guard_remat.ll b/llvm/test/CodeGen/Thumb/stack_guard_remat.ll --- a/llvm/test/CodeGen/Thumb/stack_guard_remat.ll +++ b/llvm/test/CodeGen/Thumb/stack_guard_remat.ll @@ -57,3 +57,6 @@ declare void @llvm.lifetime.end.p0(i64, ptr nocapture) attributes #0 = { nounwind ssp "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/Thumb2/stack_guard_remat.ll b/llvm/test/CodeGen/Thumb2/stack_guard_remat.ll --- a/llvm/test/CodeGen/Thumb2/stack_guard_remat.ll +++ b/llvm/test/CodeGen/Thumb2/stack_guard_remat.ll @@ -39,3 +39,6 @@ declare void @llvm.lifetime.end.p0(i64, ptr nocapture) attributes #0 = { nounwind ssp "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll --- a/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll +++ b/llvm/test/CodeGen/X86/2009-04-14-IllegalRegs.ll @@ -81,3 +81,6 @@ } declare i32 @f(ptr byval(%struct.X) align 4, ptr byval(%struct.X) align 4) nounwind ssp + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"PIC Level", i32 2} diff --git a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll --- a/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll +++ b/llvm/test/CodeGen/X86/2010-09-17-SideEffectsInChain.ll @@ -49,3 +49,6 @@ store i8 %e, ptr %c, align 8 ret i32 0 } + +!llvm.module.flags = !{!0} +!0 = !{i32 7, !"direct-access-external-data", i32 1} diff --git a/llvm/test/CodeGen/X86/stack-protector-3.ll b/llvm/test/CodeGen/X86/stack-protector-3.ll --- a/llvm/test/CodeGen/X86/stack-protector-3.ll +++ b/llvm/test/CodeGen/X86/stack-protector-3.ll @@ -7,7 +7,8 @@ ; RUN: cat %t/main.ll %t/f.ll > %t/f2.ll ; RUN: cat %t/main.ll %t/g.ll > %t/g2.ll ; RUN: cat %t/main.ll %t/h.ll > %t/h2.ll -; RUN: cat %t/existedGV.ll %t/main.ll %t/h.ll > %t/i2.ll +; RUN: cat %t/existedGV.ll %t/main.ll %t/h.ll > %t/h3.ll +; RUN: cat %t/main.ll %t/i.ll > %t/i2.ll ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/a2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/b2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/c2.ll | FileCheck --check-prefix=CHECK-GLOBAL %s @@ -16,7 +17,8 @@ ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/f2.ll | FileCheck --check-prefix=CHECK-OFFSET %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/g2.ll | FileCheck --check-prefix=CHECK-NEGATIVE-OFFSET %s ; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/h2.ll | FileCheck --check-prefix=CHECK-SYM %s -; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/i2.ll | FileCheck --check-prefix=CHECK-SYMGV %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/h3.ll | FileCheck --check-prefix=CHECK-SYMGV %s +; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/i2.ll | FileCheck --check-prefix=CHECK-SYM2 %s ; CHECK-TLS-FS-40: movq %fs:40, %rax ; CHECK-TLS-FS-40: movq %fs:40, %rax @@ -77,6 +79,15 @@ ; CHECK-SYMGV-NEXT: .cfi_def_cfa_offset 32 ; CHECK-SYMGV-NEXT: callq __stack_chk_fail +; CHECK-SYM2: movq %fs:__woof(%rip), %rax +; CHECK-SYM2-NEXT: movq %rax, 16(%rsp) +; CHECK-SYM2: movq %fs:__woof(%rip), %rax +; CHECK-SYM2-NEXT: cmpq 16(%rsp), %rax +; CHECK-SYM2-NEXT: jne .LBB0_2 +; CHECK-SYM2: .LBB0_2: +; CHECK-SYM2-NEXT: .cfi_def_cfa_offset 32 +; CHECK-SYM2-NEXT: callq __stack_chk_fai + ; ModuleID = 't.c' ;--- existedGV.ll @@ -116,7 +127,8 @@ !llvm.module.flags = !{!1} !1 = !{i32 2, !"stack-protector-guard", !"tls"} ;--- c.ll -!llvm.module.flags = !{!1} +!llvm.module.flags = !{!0,!1} +!0 = !{i32 7, !"direct-access-external-data", i32 1} !1 = !{i32 2, !"stack-protector-guard", !"global"} ;--- d.ll !llvm.module.flags = !{!1} @@ -131,5 +143,10 @@ !llvm.module.flags = !{!1} !1 = !{i32 2, !"stack-protector-guard-offset", i32 -20} ;--- h.ll -!llvm.module.flags = !{!1} +!llvm.module.flags = !{!0,!1} +!0 = !{i32 7, !"direct-access-external-data", i32 0} +!1 = !{i32 2, !"stack-protector-guard-symbol", !"__woof"} +;--- i.ll +!llvm.module.flags = !{!0,!1} +!0 = !{i32 7, !"direct-access-external-data", i32 1} !1 = !{i32 2, !"stack-protector-guard-symbol", !"__woof"}