[llvm-branch-commits] [llvm] [DirectX] Add DXILRemoveUnusedResources pass (PR #200965)

Helena Kotas via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jun 5 17:02:49 PDT 2026


https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/200965

>From 6e438402b83f6d4a8fed8fc0bbc2b7957021fadc Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 1 Jun 2026 14:56:56 -0700
Subject: [PATCH 1/2] [DirectX] Add pass that removes unused
 resources-in-unused-function.ll

Fixes #192524
---
 llvm/lib/Target/DirectX/CMakeLists.txt        |   1 +
 .../DirectX/DXILRemoveUnusedResources.cpp     | 140 ++++++++++++++++++
 .../DirectX/DXILRemoveUnusedResources.h       |  29 ++++
 llvm/lib/Target/DirectX/DirectX.h             |   6 +
 .../Target/DirectX/DirectXPassRegistry.def    |   1 +
 .../Target/DirectX/DirectXTargetMachine.cpp   |   3 +
 .../DirectX/Binding/binding-overlap-3.ll      |   2 +-
 .../DirectX/Binding/binding-overlap-4.ll      |   2 +-
 .../DirectX/Binding/binding-overlap-5.ll      |   2 +-
 .../DirectX/Binding/binding-overlap-7.ll      |   2 +-
 .../ContainerData/PSVResources-order.ll       |   2 +-
 .../DirectX/ContainerData/PSVResources.ll     |   2 +-
 .../DirectX/Metadata/cbuffer-metadata.ll      |   2 +-
 .../CodeGen/DirectX/Metadata/srv_metadata.ll  |   2 +-
 .../CodeGen/DirectX/Metadata/uav_metadata.ll  |   2 +-
 .../max-64-uavs-array-valver1.6.ll            |   2 +-
 .../DirectX/ShaderFlags/max-64-uavs.ll        |   2 +-
 .../ShaderFlags/overflow-uavs-array.ll        |   2 +-
 .../uavs-at-every-stage-lib-valver1.7.ll      |   2 +-
 .../ShaderFlags/unbounded-uavs-array.ll       |   2 +-
 llvm/test/CodeGen/DirectX/llc-pipeline.ll     |   1 +
 .../DirectX/resources-in-unused-function.ll   |  81 ++++++++++
 .../DirectX/unused-resources-impl-binding.ll  | 109 ++++++++++++++
 llvm/test/CodeGen/DirectX/unused-resources.ll |  68 +++++++++
 24 files changed, 453 insertions(+), 14 deletions(-)
 create mode 100644 llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
 create mode 100644 llvm/lib/Target/DirectX/DXILRemoveUnusedResources.h
 create mode 100644 llvm/test/CodeGen/DirectX/resources-in-unused-function.ll
 create mode 100644 llvm/test/CodeGen/DirectX/unused-resources-impl-binding.ll
 create mode 100644 llvm/test/CodeGen/DirectX/unused-resources.ll

diff --git a/llvm/lib/Target/DirectX/CMakeLists.txt b/llvm/lib/Target/DirectX/CMakeLists.txt
index 436b7499f8dca..fd730ed82cc51 100644
--- a/llvm/lib/Target/DirectX/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/CMakeLists.txt
@@ -32,6 +32,7 @@ add_llvm_target(DirectXCodeGen
   DXILPostOptimizationValidation.cpp
   DXILPrepare.cpp
   DXILPrettyPrinter.cpp
+  DXILRemoveUnusedResources.cpp
   DXILResourceAccess.cpp
   DXILResourceImplicitBinding.cpp
   DXILShaderFlags.cpp
diff --git a/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
new file mode 100644
index 0000000000000..aa05f58336752
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.cpp
@@ -0,0 +1,140 @@
+//===- DXILResourceAccess.cpp - Resource access via load/store ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DXILRemoveUnusedResources.h"
+#include "DirectX.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Analysis/VectorUtils.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+
+#define DEBUG_TYPE "dxil-remove-unused-resources"
+
+// Hidden option to disable the pass to make it easier to test
+// other passes related to DXIL resources using llc.
+static llvm::cl::opt<bool> DisableDXILRemoveUnusedResources(
+    "disable-dxil-remove-unused-resources",
+    llvm::cl::desc("Disable dxil-remove-unused-resources pass"),
+    llvm::cl::init(false), llvm::cl::Hidden);
+
+using namespace llvm;
+
+// Removes all calls to intrinsics dx_resource_handlefrom{implicit}binding 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.
+static bool removeUnusedResources(Function &F) {
+  if (DisableDXILRemoveUnusedResources)
+    return false;
+
+  SmallVector<Instruction *> DeadInstr;
+  SmallSetVector<GlobalVariable *, 4> DeadGlobals;
+  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)
+          continue;
+        if (II->user_empty()) {
+          // Initialized handle is not used anywhere.
+          DeadInstr.push_back(II);
+          continue;
+        }
+        if (!II->hasOneUser())
+          continue;
+
+        // Initialized handle is only used in one store instruction, the store
+        // is into global variable, and that global variable is not used
+        // anywhere else and does not have external linkage.
+        auto *SI = dyn_cast<StoreInst>(*II->user_begin());
+        if (!SI)
+          continue;
+        assert(SI->getValueOperand() == II &&
+               "expected value operand to be the resource handle");
+
+        GlobalVariable *GV = dyn_cast<GlobalVariable>(SI->getPointerOperand());
+        if (!GV || GV->hasExternalLinkage())
+          continue;
+
+        if (GV->hasOneUser()) {
+          assert(*GV->user_begin() == SI &&
+                 "expected single user to be the store instruction");
+          DeadInstr.push_back(SI);
+          DeadInstr.push_back(II);
+          DeadGlobals.insert(GV);
+        }
+      }
+    }
+  }
+
+  if (DeadInstr.empty())
+    return false;
+
+  for (auto *Instr : DeadInstr) {
+    if (auto *II = dyn_cast<IntrinsicInst>(Instr)) {
+      assert(II->getIntrinsicID() == Intrinsic::dx_resource_handlefrombinding ||
+             II->getIntrinsicID() ==
+                 Intrinsic::dx_resource_handlefromimplicitbinding);
+      const unsigned ResourceNameOpIndex = 4;
+      GlobalVariable *ResourceName = dyn_cast_or_null<GlobalVariable>(
+          II->getArgOperand(ResourceNameOpIndex));
+      if (ResourceName)
+        DeadGlobals.insert(ResourceName);
+    }
+    Instr->eraseFromParent();
+  }
+
+  for (auto *GV : DeadGlobals)
+    if (GV->use_empty())
+      GV->eraseFromParent();
+
+  return true;
+}
+
+PreservedAnalyses DXILRemoveUnusedResources::run(Function &F,
+                                                 FunctionAnalysisManager &AM) {
+  removeUnusedResources(F);
+  return PreservedAnalyses::all();
+}
+
+namespace {
+class DXILRemoveUnusedResourcesLegacy : public FunctionPass {
+public:
+  bool runOnFunction(Function &F) override { return removeUnusedResources(F); }
+  StringRef getPassName() const override {
+    return "DXIL Remove Unused Resources";
+  }
+  DXILRemoveUnusedResourcesLegacy() : FunctionPass(ID) {}
+
+  static char ID; // Pass identification.
+  void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+};
+char DXILRemoveUnusedResourcesLegacy::ID = 0;
+} // end anonymous namespace
+
+INITIALIZE_PASS_BEGIN(DXILRemoveUnusedResourcesLegacy, DEBUG_TYPE,
+                      "DXIL Remove Unused Resources", false, false)
+INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)
+INITIALIZE_PASS_END(DXILRemoveUnusedResourcesLegacy, DEBUG_TYPE,
+                    "DXIL Remove Unused Resources", false, false)
+
+FunctionPass *llvm::createDXILRemoveUnusedResourcesLegacyPass() {
+  return new DXILRemoveUnusedResourcesLegacy();
+}
diff --git a/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.h b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.h
new file mode 100644
index 0000000000000..2b9f61c3f8a7a
--- /dev/null
+++ b/llvm/lib/Target/DirectX/DXILRemoveUnusedResources.h
@@ -0,0 +1,29 @@
+//===- DXILRemoveUnusedResources.h - Remove unused resources ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file Pass for removing unused DXIL resources initialization calls and
+// associated global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_DIRECTX_DXILREMOVEUNUSEDRESOURCES_H
+#define LLVM_LIB_TARGET_DIRECTX_DXILREMOVEUNUSEDRESOURCES_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class DXILRemoveUnusedResources
+    : public OptionalPassInfoMixin<DXILRemoveUnusedResources> {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_DIRECTX_DXILREMOVEUNUSEDRESOURCES_H
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index dfeb1ab12665d..eb2966ee9b4c4 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -78,6 +78,12 @@ void initializeDXILOpLoweringLegacyPass(PassRegistry &);
 /// Pass to lowering LLVM intrinsic call to DXIL op function call.
 ModulePass *createDXILOpLoweringLegacyPass();
 
+/// Initializer for DXILRemoveUnusedResources
+void initializeDXILRemoveUnusedResourcesLegacyPass(PassRegistry &);
+
+/// Pass to update remove unsused resources.
+FunctionPass *createDXILRemoveUnusedResourcesLegacyPass();
+
 /// Initializer for DXILResourceAccess
 void initializeDXILResourceAccessLegacyPass(PassRegistry &);
 
diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
index f594546f98901..027803c1181f5 100644
--- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def
+++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
@@ -43,6 +43,7 @@ MODULE_PASS("print<dxil-root-signature>", dxil::RootSignatureAnalysisPrinter(dbg
 #define FUNCTION_PASS(NAME, CREATE_PASS)
 #endif
 FUNCTION_PASS("dxil-forward-handle-accesses", DXILForwardHandleAccesses())
+FUNCTION_PASS("dxil-remove-unused-resources", DXILRemoveUnusedResources())
 FUNCTION_PASS("dxil-resource-access", DXILResourceAccess())
 FUNCTION_PASS("dxil-legalize", DXILLegalizePass())
 #undef FUNCTION_PASS
diff --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 234385828bd3d..c4172b748107a 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -23,6 +23,7 @@
 #include "DXILOpLowering.h"
 #include "DXILPostOptimizationValidation.h"
 #include "DXILPrettyPrinter.h"
+#include "DXILRemoveUnusedResources.h"
 #include "DXILResourceAccess.h"
 #include "DXILResourceImplicitBinding.h"
 #include "DXILRootSignature.h"
@@ -71,6 +72,7 @@ LLVMInitializeDirectXTarget() {
   initializeDXContainerGlobalsPass(*PR);
   initializeGlobalDCELegacyPassPass(*PR);
   initializeDXILOpLoweringLegacyPass(*PR);
+  initializeDXILRemoveUnusedResourcesLegacyPass(*PR);
   initializeDXILResourceAccessLegacyPass(*PR);
   initializeDXILResourceImplicitBindingLegacyPass(*PR);
   initializeDXILTranslateMetadataLegacyPass(*PR);
@@ -117,6 +119,7 @@ class DirectXPassConfig : public TargetPassConfig {
     addPass(createGlobalDCEPass());
     addPass(createDXILMemIntrinsicsLegacyPass());
     addPass(createDXILCBufferAccessLegacyPass());
+    addPass(createDXILRemoveUnusedResourcesLegacyPass());
     addPass(createDXILResourceAccessLegacyPass());
     addPass(createDXILIntrinsicExpansionLegacyPass());
     addPass(createDXILDataScalarizationLegacyPass());
diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-3.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-3.ll
index 67365ee3b64f7..f41b3b4f91ad2 100644
--- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-3.ll
+++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-3.ll
@@ -1,5 +1,5 @@
 ; Use llc for this test so that we don't abort after the first error.
-; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc %s -disable-dxil-remove-unused-resources -o /dev/null 2>&1 | FileCheck %s
 
 ; Check multiple overlap errors.
 ; Also check different resource class with same binding values is ok (no error expected).
diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-4.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-4.ll
index bd8dda7858f9f..a0bb16a85d6ef 100644
--- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-4.ll
+++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-4.ll
@@ -1,5 +1,5 @@
 ; Use llc for this test so that we don't abort after the first error.
-; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc %s -disable-dxil-remove-unused-resources -o /dev/null 2>&1 | FileCheck %s
 
 ; Check multiple overlap errors.
 
diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-5.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-5.ll
index b047a22db5fb9..6e6ae67cdf786 100644
--- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-5.ll
+++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-5.ll
@@ -1,5 +1,5 @@
 ; Use llc for this test so that we don't abort after the first error.
-; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc %s -disable-dxil-remove-unused-resources -o /dev/null 2>&1 | FileCheck %s
 
 ; Check multiple overlap errors.
 
diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll
index 151c770489826..2e1983fd16fce 100644
--- a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll
+++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll
@@ -1,5 +1,5 @@
 ; Use llc for this test so that we don't abort after the first error.
-; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llc %s -disable-dxil-remove-unused-resources -o /dev/null 2>&1 | FileCheck %s
 
 ; Check that there is no overlap with unbounded array in different space
 
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources-order.ll b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources-order.ll
index 5cd67be1a4a28..4a6f9267c2fea 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources-order.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources-order.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s
 
 ; Check that resources are emitted to the object in the order that matches what
 ; the DXIL validator expects: CBuffers, Samplers, SRVs, and then UAVs.
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll
index ea3a02245c1cc..ffd9886d27f41 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s
 
 ; Make sure resource table is created correctly.
 ; CHECK: Resources:
diff --git a/llvm/test/CodeGen/DirectX/Metadata/cbuffer-metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/cbuffer-metadata.ll
index 6b90e17816991..f389e612e5560 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/cbuffer-metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/cbuffer-metadata.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s
 ; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT
-; RUN: llc %s --filetype=asm -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=asm -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
 
 target triple = "dxil-pc-shadermodel6.6-compute"
 
diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
index ea8f418d4dada..202f29ca2df9b 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s
 ; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT
-; RUN: llc %s --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
 
 target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
 target triple = "dxil-pc-shadermodel6.6-compute"
diff --git a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
index 0f7d56fb1261e..3c7cdb981d87f 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s
 ; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT
-; RUN: llc %s --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT
 
 target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
 target triple = "dxil-pc-shadermodel6.6-compute"
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
index a397074650e46..c4bbfcf3c8ad3 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll
@@ -1,5 +1,5 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
 
 ; This test makes sure that resource arrays sizes are accounted for when
 ; counting the number of UAVs for setting the shader flag '64 UAV slots' when
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
index 6ed267d05dae1..6ef00b1a21b62 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll
@@ -1,5 +1,5 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
 
 ; This test makes sure that the shader flag '64 UAV slots' is set when there are
 ; more than 8 UAVs in the module.
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll
index 6b08f62ff73ed..4f25c0cd69d3a 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll
@@ -1,5 +1,5 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ
 
 ; This test makes sure that no overflow is happening when a resource is followed
 ; by an unbounded array of UAVs. 
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
index ae2b35f80bde5..5ab0153af4d7c 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll
@@ -1,5 +1,5 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
 
 ; This test ensures that a library shader with a UAV gets the module and
 ; shader feature flag UAVsAtEveryStage when the DXIL validator version is < 1.8
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll
index ba323d60fb530..6b7de13153df7 100644
--- a/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll
@@ -1,5 +1,5 @@
 ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
-; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ
 
 ; This test makes sure that Max64UAVs is correctly set when using an
 ; unbounded array of UAVs;
diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
index 2474e08ac1549..021a12a4b9334 100644
--- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll
+++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll
@@ -21,6 +21,7 @@
 ; CHECK-NEXT:   DXIL Memory Intrinsic Elimination
 ; CHECK-NEXT:   DXIL CBuffer Access
 ; CHECK-NEXT:   FunctionPass Manager
+; CHECK-NEXT:     DXIL Remove Unused Resources
 ; CHECK-NEXT:     DXIL Resource Access
 ; CHECK-NEXT:   DXIL Intrinsic Expansion
 ; CHECK-NEXT:   DXIL Data Scalarization
diff --git a/llvm/test/CodeGen/DirectX/resources-in-unused-function.ll b/llvm/test/CodeGen/DirectX/resources-in-unused-function.ll
new file mode 100644
index 0000000000000..3476832402517
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/resources-in-unused-function.ll
@@ -0,0 +1,81 @@
+; RUN: llc %s -stop-after=dxil-resource-access -o - | FileCheck %s
+; RUN: llc %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-PRINT
+
+target triple = "dxil-pc-shadermodel6.6-compute"
+
+; This test makes sure that if resources are referenced in a function that
+; is not used, then after the function is optimized out we also remove:
+; - unused resource initialization calls
+; - unused associated global resource variables
+; - resource name strings
+
+%__cblayout_CB = type <{ i32, float }>
+%"__cblayout_$Globals" = type <{ i32, float }>
+
+ at CB.cb = internal global target("dx.CBuffer", %__cblayout_CB) poison
+ at c = external hidden local_unnamed_addr addrspace(2) global i32, align 4
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+ at _ZL3Buf.0 = internal unnamed_addr global target("dx.TypedBuffer", float, 1, 0, 0) poison, align 4
+ at .str = private unnamed_addr constant [4 x i8] c"Buf\00", align 1
+ at a = external hidden local_unnamed_addr addrspace(2) global i32, align 4
+@"$Globals.cb" = internal global target("dx.CBuffer", %"__cblayout_$Globals") poison
+@"$Globals.str" = private unnamed_addr constant [9 x i8] c"$Globals\00", align 1
+
+; Unused function that references resources
+define hidden void @_Z3foov() local_unnamed_addr #1 {
+entry:
+  %0 = load i32, ptr addrspace(2) @a, align 4
+  %1 = load i32, ptr addrspace(2) @c, align 4
+  %add = add nsw i32 %1, %0
+  %conv = sitofp i32 %add to float
+  %2 = load target("dx.TypedBuffer", float, 1, 0, 0), ptr @_ZL3Buf.0, align 4
+  %3 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_1_0_0t.i32(target("dx.TypedBuffer", float, 1, 0, 0) %2, i32 0)
+  store float %conv, ptr %3, align 4
+  ret void
+}
+
+define void @main() {
+entry:
+
+; CBuffers
+  %cb_handle0 = tail call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst(i32 0, i32 0, i32 1, i32 0, ptr nonnull @CB.str)
+  store target("dx.CBuffer", %__cblayout_CB) %cb_handle0, ptr @CB.cb, align 4
+
+  %uav_handle = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, ptr nonnull @.str)
+  store target("dx.TypedBuffer", float, 1, 0, 0) %uav_handle, ptr @_ZL3Buf.0, align 4
+  
+  %cb_handle1 = tail call target("dx.CBuffer", %"__cblayout_$Globals") @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"(i32 1, i32 0, i32 1, i32 0, ptr nonnull @"$Globals.str")
+  store target("dx.CBuffer", %"__cblayout_$Globals") %cb_handle1, ptr @"$Globals.cb", align 4
+
+  ret void
+}
+
+!hlsl.cbs = !{!0, !1}
+
+; This is a list of all the constant buffers in the shader.
+; The null values in the list indicate that the corresponding constant is not used in the shader.
+!0 = distinct !{ptr @CB.cb, ptr addrspace(2) @c, null}
+!1 = distinct !{ptr @"$Globals.cb", ptr addrspace(2) @a, null}
+
+; Make sure the resource globals and initialization calls are removed from the module
+; CHECK-NOT: @CB.cb
+; CHECK-NOT: @c
+; CHECK-NOT: @CB.str
+; CHECK-NOT: @_ZL3Buf.0
+; CHECK-NOT: @.str
+; CHECK-NOT: @a
+; CHECK-NOT: @"$Globals.cb"
+; CHECK-NOT: @"$Globals.str" 
+; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefrombinding
+; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefromimplicitbinding
+
+; Make sure the resource bindings table is empty
+; CHECK-PRINT: ; Resource Bindings:
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; Name                                  Type  Format         Dim      ID      HLSL Bind     Count
+; CHECK-PRINT-NEXT: ; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; ModuleID
+; CHECK-PRINT-NOT: ; Buf
+; CHECK-PRINT-NOT: ; CB
+; CHECK-PRINT-NOT: ; $Globals
diff --git a/llvm/test/CodeGen/DirectX/unused-resources-impl-binding.ll b/llvm/test/CodeGen/DirectX/unused-resources-impl-binding.ll
new file mode 100644
index 0000000000000..db74746f14434
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/unused-resources-impl-binding.ll
@@ -0,0 +1,109 @@
+; RUN: llc -stop-after=dxil-resource-access %s -o - | FileCheck %s
+; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK-PRINT
+
+target triple = "dxil-pc-shadermodel6.6-compute"
+
+; This test makes sure that unused resource removed in dxil-resource-access
+; pass do not affect implicit resource bindings.
+; For constant buffers declared in the order {CB_Unused, CB, $Globals} where only
+; CB is used, the CB should be the only resource that remains in the resource bindings
+; table and should be assigned slot cb0.
+; Similarly, for RWBuffer resources declared in order {Buf_Unused, Buf} where only Buf
+; is used, the Buf resource should be the only UAV resource in the resource bindings table 
+; and should be assigned slot u0.
+
+%__cblayout_CB_Unused = type <{ i32 }>
+%__cblayout_CB = type <{ i32 }>
+%"__cblayout_$Globals" = type <{ i32 }>
+
+ at CB_Unused.cb = internal global target("dx.CBuffer", %__cblayout_CB_Unused) poison
+ at CB_Unused.str = private unnamed_addr constant [10 x i8] c"CB_Unused\00", align 1
+ at CB.cb = internal global target("dx.CBuffer", %__cblayout_CB) poison
+ at c = external hidden local_unnamed_addr addrspace(2) global i32, align 4
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+ at _ZL10Buf_Unused.0 = internal unnamed_addr global target("dx.TypedBuffer", i32, 1, 0, 1) poison, align 4
+ at .str = private unnamed_addr constant [11 x i8] c"Buf_Unused\00", align 1
+ at _ZL3Buf.0 = internal unnamed_addr global target("dx.TypedBuffer", i32, 1, 0, 1) poison, align 4
+ at .str.2 = private unnamed_addr constant [4 x i8] c"Buf\00", align 1
+ at a = external hidden local_unnamed_addr addrspace(2) global i32, align 4
+@"$Globals.cb" = internal global target("dx.CBuffer", %"__cblayout_$Globals") poison
+@"$Globals.str" = private unnamed_addr constant [9 x i8] c"$Globals\00", align 1
+
+; Unused function foo
+define hidden void @_Z3foov() {
+entry:
+  ; Use constant @a from $Globals and buffer Buf_Unused
+  %0 = load i32, ptr addrspace(2) @a, align 4
+  %1 = load target("dx.TypedBuffer", i32, 1, 0, 1), ptr @_ZL10Buf_Unused.0, align 4
+  %2 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t.i32(target("dx.TypedBuffer", i32, 1, 0, 1) %1, i32 0)
+  store i32 %0, ptr %2, align 4
+  ret void
+}
+
+define void @main() {
+entry:
+  %cb_handle0 = tail call target("dx.CBuffer", %__cblayout_CB_Unused) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Unusedst(i32 0, i32 0, i32 1, i32 0, ptr nonnull @CB_Unused.str)
+  store target("dx.CBuffer", %__cblayout_CB_Unused) %cb_handle0, ptr @CB_Unused.cb, align 4
+
+  %cb_handle1 = tail call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst(i32 1, i32 0, i32 1, i32 0, ptr nonnull @CB.str)
+  store target("dx.CBuffer", %__cblayout_CB) %cb_handle1, ptr @CB.cb, align 4
+
+  %uav_handle0 = tail call target("dx.TypedBuffer", i32, 1, 0, 1) @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_i32_1_0_1t(i32 2, i32 0, i32 1, i32 0, ptr nonnull @.str)
+  store target("dx.TypedBuffer", i32, 1, 0, 1) %uav_handle0, ptr @_ZL10Buf_Unused.0, align 4
+
+  %uav_handle1 = tail call target("dx.TypedBuffer", i32, 1, 0, 1) @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_i32_1_0_1t(i32 3, i32 0, i32 1, i32 0, ptr nonnull @.str.2)
+  store target("dx.TypedBuffer", i32, 1, 0, 1) %uav_handle1, ptr @_ZL3Buf.0, align 4
+
+  %cb_handle2 = tail call target("dx.CBuffer", %"__cblayout_$Globals") @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"(i32 4, i32 0, i32 1, i32 0, ptr nonnull @"$Globals.str")
+  store target("dx.CBuffer", %"__cblayout_$Globals") %cb_handle2, ptr @"$Globals.cb", align 4
+
+  ; Use constant @c from CB and buffer Buf
+  %1 = load i32, ptr addrspace(2) @c, align 4
+  %2 = tail call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t.i32(target("dx.TypedBuffer", i32, 1, 0, 1) %uav_handle1, i32 0)
+  store i32 %1, ptr %2, align 4
+  ret void
+}
+
+!hlsl.cbs = !{!0, !1, !2}
+
+; This is a list of all the constant buffers in the shader.
+; The null values in the list indicate that the corresponding constant is not used in the shader.
+!0 = distinct !{ptr @CB_Unused.cb, null}
+!1 = !{ptr @CB.cb, ptr addrspace(2) @c}
+!2 = !{ptr @"$Globals.cb", ptr addrspace(2) @a}
+
+; Make sure the unused resource globals and initialization calls are removed from the module
+; and the used ones are retained.
+; CHECK-NOT: @CB_Unused.cb
+; CHECK-NOT: @CB_Unused.str
+; CHECK-NOT: @_ZL10Buf_Unused.0
+; CHECK-NOT: @.str
+; CHECK-NOT: @"$Globals.cb"
+; CHECK-NOT: @"$Globals.str" 
+
+; CHECK: @CB.cb = internal global target("dx.CBuffer", %__cblayout_CB) poison
+; CHECK: @CB.str = internal unnamed_addr constant [3 x i8] c"CB\00", align 1
+; CHECK: @_ZL3Buf.0 = internal unnamed_addr global target("dx.TypedBuffer", i32, 1, 0, 1) poison, align 4
+; CHECK: @.str.2 = internal unnamed_addr constant [4 x i8] c"Buf\00", align 1
+
+; CHECK-NOT: {{.*}} call {{.*}} @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CB_Unusedst({{.*}}, ptr nonnull @CB_unused.str)
+; CHECK: call {{.*}} @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst({{.*}}, ptr nonnull @CB.str)
+; CHECK-NOT: call {{.*}} @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"({{.*}}, ptr nonnull @"$Globals.str")
+
+; CHECK-NOT: call {{.*}} @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_i32_1_0_1t({{.*}}, ptr nonnull @.str)
+; CHECK: call {{.*}} @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_i32_1_0_1t({{.*}}, ptr nonnull @.str.2)
+  
+; Make sure the resource bindings table contain only the used resources with correct binding information.
+
+; CHECK-PRINT: ; Resource Bindings:
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; Name                                 Type  Format         Dim      ID      HLSL Bind     Count
+; CHECK-PRINT-NEXT: ; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
+; CHECK-PRINT-NEXT: ; Buf                                   UAV     i32         buf      U0             u0         1
+; CHECK-PRINT-NEXT: ; CB                                cbuffer      NA          NA     CB0            cb0         1
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; ModuleID
+
+; CHECK-PRINT-NOT: ; Buf_Unused
+; CHECK-PRINT-NOT: ; CB_Unused
+; CHECK-PRINT-NOT: ; $Globals
diff --git a/llvm/test/CodeGen/DirectX/unused-resources.ll b/llvm/test/CodeGen/DirectX/unused-resources.ll
new file mode 100644
index 0000000000000..b11638cec0f9a
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/unused-resources.ll
@@ -0,0 +1,68 @@
+; RUN: opt -S -dxil-remove-unused-resources %s -o - | FileCheck %s
+; RUN: llc %s -o - | FileCheck %s --check-prefix=CHECK-PRINT
+
+target triple = "dxil-pc-shadermodel6.6-compute"
+
+; This test makes sure that we remove:
+; - unused resource initialization calls
+; - unused cbuffers and associated global variables
+; - resource name strings
+
+%__cblayout_CB = type <{ i32, float }>
+%"__cblayout_$Globals" = type <{ i32, float }>
+
+ at CB.cb = internal global target("dx.CBuffer", %__cblayout_CB) poison
+ at CB.str = private unnamed_addr constant [3 x i8] c"CB\00", align 1
+@"$Globals.cb" = internal global target("dx.CBuffer", %"__cblayout_$Globals") poison
+@"$Globals.str" = private unnamed_addr constant [9 x i8] c"$Globals\00", align 1
+ at _ZL3Buf = internal unnamed_addr global target("dx.RawBuffer", i16, 1, 0) poison, align 4
+ at Buf.str = private unnamed_addr constant [4 x i8] c"Buf\00", align 1
+
+define void @main() {
+entry:
+
+; CBuffers
+  %cb_handle0 = tail call target("dx.CBuffer", %__cblayout_CB) @llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_CBst(i32 0, i32 0, i32 1, i32 0, ptr nonnull @CB.str)
+  store target("dx.CBuffer", %__cblayout_CB) %cb_handle0, ptr @CB.cb, align 4
+
+  %cb_handle1 = tail call target("dx.CBuffer", %"__cblayout_$Globals") @"llvm.dx.resource.handlefromimplicitbinding.tdx.CBuffer_s___cblayout_$Globalsst"(i32 2, i32 0, i32 1, i32 0, ptr nonnull @"$Globals.str")
+  store target("dx.CBuffer", %"__cblayout_$Globals") %cb_handle1, ptr @"$Globals.cb", align 4
+
+; SrvBuffer
+  %srv_handle = call target("dx.TypedBuffer", i64, 0, 0, 0)
+            @llvm.dx.resource.handlefrombinding(i32 5, i32 20, i32 1, i32 0, ptr null)
+
+; UavBuffer
+  %uav_handle = call target("dx.RawBuffer", i16, 1, 0)
+            @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
+
+  ret void
+}
+
+!hlsl.cbs = !{!0, !1}
+
+; This is a list of all the constant buffers in the shader.
+; The null values in the list indicate that the corresponding constant is not used in the shader.
+!0 = distinct !{ptr @CB.cb, null, null}
+!1 = distinct !{ptr @"$Globals.cb", null, null}
+
+; CHECK-NOT: @CB.cb
+; CHECK-NOT: @CB.str
+; CHECK-NOT: @"$Globals.cb"
+; CHECK-NOT: @"$Globals.str" 
+; CHECK-NOT: @_ZL3Buf
+; CHECK-NOT: @Buf.str  
+; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefrombinding
+; CHECK-NOT: call {{.*}} llvm.dx.resource.handlefromimplicitbinding
+
+; Make sure the resource bindings table is empty
+; CHECK-PRINT: ; Resource Bindings:
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; Name                                  Type  Format         Dim      ID      HLSL Bind     Count
+; CHECK-PRINT-NEXT: ; ------------------------------ ---------- ------- ----------- ------- -------------- ---------
+; CHECK-PRINT-NEXT: ;
+; CHECK-PRINT-NEXT: ; ModuleID
+; CHECK-PRINT-NOT: ; Buf
+; CHECK-PRINT-NOT: ; CB
+; CHECK-PRINT-NOT: ; $Globals

>From 747afb79deace61c08d9459af69026be5e0638bd Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Fri, 5 Jun 2026 17:02:30 -0700
Subject: [PATCH 2/2] add -disable-dxil-remove-unused-resources option to
 cbuffer_global_elim.ll tests

---
 llvm/test/CodeGen/DirectX/cbuffer_global_elim.ll | 4 ++--
 llvm/test/CodeGen/SPIRV/cbuffer_global_elim.ll   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/CodeGen/DirectX/cbuffer_global_elim.ll b/llvm/test/CodeGen/DirectX/cbuffer_global_elim.ll
index d4bc9415bc076..cc0f91dd4f3a6 100644
--- a/llvm/test/CodeGen/DirectX/cbuffer_global_elim.ll
+++ b/llvm/test/CodeGen/DirectX/cbuffer_global_elim.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -S -passes='dxil-cbuffer-access' %s -o - | FileCheck %s --check-prefixes=CHECK
-; RUN: llc %s -o - | FileCheck %s --check-prefixes=CHECK-LOWERED
-; RUN: llc %s -O3 -o - | FileCheck %s --check-prefixes=CHECK-LOWERED
+; RUN: llc -disable-dxil-remove-unused-resources %s -o - | FileCheck %s --check-prefixes=CHECK-LOWERED
+; RUN: llc -disable-dxil-remove-unused-resources %s -O3 -o - | FileCheck %s --check-prefixes=CHECK-LOWERED
 
 target triple = "dxil-unknown-shadermodel6.6-compute"
 
diff --git a/llvm/test/CodeGen/SPIRV/cbuffer_global_elim.ll b/llvm/test/CodeGen/SPIRV/cbuffer_global_elim.ll
index 160e56727ed35..b749c48e5508b 100644
--- a/llvm/test/CodeGen/SPIRV/cbuffer_global_elim.ll
+++ b/llvm/test/CodeGen/SPIRV/cbuffer_global_elim.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -S -passes='spirv-cbuffer-access' %s -o - | FileCheck %s
-; RUN: llc %s -o - | FileCheck %s
-; RUN: llc %s -O3 -o - | FileCheck %s
+; RUN: llc -disable-dxil-remove-unused-resources %s -o - | FileCheck %s
+; RUN: llc -disable-dxil-remove-unused-resources %s -O3 -o - | FileCheck %s
 
 target triple = "spirv-unknown-vulkan1.3-compute"
 



More information about the llvm-branch-commits mailing list