DXC does not eliminate wave intrinsic calls even when the result is unused
Description The wave intrinsics are kept in the final dxil but I would expect them to be removed by DCE.
Steps to Reproduce
https://shader-playground.timjones.io/350a97df5de025ead832c7054409a7aa
// dxc /T ps_6_0 t.hlsl
[RootSignature("")]
void main(int a : A) {
(void)WaveReadLaneFirst(a);
}
Actual Behavior
The output of WaveReadLaneFirst is unused, but the intrinsic call is still there in the dxil.
define void @main() {
%1 = call i32 @dx.op.loadInput.i32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = call i32 @dx.op.waveReadLaneFirst.i32(i32 118, i32 %1) ; WaveReadLaneFirst(value)
ret void
}
Environment
- DXC version
Version: dxcompiler.dll: 1.6 - 1.6.2104.52 (e09a454eb); dxil.dll: 1.6(101.6.2104.33). Also repros on shader-playground with dxc trunc. - Host Operating System
Windows
Related PR: #5559
Related issues: #5302, #5034, #5177
I've marked this as a correctness issue. While in this case it is more an optimization issue, I'm not convinced that there isn't a correctness bug lurking here too.
I don't think #5302 is related to this same issue. The underlying issue there is that we are only applying the dx.break fix to PS/CS/LIB targets.
https://github.com/microsoft/DirectXShaderCompiler/issues/5302#issuecomment-1597605713
In tools/clang/lib/CodeGen/CGHLSLMS.cpp, in function EmitHLSLCondBreak, around line 4660:
if (!m_pHLModule->GetShaderModel()->IsPS() && !m_pHLModule->GetShaderModel()->IsCS() && !m_pHLModule->GetShaderModel()->IsLib()) { return CGF.Builder.CreateBr(DestBB); }
Thanks @dmpots! I just did a quick skim during triage and didn't have full context but wanted to leave breadcrumbs.