Skip to content

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