Skip to content

Commit 5bdf5f8

Browse files
authored
instcombine pass before jumpthread for lifetimes (microsoft#4459)
Lifetime markers require a cleanup pass to eliminate some unnecessary code, however one of those passes was JumpThreading, which only eliminated certain dead blocks, which eliminated phi instructions leaving looped self increments unconditionally incrementing themselves, which ended up with infinite recursion when trying to process that instruction. By adding Instcombining first, all unreachable blocks are elimianted first so the partial elimination doesn't leave such bad phi users. To avoid losing convergence for DXIL specific operations, we must first run the convergent marker pass, so these passes are moved a little later than before.
1 parent 95da6e7 commit 5bdf5f8

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

lib/Transforms/IPO/PassManagerBuilder.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,19 +260,19 @@ static void addHLSLPasses(bool HLSLHighLevel, unsigned OptLevel, bool OnlyWarnOn
260260
MPM.add(createDxilConditionalMem2RegPass(NoOpt));
261261
MPM.add(createDxilDeleteRedundantDebugValuesPass());
262262

263-
// Clean up inefficiencies that can cause unnecessary live values related to
264-
// lifetime marker cleanup blocks. This is the earliest possible location
265-
// without interfering with HLSL-specific lowering.
266-
if (!NoOpt && EnableLifetimeMarkers) {
267-
MPM.add(createSROAPass());
268-
MPM.add(createJumpThreadingPass());
269-
}
270-
271263
// Remove unneeded dxbreak conditionals
272264
MPM.add(createCleanupDxBreakPass());
273265

274266
if (!NoOpt) {
275267
MPM.add(createDxilConvergentMarkPass());
268+
// Clean up inefficiencies that can cause unnecessary live values related to
269+
// lifetime marker cleanup blocks. This is the earliest possible location
270+
// without interfering with HLSL-specific lowering.
271+
if (EnableLifetimeMarkers) {
272+
MPM.add(createSROAPass());
273+
MPM.add(createInstructionCombiningPass());
274+
MPM.add(createJumpThreadingPass());
275+
}
276276
}
277277

278278
if (!NoOpt)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %dxc -T ps_6_6 %s | FileCheck %s
2+
3+
// Check a shader that previously resulted in a self-referencial add instruction
4+
// when the PHI it previously drew from was eliminated due to poor dead basic block elimination
5+
// The end result is a really dumb shader because most of the code is dead
6+
7+
// CHECK: define void @main()
8+
// CHECK: call void @dx.op.storeOutput.f32(i32 5
9+
// CHECK-NEXT: ret void
10+
11+
float main (uint2 param : P) : SV_Target {
12+
13+
bool yes = true;
14+
15+
// Trivially dead conditional block that becomes several basic blocks
16+
// If BB elimination passes aren't done in the right order,
17+
// Only some of the unused blocks could be destroyed and update the phi users incorrectly
18+
if (!yes) {
19+
for (int i = 0; i < 1; i++) {
20+
// Force a PHI by breaking the block up
21+
if (param.y)
22+
break;
23+
// This will use a PHI that, when the inital loop block is eliminated,
24+
// could end up unconditionally adding to itself
25+
++param.x;
26+
}
27+
}
28+
return 0;
29+
}

0 commit comments

Comments
 (0)