[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