[llvm] [DirectX] Remove intrinsic definitions with no use (PR #133459)
Farzon Lotfi via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 28 13:20:10 PDT 2025
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/133459
>From c80789d1feb752f0e05576e5a9cf3a3169aa9f9a Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Fri, 28 Mar 2025 11:42:26 -0400
Subject: [PATCH 1/2] [DirectX] Remove intrinsic definitions with no use
I was planning to use GlobalDCE, but that does more than whats needed to
fix the backend. GlobalDCE also doesn't honor `hlsl.export` and making
it be able to is more work than expanding the DXIL legalizer.
This change reduces "Unsupported intrinsic for DXIL lowering" errors
when compiling DML shaders from 12218 to 415. and improves our compilation success rate
from less than 1% to 44%.
---
llvm/lib/Target/DirectX/DXILLegalizePass.cpp | 53 ++++++++++++++-----
llvm/lib/Target/DirectX/DXILLegalizePass.h | 2 +-
llvm/lib/Target/DirectX/DirectX.h | 2 +-
.../Target/DirectX/DirectXPassRegistry.def | 2 +-
.../CodeGen/DirectX/remove-dead-intriniscs.ll | 22 ++++++++
5 files changed, 64 insertions(+), 17 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/remove-dead-intriniscs.ll
diff --git a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
index 395311e430fbb..8eb0a0458d478 100644
--- a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
+++ b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
@@ -12,6 +12,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <functional>
@@ -20,6 +21,12 @@
using namespace llvm;
+static void removeDeadIntrinsics(Function &F,
+ SmallVectorImpl<Function *> &ToRemove) {
+ if (F.isIntrinsic() && F.use_empty())
+ ToRemove.push_back(&F);
+}
+
static void fixI8TruncUseChain(Instruction &I,
SmallVectorImpl<Instruction *> &ToRemove,
DenseMap<Value *, Value *> &ReplacedValues) {
@@ -146,11 +153,26 @@ class DXILLegalizationPipeline {
public:
DXILLegalizationPipeline() { initializeLegalizationPipeline(); }
- bool runLegalizationPipeline(Function &F) {
+ bool runLegalizationPipeline(Module &M) {
+ bool Changes = false;
+ SmallVector<Function *> ToRemove;
+ for (auto &F : make_early_inc_range(M.functions())) {
+ Changes |= runFunctionLegalizationPipeline(F);
+ for (auto &LegalizationFn : ModuleLegalizationPipeline)
+ LegalizationFn(F, ToRemove);
+ }
+
+ for (Function *F : ToRemove)
+ F->eraseFromParent();
+
+ return Changes && !ToRemove.empty();
+ }
+
+ bool runFunctionLegalizationPipeline(Function &F) {
SmallVector<Instruction *> ToRemove;
DenseMap<Value *, Value *> ReplacedValues;
for (auto &I : instructions(F)) {
- for (auto &LegalizationFn : LegalizationPipeline)
+ for (auto &LegalizationFn : FunctionLegalizationPipeline)
LegalizationFn(I, ToRemove, ReplacedValues);
}
@@ -164,37 +186,40 @@ class DXILLegalizationPipeline {
SmallVector<
std::function<void(Instruction &, SmallVectorImpl<Instruction *> &,
DenseMap<Value *, Value *> &)>>
- LegalizationPipeline;
+ FunctionLegalizationPipeline;
+ SmallVector<std::function<void(Function &, SmallVectorImpl<Function *> &)>>
+ ModuleLegalizationPipeline;
void initializeLegalizationPipeline() {
- LegalizationPipeline.push_back(fixI8TruncUseChain);
- LegalizationPipeline.push_back(downcastI64toI32InsertExtractElements);
+ FunctionLegalizationPipeline.push_back(fixI8TruncUseChain);
+ FunctionLegalizationPipeline.push_back(
+ downcastI64toI32InsertExtractElements);
+ ModuleLegalizationPipeline.push_back(removeDeadIntrinsics);
}
};
-class DXILLegalizeLegacy : public FunctionPass {
+class DXILLegalizeLegacy : public ModulePass {
public:
- bool runOnFunction(Function &F) override;
- DXILLegalizeLegacy() : FunctionPass(ID) {}
+ bool runOnModule(Module &M) override;
+ DXILLegalizeLegacy() : ModulePass(ID) {}
static char ID; // Pass identification.
};
} // namespace
-PreservedAnalyses DXILLegalizePass::run(Function &F,
- FunctionAnalysisManager &FAM) {
+PreservedAnalyses DXILLegalizePass::run(Module &M, ModuleAnalysisManager &MAM) {
DXILLegalizationPipeline DXLegalize;
- bool MadeChanges = DXLegalize.runLegalizationPipeline(F);
+ bool MadeChanges = DXLegalize.runLegalizationPipeline(M);
if (!MadeChanges)
return PreservedAnalyses::all();
PreservedAnalyses PA;
return PA;
}
-bool DXILLegalizeLegacy::runOnFunction(Function &F) {
+bool DXILLegalizeLegacy::runOnModule(Module &M) {
DXILLegalizationPipeline DXLegalize;
- return DXLegalize.runLegalizationPipeline(F);
+ return DXLegalize.runLegalizationPipeline(M);
}
char DXILLegalizeLegacy::ID = 0;
@@ -204,6 +229,6 @@ INITIALIZE_PASS_BEGIN(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
INITIALIZE_PASS_END(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
false)
-FunctionPass *llvm::createDXILLegalizeLegacyPass() {
+ModulePass *llvm::createDXILLegalizeLegacyPass() {
return new DXILLegalizeLegacy();
}
diff --git a/llvm/lib/Target/DirectX/DXILLegalizePass.h b/llvm/lib/Target/DirectX/DXILLegalizePass.h
index 9d6d1cd19081d..dfa8124be7108 100644
--- a/llvm/lib/Target/DirectX/DXILLegalizePass.h
+++ b/llvm/lib/Target/DirectX/DXILLegalizePass.h
@@ -15,7 +15,7 @@ namespace llvm {
class DXILLegalizePass : public PassInfoMixin<DXILLegalizePass> {
public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
};
} // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index 96a8a08c875f8..98985db39fc61 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -52,7 +52,7 @@ void initializeDXILLegalizeLegacyPass(PassRegistry &);
/// Pass to Legalize DXIL by remove i8 truncations and i64 insert/extract
/// elements
-FunctionPass *createDXILLegalizeLegacyPass();
+ModulePass *createDXILLegalizeLegacyPass();
/// Initializer for DXILOpLowering
void initializeDXILOpLoweringLegacyPass(PassRegistry &);
diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
index 87d91ead1896f..473f142589d1f 100644
--- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def
+++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
@@ -26,6 +26,7 @@ MODULE_ANALYSIS("dxil-root-signature-analysis", dxil::RootSignatureAnalysis())
MODULE_PASS("dxil-data-scalarization", DXILDataScalarization())
MODULE_PASS("dxil-flatten-arrays", DXILFlattenArrays())
MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion())
+MODULE_PASS("dxil-legalize", DXILLegalizePass())
MODULE_PASS("dxil-op-lower", DXILOpLowering())
MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs()))
MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata())
@@ -38,5 +39,4 @@ MODULE_PASS("print<dxil-root-signature>", dxil::RootSignatureAnalysisPrinter(dbg
#define FUNCTION_PASS(NAME, CREATE_PASS)
#endif
FUNCTION_PASS("dxil-resource-access", DXILResourceAccess())
-FUNCTION_PASS("dxil-legalize", DXILLegalizePass())
#undef FUNCTION_PASS
diff --git a/llvm/test/CodeGen/DirectX/remove-dead-intriniscs.ll b/llvm/test/CodeGen/DirectX/remove-dead-intriniscs.ll
new file mode 100644
index 0000000000000..e3b1f0b69d0b7
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/remove-dead-intriniscs.ll
@@ -0,0 +1,22 @@
+
+; RUN: llc %s -mtriple=dxil-pc-shadermodel6.3-library --filetype=asm -o - | FileCheck %s
+
+declare void @llvm.lifetime.start.p0(i64, ptr) #1
+declare void @llvm.lifetime.end.p0(i64, ptr) #1
+declare i32 @llvm.dx.udot.v4i32(<4 x i32>, <4 x i32>) #2
+declare void @llvm.memset.p0.i32(ptr, i8, i32, i1) #3
+
+; CHECK-NOT: declare void @llvm.lifetime.start.p0(i64, ptr)
+; CHECK-NOT: declare void @llvm.lifetime.end.p0(i64, ptr)
+; CHECK-NOT: declare i32 @llvm.dx.udot.v4i32(<4 x i32>, <4 x i32>)
+; CHECK-NOT: declare void @llvm.memset.p0.i32(ptr, i8, i32, i1)
+
+; CHECK-LABEL: empty_fn
+define void @empty_fn () local_unnamed_addr #0 {
+ ret void
+ }
+
+attributes #0 = { convergent norecurse nounwind "hlsl.export"}
+attributes #1 = { nounwind memory(argmem: readwrite) }
+attributes #2 = { nounwind memory(none) }
+attributes #3 = { nounwind memory(argmem: write) }
>From 82cac25e1b30a8bd13da9aea1d2587cb2b0b8c01 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Fri, 28 Mar 2025 16:19:14 -0400
Subject: [PATCH 2/2] revert changes to LegalizerPass, instead do cleanup in
DXILFinalizeLinkage.cpp where intrinsics are getting orphaned
---
.../Target/DirectX/DXILFinalizeLinkage.cpp | 12 ++++-
llvm/lib/Target/DirectX/DXILLegalizePass.cpp | 53 +++++--------------
llvm/lib/Target/DirectX/DXILLegalizePass.h | 2 +-
llvm/lib/Target/DirectX/DirectX.h | 2 +-
.../Target/DirectX/DirectXPassRegistry.def | 2 +-
5 files changed, 27 insertions(+), 44 deletions(-)
diff --git a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
index 91ac758150fb4..7651617adc43b 100644
--- a/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
+++ b/llvm/lib/Target/DirectX/DXILFinalizeLinkage.cpp
@@ -18,7 +18,7 @@
using namespace llvm;
static bool finalizeLinkage(Module &M) {
- SmallPtrSet<Function *, 8> Funcs;
+ SmallVector<Function *> Funcs;
// Collect non-entry and non-exported functions to set to internal linkage.
for (Function &EF : M.functions()) {
@@ -26,7 +26,7 @@ static bool finalizeLinkage(Module &M) {
continue;
if (EF.hasFnAttribute("hlsl.shader") || EF.hasFnAttribute("hlsl.export"))
continue;
- Funcs.insert(&EF);
+ Funcs.push_back(&EF);
}
for (Function *F : Funcs) {
@@ -36,6 +36,14 @@ static bool finalizeLinkage(Module &M) {
M.getFunctionList().erase(F);
}
+ // Do a pass over intrinsics that are no longer used and remove them.
+ Funcs.clear();
+ for (Function &F : M.functions())
+ if (F.isIntrinsic() && F.use_empty())
+ Funcs.push_back(&F);
+ for (Function *F : Funcs)
+ F->eraseFromParent();
+
return false;
}
diff --git a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
index 8eb0a0458d478..395311e430fbb 100644
--- a/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
+++ b/llvm/lib/Target/DirectX/DXILLegalizePass.cpp
@@ -12,7 +12,6 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <functional>
@@ -21,12 +20,6 @@
using namespace llvm;
-static void removeDeadIntrinsics(Function &F,
- SmallVectorImpl<Function *> &ToRemove) {
- if (F.isIntrinsic() && F.use_empty())
- ToRemove.push_back(&F);
-}
-
static void fixI8TruncUseChain(Instruction &I,
SmallVectorImpl<Instruction *> &ToRemove,
DenseMap<Value *, Value *> &ReplacedValues) {
@@ -153,26 +146,11 @@ class DXILLegalizationPipeline {
public:
DXILLegalizationPipeline() { initializeLegalizationPipeline(); }
- bool runLegalizationPipeline(Module &M) {
- bool Changes = false;
- SmallVector<Function *> ToRemove;
- for (auto &F : make_early_inc_range(M.functions())) {
- Changes |= runFunctionLegalizationPipeline(F);
- for (auto &LegalizationFn : ModuleLegalizationPipeline)
- LegalizationFn(F, ToRemove);
- }
-
- for (Function *F : ToRemove)
- F->eraseFromParent();
-
- return Changes && !ToRemove.empty();
- }
-
- bool runFunctionLegalizationPipeline(Function &F) {
+ bool runLegalizationPipeline(Function &F) {
SmallVector<Instruction *> ToRemove;
DenseMap<Value *, Value *> ReplacedValues;
for (auto &I : instructions(F)) {
- for (auto &LegalizationFn : FunctionLegalizationPipeline)
+ for (auto &LegalizationFn : LegalizationPipeline)
LegalizationFn(I, ToRemove, ReplacedValues);
}
@@ -186,40 +164,37 @@ class DXILLegalizationPipeline {
SmallVector<
std::function<void(Instruction &, SmallVectorImpl<Instruction *> &,
DenseMap<Value *, Value *> &)>>
- FunctionLegalizationPipeline;
- SmallVector<std::function<void(Function &, SmallVectorImpl<Function *> &)>>
- ModuleLegalizationPipeline;
+ LegalizationPipeline;
void initializeLegalizationPipeline() {
- FunctionLegalizationPipeline.push_back(fixI8TruncUseChain);
- FunctionLegalizationPipeline.push_back(
- downcastI64toI32InsertExtractElements);
- ModuleLegalizationPipeline.push_back(removeDeadIntrinsics);
+ LegalizationPipeline.push_back(fixI8TruncUseChain);
+ LegalizationPipeline.push_back(downcastI64toI32InsertExtractElements);
}
};
-class DXILLegalizeLegacy : public ModulePass {
+class DXILLegalizeLegacy : public FunctionPass {
public:
- bool runOnModule(Module &M) override;
- DXILLegalizeLegacy() : ModulePass(ID) {}
+ bool runOnFunction(Function &F) override;
+ DXILLegalizeLegacy() : FunctionPass(ID) {}
static char ID; // Pass identification.
};
} // namespace
-PreservedAnalyses DXILLegalizePass::run(Module &M, ModuleAnalysisManager &MAM) {
+PreservedAnalyses DXILLegalizePass::run(Function &F,
+ FunctionAnalysisManager &FAM) {
DXILLegalizationPipeline DXLegalize;
- bool MadeChanges = DXLegalize.runLegalizationPipeline(M);
+ bool MadeChanges = DXLegalize.runLegalizationPipeline(F);
if (!MadeChanges)
return PreservedAnalyses::all();
PreservedAnalyses PA;
return PA;
}
-bool DXILLegalizeLegacy::runOnModule(Module &M) {
+bool DXILLegalizeLegacy::runOnFunction(Function &F) {
DXILLegalizationPipeline DXLegalize;
- return DXLegalize.runLegalizationPipeline(M);
+ return DXLegalize.runLegalizationPipeline(F);
}
char DXILLegalizeLegacy::ID = 0;
@@ -229,6 +204,6 @@ INITIALIZE_PASS_BEGIN(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
INITIALIZE_PASS_END(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
false)
-ModulePass *llvm::createDXILLegalizeLegacyPass() {
+FunctionPass *llvm::createDXILLegalizeLegacyPass() {
return new DXILLegalizeLegacy();
}
diff --git a/llvm/lib/Target/DirectX/DXILLegalizePass.h b/llvm/lib/Target/DirectX/DXILLegalizePass.h
index dfa8124be7108..9d6d1cd19081d 100644
--- a/llvm/lib/Target/DirectX/DXILLegalizePass.h
+++ b/llvm/lib/Target/DirectX/DXILLegalizePass.h
@@ -15,7 +15,7 @@ namespace llvm {
class DXILLegalizePass : public PassInfoMixin<DXILLegalizePass> {
public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
};
} // namespace llvm
diff --git a/llvm/lib/Target/DirectX/DirectX.h b/llvm/lib/Target/DirectX/DirectX.h
index 98985db39fc61..96a8a08c875f8 100644
--- a/llvm/lib/Target/DirectX/DirectX.h
+++ b/llvm/lib/Target/DirectX/DirectX.h
@@ -52,7 +52,7 @@ void initializeDXILLegalizeLegacyPass(PassRegistry &);
/// Pass to Legalize DXIL by remove i8 truncations and i64 insert/extract
/// elements
-ModulePass *createDXILLegalizeLegacyPass();
+FunctionPass *createDXILLegalizeLegacyPass();
/// Initializer for DXILOpLowering
void initializeDXILOpLoweringLegacyPass(PassRegistry &);
diff --git a/llvm/lib/Target/DirectX/DirectXPassRegistry.def b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
index 473f142589d1f..87d91ead1896f 100644
--- a/llvm/lib/Target/DirectX/DirectXPassRegistry.def
+++ b/llvm/lib/Target/DirectX/DirectXPassRegistry.def
@@ -26,7 +26,6 @@ MODULE_ANALYSIS("dxil-root-signature-analysis", dxil::RootSignatureAnalysis())
MODULE_PASS("dxil-data-scalarization", DXILDataScalarization())
MODULE_PASS("dxil-flatten-arrays", DXILFlattenArrays())
MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion())
-MODULE_PASS("dxil-legalize", DXILLegalizePass())
MODULE_PASS("dxil-op-lower", DXILOpLowering())
MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs()))
MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata())
@@ -39,4 +38,5 @@ MODULE_PASS("print<dxil-root-signature>", dxil::RootSignatureAnalysisPrinter(dbg
#define FUNCTION_PASS(NAME, CREATE_PASS)
#endif
FUNCTION_PASS("dxil-resource-access", DXILResourceAccess())
+FUNCTION_PASS("dxil-legalize", DXILLegalizePass())
#undef FUNCTION_PASS
More information about the llvm-commits
mailing list