[llvm] [TargetLowering][COFF] Only check shouldAssumeDSOLocal on GlobalVariable in lowerRelativeReference (PR #225160)

Andy Lim via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 21 12:54:23 PDT 2026


https://github.com/andysjlim updated https://github.com/llvm/llvm-project/pull/225160

>From 7c0284c794d99f00384ed7a9c6b95306e9356de4 Mon Sep 17 00:00:00 2001
From: Andrew Lim <andysjlim at chromium.org>
Date: Mon, 21 Sep 2026 17:37:01 +0000
Subject: [PATCH] [TargetLowering][COFF] Only check shouldAssumeDSOLocal on
 GlobalVariable in lowerRelativeReference

In #220674, a check was added to lowerRelativeReference requiring that
LHS be dso_local to prevent image-relative relocations for dllimport variables.
However, this check was applied unconditionally to all GlobalObjects,
including Functions.

On Windows COFF, dllimport functions are valid targets for image-relative
relocations because the linker provides import thunks in the local image.
In particular, MSVC C++ exception handling metadata (ThrowInfo and
CatchableType) references imported copy constructors and destructors via
image-relative offsets when throwing exception types across DLL boundaries.
Rejecting them caused compilation failures in downstream projects like
PyTorch with:
  "error: symbol '__ImageBase' can not be undefined in a subtraction expression"

Restrict the shouldAssumeDSOLocal check to GlobalVariables only.
---
 .../CodeGen/TargetLoweringObjectFileImpl.cpp  | 22 +++++++++++++------
 llvm/test/MC/COFF/ir-to-imgrel.ll             |  2 +-
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 2756ea19fb7f65..ee236a6ea0f80a 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2123,16 +2123,24 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
                               : dyn_cast<GlobalObject>(LHS);
 
   // Both ptrtoint instructions must wrap global objects:
-  // - Only dso_local global variables/functions (or direct aliases thereof) are
-  //   eligible for image relative relocations.
+  // - Only global variables that are dso_local are eligible for image relative
+  //   relocations.
+  // - FIXME: Referring to a dllimport function produces an image-relative
+  //   relocation against the local import thunk rather than the canonical
+  //   function pointer, which lacks program-wide pointer identity. This is
+  //   sufficient for use cases like MSVC exception handling metadata (where the
+  //   function is only invoked), but is not theoretically sound in general.
+  //   We probably need something like dso_local_equivalent to explicitly
+  //   request a callable local entry point.
   // - The subtrahend refers to the special symbol __ImageBase, a
-  // GlobalVariable. We expect __ImageBase to be a global variable without a
-  // section, externally defined.
+  //   GlobalVariable. We expect __ImageBase to be a global variable without a
+  //   section, externally defined.
   //
   // It should look something like this: @__ImageBase = external constant i8
-  if (!GO || !TM.shouldAssumeDSOLocal(LHS) || GO->isThreadLocal() ||
-      !isa<GlobalVariable>(RHS) || RHS->isThreadLocal() ||
-      RHS->getName() != "__ImageBase" || !RHS->hasExternalLinkage() ||
+  if (!GO || (isa<GlobalVariable>(GO) && !TM.shouldAssumeDSOLocal(LHS)) ||
+      GO->isThreadLocal() || !isa<GlobalVariable>(RHS) ||
+      RHS->isThreadLocal() || RHS->getName() != "__ImageBase" ||
+      !RHS->hasExternalLinkage() ||
       cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection())
     return nullptr;
 
diff --git a/llvm/test/MC/COFF/ir-to-imgrel.ll b/llvm/test/MC/COFF/ir-to-imgrel.ll
index 7c313933071d84..576be50793bfec 100644
--- a/llvm/test/MC/COFF/ir-to-imgrel.ll
+++ b/llvm/test/MC/COFF/ir-to-imgrel.ll
@@ -8,7 +8,7 @@
 ; RELOC: IMAGE_REL_AMD64_ADDR32NB ?x@@3HA
 @"\01?x@@3HA" = global i32 trunc (i64 sub nsw (i64 ptrtoint (ptr @"\01?x@@3HA" to i64), i64 ptrtoint (ptr @__ImageBase to i64)) to i32), align 4
 
-declare void @f()
+declare dllimport void @f()
 
 ; X64: .long   f at IMGREL
 ; RELOC: IMAGE_REL_AMD64_ADDR32NB f



More information about the llvm-commits mailing list