Skip to content

[DirectX] Convert private global variables to internal linkage during Finalize Linkage pass #146406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 7, 2025

Conversation

kmpeng
Copy link
Contributor

@kmpeng kmpeng commented Jun 30, 2025

Fixes #140420. The switch.table.* validation errors were caused by DXIL not supporting private global variables. Converting them to internal linkage fixes the bug.

May need more discussion on the preserved analyses/a follow-up PR that fixes what this pass says it preserves.

@llvmbot
Copy link
Member

llvmbot commented Jun 30, 2025

@llvm/pr-subscribers-backend-directx

Author: Kaitlin Peng (kmpeng)

Changes

Fixes #140420. The switch.table.* validation errors were caused by DXIL not supporting private global variables. Converting them to internal linkage fixes the bug.

May need more discussion on the preserved analyses/a follow-up PR that fixes what this pass says it preserves.


Full diff: https://github.com/llvm/llvm-project/pull/146406.diff

1 Files Affected:

  • (modified) llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp (+17-3)
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index 94b2dbe78c4f7..5f331dbd2d826 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -18,6 +18,16 @@
 using namespace llvm;
 
 static bool finalizeLinkage(Module &M) {
+  bool MadeChange = false;
+
+  // Convert private global variables to internal linkage.
+  for (GlobalVariable &GV : M.globals()) {
+    if (GV.hasPrivateLinkage()) {
+      GV.setLinkage(GlobalValue::InternalLinkage);
+      MadeChange = true;
+    }
+  }
+
   SmallVector<Function *> Funcs;
 
   // Collect non-entry and non-exported functions to set to internal linkage.
@@ -32,13 +42,17 @@ static bool finalizeLinkage(Module &M) {
   }
 
   for (Function *F : Funcs) {
-    if (F->getLinkage() == GlobalValue::ExternalLinkage)
+    if (F->getLinkage() == GlobalValue::ExternalLinkage) {
       F->setLinkage(GlobalValue::InternalLinkage);
-    if (F->isDefTriviallyDead())
+      MadeChange = true;
+    }
+    if (F->isDefTriviallyDead()) {
       M.getFunctionList().erase(F);
+      MadeChange = true;
+    }
   }
 
-  return false;
+  return MadeChange;
 }
 
 PreservedAnalyses DXILFinalizeLinkage::run(Module &M,

Comment on lines +25 to +28
if (GV.hasPrivateLinkage()) {
GV.setLinkage(GlobalValue::InternalLinkage);
MadeChange = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be removing these if GV.use_empty() to match what we do with functions? Alternatively, if we don't expect to ever get here with unused private globals, can we assert(!GV.use_empty()) here? Or is it okay/expected for us to leave unused internal variables around?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats the solution we worked for this ticket #139023. My understanding was though we didn't want to blanket do this because of external linkage. so, I suppose we could do something like

if(GV.use_empty() && !GV.hasExtenalLinkage())
    ToErase.push_back(&G);

Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this change. I beleive Justin's concerns can be addressed when we put up a pr for #139023

@kmpeng kmpeng merged commit dc8e89b into llvm:main Jul 7, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DirectX] External declaration 'switch.table.*' is unused
5 participants