[llvm] [DirectX] Remove unused heap resources (PR #218093)

Helena Kotas via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 21:02:04 PDT 2026


https://github.com/hekota created https://github.com/llvm/llvm-project/pull/218093

Add handling of `llvm.dx.resource.handlefromheap` to `DXILRemoveUnusedResources` pass. In practice heap resources are usually assigned to local variables, and get cleaned up in earlier passes if unused. If that does not happen for some reason, they get removed by `DXILRemoveUnusedResources`.

Related to #208053

>From fec2c7cf34e629a7aa5382d23bf290424d2a8525 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Fri, 21 Aug 2026 15:53:58 -0700
Subject: [PATCH] [DirectX] Remove unused heap resources

Add handling of `llvm.dx.resource.handlefromheap` to `DXILRemoveUnusedResources` pass and add tests.

Related to #208053
---
 .../DirectX/DXILRemoveUnusedResources.cpp      | 18 +++++++++++-------
 llvm/test/CodeGen/DirectX/unused-resources.ll  |  6 ++++++
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
index aa05f58336752..80d5d54c55171 100644
--- a/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
+++ b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
@@ -33,7 +33,13 @@ static llvm::cl::opt<bool> DisableDXILRemoveUnusedResources(
 
 using namespace llvm;
 
-// Removes all calls to intrinsics dx_resource_handlefrom{implicit}binding that
+static bool isResourceHandleCreation(Intrinsic::ID ID) {
+  return ID == Intrinsic::dx_resource_handlefrombinding ||
+         ID == Intrinsic::dx_resource_handlefromimplicitbinding ||
+         ID == Intrinsic::dx_resource_handlefromheap;
+}
+
+// Removes all calls to resource handle creation intrinsics that
 // either are not used, or their only use is in a store instruction, which
 // stores the initialized handle into a global variable that does not have
 // external linkage and that is not used anywhere else in the module.
@@ -46,9 +52,7 @@ static bool removeUnusedResources(Function &F) {
   for (BasicBlock &BB : make_early_inc_range(F)) {
     for (Instruction &I : BB) {
       if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
-        if (II->getIntrinsicID() != Intrinsic::dx_resource_handlefrombinding &&
-            II->getIntrinsicID() !=
-                Intrinsic::dx_resource_handlefromimplicitbinding)
+        if (!isResourceHandleCreation(II->getIntrinsicID()))
           continue;
         if (II->user_empty()) {
           // Initialized handle is not used anywhere.
@@ -87,9 +91,9 @@ static bool removeUnusedResources(Function &F) {
 
   for (auto *Instr : DeadInstr) {
     if (auto *II = dyn_cast<IntrinsicInst>(Instr)) {
-      assert(II->getIntrinsicID() == Intrinsic::dx_resource_handlefrombinding ||
-             II->getIntrinsicID() ==
-                 Intrinsic::dx_resource_handlefromimplicitbinding);
+      assert(isResourceHandleCreation(II->getIntrinsicID()));
+      if (II->getIntrinsicID() == Intrinsic::dx_resource_handlefromheap)
+        continue;
       const unsigned ResourceNameOpIndex = 4;
       GlobalVariable *ResourceName = dyn_cast_or_null<GlobalVariable>(
           II->getArgOperand(ResourceNameOpIndex));
diff --git a/llvm/test/CodeGen/DirectX/unused-resources.ll b/llvm/test/CodeGen/DirectX/unused-resources.ll
index b11638cec0f9a..ae9d5651a78ee 100644
--- a/llvm/test/CodeGen/DirectX/unused-resources.ll
+++ b/llvm/test/CodeGen/DirectX/unused-resources.ll
@@ -7,6 +7,7 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 ; - unused resource initialization calls
 ; - unused cbuffers and associated global variables
 ; - resource name strings
+; - unused resource handles created from the descriptor heap
 
 %__cblayout_CB = type <{ i32, float }>
 %"__cblayout_$Globals" = type <{ i32, float }>
@@ -37,6 +38,10 @@ entry:
             @llvm.dx.resource.handlefrombinding(i32 0, i32 6, i32 1, i32 0, ptr @Buf.str)
   store target("dx.RawBuffer", i16, 1, 0) %uav_handle, ptr @_ZL3Buf, align 4
 
+; Heap resource
+  %heap_handle = call target("dx.RawBuffer", i16, 1, 0)
+            @llvm.dx.resource.handlefromheap(i32 0)
+
   ret void
 }
 
@@ -55,6 +60,7 @@ entry:
 ; CHECK-NOT: @Buf.str  
 ; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefrombinding
 ; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefromimplicitbinding
+; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefromheap
 
 ; Make sure the resource bindings table is empty
 ; CHECK-PRINT: ; Resource Bindings:



More information about the llvm-commits mailing list