microsoft / microsoft/DirectXShaderCompiler
[ScopeNestedCFG] Basic Blocks are cloned when containing convergent ops
Open
@bob80905 is already working on this.
Since Feb 9, 2026.
bug
- Dominant language
- C++
- Stars
- 3.7k
- Forks
- 900
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 44
Description
Description
Basic blocks containing convergent ops are being cloned, causing there to be multiple convergent ops, more than the original source. This is bad.
Steps to Reproduce
Run opt.exe on this IR:
; RUN: %opt-exe %s -scopenested -S | FileCheck %s
declare float @dx.wave.op(float) convergent
define void @CSMain(i32 %tid, float %v) convergent {
entry:
switch i32 %tid, label %exit [
i32 0, label %case0
i32 1, label %case1
]
case0: ; switch case 0
%w0 = call float @dx.wave.op(float %v)
br label %case1 ; FALLTHROUGH
case1: ; switch case 1
%a = phi float [ %w0, %case0 ],
[ 0.0, %entry ]
%w1 = call float @dx.wave.op(float %v)
%sum = fadd float %a, %w1
br label %exit
exit:
%r = phi float [ %sum, %case1 ],
[ 0.0, %entry ]
ret void
}
Actual Behavior
The observed issue is that there are 3 calls to the abstract wave op instruction, rather than the expected 2.
This can be seen here:
; ModuleID = 'C:\temp\min.ll'
; Function Attrs: convergent
declare float @dx.wave.op(float) #0
; Function Attrs: convergent
define void @CSMain(i32 %tid, float %v) #0 {
entry:
switch i32 %tid, label %dx.EndSwitchScope [
i32 0, label %case0
i32 1, label %case1.4
], !dx.BranchKind !0
case0: ; preds = %entry
%w0 = call float @dx.wave.op(float %v)
br label %case1
case1: ; preds = %case0
%a = phi float [ %w0, %case0 ], [ 0.000000e+00, %entry ]
%w1 = call float @dx.wave.op(float %v)
%sum = fadd float %a, %w1
br label %dx.SwitchBreak
case1.4: ; preds = %entry
%a.1 = phi float [ %w0, %case0 ], [ 0.000000e+00, %entry ]
%w1.2 = call float @dx.wave.op(float %v)
%sum.3 = fadd float %a.1, %w1.2
br label %dx.SwitchBreak.5
dx.EndSwitchScope: ; preds = %dx.SwitchBreak.5, %dx.SwitchBreak, %entry
br label %exit, !dx.BranchKind !1
dx.SwitchBreak: ; preds = %case1
br label %dx.EndSwitchScope, !dx.BranchKind !2
dx.SwitchBreak.5: ; preds = %case1.4
br label %dx.EndSwitchScope, !dx.BranchKind !2
exit: ; preds = %dx.EndSwitchScope
%r = phi float [ %sum, %case1 ], [ 0.000000e+00, %entry ]
ret void
}
attributes #0 = { convergent }
!0 = !{i32 4}
!1 = !{i32 5}
!2 = !{i32 7}
Environment
- DXC version: dxcompiler.dll: 1.10(5196-98bc4c27)(1.8.0.5070) - 1.8.0.5070 (move_coop_vec_feature_to_610, 55805c7f6815-dirty)
- Host Operating System Windows 11 Version 10.0.26200 Build 26200
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.