[clang] [LTO] A static relocation model can override the PIC level wrt treating external address as directly accessible (PR #65512)

Wolfgang Pieb via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 6 11:28:15 PDT 2023


https://github.com/wolfy1961 created https://github.com/llvm/llvm-project/pull/65512:

As described in issue [#64999](https://github.com/llvm/llvm-project/issues/64999), commit [e018cbf7208](https://github.com/llvm/llvm-project/commit/e018cbf7208b3d34f18997ddee84c66cee32fb1b) caused the symbol __stack_chk_guard to not become dso_local when PIC is enabled in a module. However, during LTO we can force a static relocation model, which overrides the PIC level. In this case __stack_chk_guard should become dso_local.
For this purpose we're adding a boolean to the interface of getDirectAccessExternalData() to indicate the relocation model.

Fixes https://github.com/llvm/llvm-project/issues/64999

>From 6a176368c90183fc1744b73632746636fe46da42 Mon Sep 17 00:00:00 2001
From: wpieb <Wolfgang.Pieb at sony.com>
Date: Tue, 5 Sep 2023 10:43:23 -0700
Subject: [PATCH] [LTO] A static relocation model can override the PIC level
 wrt treating external address as directly accessible.

Fixes https://github.com/llvm/llvm-project/issues/64999
---
 clang/lib/CodeGen/CodeGenModule.cpp         |  5 +--
 llvm/include/llvm/IR/Module.h               |  2 +-
 llvm/lib/CodeGen/TargetLoweringBase.cpp     |  3 +-
 llvm/lib/IR/Module.cpp                      |  4 +--
 llvm/lib/Target/X86/X86ISelLoweringCall.cpp |  3 +-
 llvm/test/LTO/ARM/ssp-static-reloc.ll       | 38 +++++++++++++++++++++
 6 files changed, 48 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/LTO/ARM/ssp-static-reloc.ll

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 95f185f5824d8c..f0a10f5d294270 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1127,7 +1127,8 @@ void CodeGenModule::Release() {
   if (LangOpts.HLSL)
     getHLSLRuntime().finishCodeGen();
 
-  if (uint32_t PLevel = Context.getLangOpts().PICLevel) {
+  uint32_t PLevel = Context.getLangOpts().PICLevel;
+  if (PLevel) {
     assert(PLevel < 3 && "Invalid PIC Level");
     getModule().setPICLevel(static_cast<llvm::PICLevel::Level>(PLevel));
     if (Context.getLangOpts().PIE)
@@ -1152,7 +1153,7 @@ void CodeGenModule::Release() {
     getModule().setRtLibUseGOT();
   if (getTriple().isOSBinFormatELF() &&
       CodeGenOpts.DirectAccessExternalData !=
-          getModule().getDirectAccessExternalData()) {
+          getModule().getDirectAccessExternalData(PLevel == 0)) {
     getModule().setDirectAccessExternalData(
         CodeGenOpts.DirectAccessExternalData);
   }
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 670a40b28eabbe..bf2c41bb9c3e44 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -947,7 +947,7 @@ class LLVM_EXTERNAL_VISIBILITY Module {
 
   /// Get/set whether referencing global variables can use direct access
   /// relocations on ELF targets.
-  bool getDirectAccessExternalData() const;
+  bool getDirectAccessExternalData(bool IsStaticRelocModel) const;
   void setDirectAccessExternalData(bool Value);
 
   /// Get/set whether synthesized functions should get the uwtable attribute.
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 3e4bff5ddce126..e1f439fd32dad1 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -2016,7 +2016,8 @@ void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
                                   "__stack_chk_guard");
 
     // FreeBSD has "__stack_chk_guard" defined externally on libc.so
-    if (M.getDirectAccessExternalData() &&
+    if (M.getDirectAccessExternalData(TM.getRelocationModel() ==
+                                      Reloc::Static) &&
         !TM.getTargetTriple().isWindowsGNUEnvironment() &&
         !TM.getTargetTriple().isOSFreeBSD() &&
         !TM.getTargetTriple().isOSDarwin())
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 73354a8f36d215..8186f256007c48 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -672,12 +672,12 @@ void Module::setRtLibUseGOT() {
   addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
 }
 
-bool Module::getDirectAccessExternalData() const {
+bool Module::getDirectAccessExternalData(bool IsStaticRelocModel) const {
   auto *Val = cast_or_null<ConstantAsMetadata>(
       getModuleFlag("direct-access-external-data"));
   if (Val)
     return cast<ConstantInt>(Val->getValue())->getZExtValue() > 0;
-  return getPICLevel() == PICLevel::NotPIC;
+  return getPICLevel() == PICLevel::NotPIC || IsStaticRelocModel;
 }
 
 void Module::setDirectAccessExternalData(bool Value) {
diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
index 754d2042105e57..9eeb9bf682b1f4 100644
--- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
+++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp
@@ -606,7 +606,8 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
                                 nullptr, GuardSymb, nullptr,
                                 GlobalValue::NotThreadLocal, AddressSpace);
         if (!Subtarget.isTargetDarwin())
-          GV->setDSOLocal(M->getDirectAccessExternalData());
+          GV->setDSOLocal(M->getDirectAccessExternalData(
+              getTargetMachine().getRelocationModel() == Reloc::Static));
       }
       return GV;
     }
diff --git a/llvm/test/LTO/ARM/ssp-static-reloc.ll b/llvm/test/LTO/ARM/ssp-static-reloc.ll
new file mode 100644
index 00000000000000..3c8688d8e7b1c6
--- /dev/null
+++ b/llvm/test/LTO/ARM/ssp-static-reloc.ll
@@ -0,0 +1,38 @@
+; Check that we do not generate an extra indirection accessing the stack guard
+; variable, when the relocation model is static.
+;
+; RUN: llvm-as < %s > %t.bc
+; RUN: llvm-lto -O0 -relocation-model=static -o %t.o %t.bc
+; RUN: llvm-objdump -d -r %t.o | FileCheck %s
+
+target triple = "armv4t-unknown-unknown"
+
+define arm_aapcscc i8 @foo() #0 {
+entry:
+  %arr = alloca [200 x i8], align 1
+  call void @llvm.memset.p0.i32(ptr align 1 %arr, i8 0, i32 200, i1 false)
+  %arrayidx = getelementptr inbounds [200 x i8], ptr %arr, i32 0, i8 5
+  %0 = load i8, ptr %arrayidx, align 1
+  ret i8 %0
+}
+
+; CHECK:      <foo>:
+; CHECK:      [[#%x,CURPC:]]:{{.*}} ldr r[[REG1:[0-9]+]], [pc, #0x[[#%x,OFFSET:]]]
+; CHECK-NEXT: ldr r[[REG2:[0-9]+]], [r[[REG1]]]
+; CHECK-NEXT: str r[[REG2]],
+; CHECK:      [[#CURPC + OFFSET + 8]]:{{.*}}.word
+; CHECK-NEXT: R_ARM_ABS32 __stack_chk_guard
+
+declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)
+
+define arm_aapcscc i32 @main() {
+entry:
+  %call = call arm_aapcscc i8 @foo()
+  %conv = zext i8 %call to i32
+  ret i32 %conv
+}
+
+attributes #0 = { noinline nounwind optnone sspstrong }
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"PIC Level", i32 2}



More information about the cfe-commits mailing list