diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 68e8e93e5b77..f8d39e40b6c9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -449,7 +449,24 @@ static bool shouldAssumeDSOLocal(const CIRGenModule &CGM, return false; if (CGOpts.DirectAccessExternalData) { - llvm_unreachable("-fdirect-access-external-data not supported"); + // If -fdirect-access-external-data (default for -fno-pic), set dso_local + // for non-thread-local variables. If the symbol is not defined in the + // executable, a copy relocation will be needed at link time. dso_local is + // excluded for thread-local variables because they generally don't support + // copy relocations. + if (auto gv = dyn_cast(GV.getOperation())) + if (!gv.getTlsModelAttr()) + return true; + + // -fno-pic sets dso_local on a function declaration to allow direct + // accesses when taking its address (similar to a data symbol). If the + // function is not defined in the executable, a canonical PLT entry will be + // needed at link time. -fno-direct-access-external-data can avoid the + // canonical PLT entry. We don't generalize this condition to -fpie/-fpic as + // it could just cause trouble without providing perceptible benefits. + if (isa(GV) && !CGOpts.NoPLT && + RM == llvm::Reloc::Static) + return true; } // If we can use copy relocations we can assume it is local. diff --git a/clang/test/CIR/CodeGen/no-pie.c b/clang/test/CIR/CodeGen/no-pie.c new file mode 100644 index 000000000000..c0ffd9790392 --- /dev/null +++ b/clang/test/CIR/CodeGen/no-pie.c @@ -0,0 +1,11 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -fno-PIE -S -Xclang -emit-cir %s -o %t1.cir +// RUN: FileCheck --input-file=%t1.cir %s -check-prefix=CIR +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -fno-PIE -S -Xclang -emit-llvm %s -o %t1.ll +// RUN: FileCheck --input-file=%t1.ll %s -check-prefix=LLVM + +extern int var; +int get() { + return var; +} +// CIR: cir.global "private" external dsolocal @var : !s32i {alignment = 4 : i64} +// LLVM: @var = external dso_local global i32 \ No newline at end of file