From 5ea7949caf0cdd447fd950196b48397d6f573a27 Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Wed, 11 Dec 2024 09:06:04 +0100 Subject: [PATCH] Prevent local optimizations of definitions In case of weak definitions, JITLink might merge symbols because we currently add all llvm::Module's into a single JITDylib. For merges that late in the pipeline, we also have to prevent optimizations that take advantage of "localness" to avoid out-of-range relocations for example on AArch64. --- lib/Interpreter/BackendPasses.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/Interpreter/BackendPasses.cpp b/lib/Interpreter/BackendPasses.cpp index 0271f526e0..fac174258b 100644 --- a/lib/Interpreter/BackendPasses.cpp +++ b/lib/Interpreter/BackendPasses.cpp @@ -151,19 +151,24 @@ namespace { namespace { class PreventLocalOptPass : public PassInfoMixin { bool runOnGlobal(GlobalValue& GV) { - if (!GV.isDeclaration()) - return false; // no change. - - // GV is a declaration with no definition. Make sure to prevent any - // optimization that tries to take advantage of the actual definition - // being "local" because we have no influence on the memory layout of - // data sections and how "close" they are to the code. - bool changed = false; + // Prevent any optimization that tries to take advantage of the actual + // definition being "local" because we have no influence on the memory + // layout of sections and how "close" they are. + if (GV.hasLocalLinkage()) { - GV.setLinkage(llvm::GlobalValue::ExternalLinkage); - changed = true; + if (GV.isDeclaration()) { + // For declarations with no definition, we can simply adjust the + // linkage. + GV.setLinkage(llvm::GlobalValue::ExternalLinkage); + changed = true; + } else { + // FIXME: Not clear what would be the right linkage. We also cannot + // continue because "GlobalValue with local linkage [...] must be + // dso_local!" + return false; + } } if (!GV.hasDefaultVisibility()) { @@ -172,7 +177,7 @@ namespace { } // Set DSO locality last because setLinkage() and setVisibility() check - // isImplicitDSOLocal(). + // isImplicitDSOLocal() and then might call setDSOLocal(true). if (GV.isDSOLocal()) { GV.setDSOLocal(false); changed = true;