Skip to content

Commit 5d8498f

Browse files
committed
[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%.
1 parent 08aedf7 commit 5d8498f

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

llvm/lib/Target/DirectX/DXILLegalizePass.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/IR/IRBuilder.h"
1313
#include "llvm/IR/InstIterator.h"
1414
#include "llvm/IR/Instruction.h"
15+
#include "llvm/IR/Module.h"
1516
#include "llvm/Pass.h"
1617
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
1718
#include <functional>
@@ -20,6 +21,12 @@
2021

2122
using namespace llvm;
2223

24+
static void removeDeadIntrinsics(Function &F,
25+
SmallVectorImpl<Function *> &ToRemove) {
26+
if (F.isIntrinsic() && F.use_empty())
27+
ToRemove.push_back(&F);
28+
}
29+
2330
static void fixI8TruncUseChain(Instruction &I,
2431
SmallVectorImpl<Instruction *> &ToRemove,
2532
DenseMap<Value *, Value *> &ReplacedValues) {
@@ -146,11 +153,26 @@ class DXILLegalizationPipeline {
146153
public:
147154
DXILLegalizationPipeline() { initializeLegalizationPipeline(); }
148155

149-
bool runLegalizationPipeline(Function &F) {
156+
bool runLegalizationPipeline(Module &M) {
157+
bool Changes = false;
158+
SmallVector<Function *> ToRemove;
159+
for (auto &F : make_early_inc_range(M.functions())) {
160+
Changes |= runFunctionLegalizationPipeline(F);
161+
for (auto &LegalizationFn : ModuleLegalizationPipeline)
162+
LegalizationFn(F, ToRemove);
163+
}
164+
165+
for (Function *F : ToRemove)
166+
F->eraseFromParent();
167+
168+
return Changes && !ToRemove.empty();
169+
}
170+
171+
bool runFunctionLegalizationPipeline(Function &F) {
150172
SmallVector<Instruction *> ToRemove;
151173
DenseMap<Value *, Value *> ReplacedValues;
152174
for (auto &I : instructions(F)) {
153-
for (auto &LegalizationFn : LegalizationPipeline)
175+
for (auto &LegalizationFn : FunctionLegalizationPipeline)
154176
LegalizationFn(I, ToRemove, ReplacedValues);
155177
}
156178

@@ -164,37 +186,40 @@ class DXILLegalizationPipeline {
164186
SmallVector<
165187
std::function<void(Instruction &, SmallVectorImpl<Instruction *> &,
166188
DenseMap<Value *, Value *> &)>>
167-
LegalizationPipeline;
189+
FunctionLegalizationPipeline;
190+
SmallVector<std::function<void(Function &, SmallVectorImpl<Function *> &)>>
191+
ModuleLegalizationPipeline;
168192

169193
void initializeLegalizationPipeline() {
170-
LegalizationPipeline.push_back(fixI8TruncUseChain);
171-
LegalizationPipeline.push_back(downcastI64toI32InsertExtractElements);
194+
FunctionLegalizationPipeline.push_back(fixI8TruncUseChain);
195+
FunctionLegalizationPipeline.push_back(
196+
downcastI64toI32InsertExtractElements);
197+
ModuleLegalizationPipeline.push_back(removeDeadIntrinsics);
172198
}
173199
};
174200

175-
class DXILLegalizeLegacy : public FunctionPass {
201+
class DXILLegalizeLegacy : public ModulePass {
176202

177203
public:
178-
bool runOnFunction(Function &F) override;
179-
DXILLegalizeLegacy() : FunctionPass(ID) {}
204+
bool runOnModule(Module &M) override;
205+
DXILLegalizeLegacy() : ModulePass(ID) {}
180206

181207
static char ID; // Pass identification.
182208
};
183209
} // namespace
184210

185-
PreservedAnalyses DXILLegalizePass::run(Function &F,
186-
FunctionAnalysisManager &FAM) {
211+
PreservedAnalyses DXILLegalizePass::run(Module &M, ModuleAnalysisManager &MAM) {
187212
DXILLegalizationPipeline DXLegalize;
188-
bool MadeChanges = DXLegalize.runLegalizationPipeline(F);
213+
bool MadeChanges = DXLegalize.runLegalizationPipeline(M);
189214
if (!MadeChanges)
190215
return PreservedAnalyses::all();
191216
PreservedAnalyses PA;
192217
return PA;
193218
}
194219

195-
bool DXILLegalizeLegacy::runOnFunction(Function &F) {
220+
bool DXILLegalizeLegacy::runOnModule(Module &M) {
196221
DXILLegalizationPipeline DXLegalize;
197-
return DXLegalize.runLegalizationPipeline(F);
222+
return DXLegalize.runLegalizationPipeline(M);
198223
}
199224

200225
char DXILLegalizeLegacy::ID = 0;
@@ -204,6 +229,6 @@ INITIALIZE_PASS_BEGIN(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
204229
INITIALIZE_PASS_END(DXILLegalizeLegacy, DEBUG_TYPE, "DXIL Legalizer", false,
205230
false)
206231

207-
FunctionPass *llvm::createDXILLegalizeLegacyPass() {
232+
ModulePass *llvm::createDXILLegalizeLegacyPass() {
208233
return new DXILLegalizeLegacy();
209234
}

llvm/lib/Target/DirectX/DXILLegalizePass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace llvm {
1515

1616
class DXILLegalizePass : public PassInfoMixin<DXILLegalizePass> {
1717
public:
18-
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
18+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
1919
};
2020
} // namespace llvm
2121

llvm/lib/Target/DirectX/DirectX.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ void initializeDXILLegalizeLegacyPass(PassRegistry &);
5252

5353
/// Pass to Legalize DXIL by remove i8 truncations and i64 insert/extract
5454
/// elements
55-
FunctionPass *createDXILLegalizeLegacyPass();
55+
ModulePass *createDXILLegalizeLegacyPass();
5656

5757
/// Initializer for DXILOpLowering
5858
void initializeDXILOpLoweringLegacyPass(PassRegistry &);

llvm/lib/Target/DirectX/DirectXPassRegistry.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ MODULE_ANALYSIS("dxil-root-signature-analysis", dxil::RootSignatureAnalysis())
2626
MODULE_PASS("dxil-data-scalarization", DXILDataScalarization())
2727
MODULE_PASS("dxil-flatten-arrays", DXILFlattenArrays())
2828
MODULE_PASS("dxil-intrinsic-expansion", DXILIntrinsicExpansion())
29+
MODULE_PASS("dxil-legalize", DXILLegalizePass())
2930
MODULE_PASS("dxil-op-lower", DXILOpLowering())
3031
MODULE_PASS("dxil-pretty-printer", DXILPrettyPrinterPass(dbgs()))
3132
MODULE_PASS("dxil-translate-metadata", DXILTranslateMetadata())
@@ -38,5 +39,4 @@ MODULE_PASS("print<dxil-root-signature>", dxil::RootSignatureAnalysisPrinter(dbg
3839
#define FUNCTION_PASS(NAME, CREATE_PASS)
3940
#endif
4041
FUNCTION_PASS("dxil-resource-access", DXILResourceAccess())
41-
FUNCTION_PASS("dxil-legalize", DXILLegalizePass())
4242
#undef FUNCTION_PASS
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
; RUN: llc %s -mtriple=dxil-pc-shadermodel6.3-library --filetype=asm -o - | FileCheck %s
3+
4+
declare void @llvm.lifetime.start.p0(i64, ptr) #1
5+
declare void @llvm.lifetime.end.p0(i64, ptr) #1
6+
declare i32 @llvm.dx.udot.v4i32(<4 x i32>, <4 x i32>) #2
7+
declare void @llvm.memset.p0.i32(ptr, i8, i32, i1) #3
8+
9+
; CHECK-NOT: declare void @llvm.lifetime.start.p0(i64, ptr)
10+
; CHECK-NOT: declare void @llvm.lifetime.end.p0(i64, ptr)
11+
; CHECK-NOT: declare i32 @llvm.dx.udot.v4i32(<4 x i32>, <4 x i32>)
12+
; CHECK-NOT: declare void @llvm.memset.p0.i32(ptr, i8, i32, i1)
13+
14+
; CHECK-LABEL: empty_fn
15+
define void @empty_fn () local_unnamed_addr #0 {
16+
ret void
17+
}
18+
19+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
20+
attributes #1 = { nounwind memory(argmem: readwrite) }
21+
attributes #2 = { nounwind memory(none) }
22+
attributes #3 = { nounwind memory(argmem: write) }

0 commit comments

Comments
 (0)