-
Notifications
You must be signed in to change notification settings - Fork 51
Description
Is your feature request related to a problem? Please describe.
Not sure exactly what to call this, but I want to talk about this section of the HLSL specification. This is one of the few places in the specification that explicitly says that code of this type is invalid.
The rationale for why this code is invalid is a bit stretched, and suggests that an optimizer doing lifetime analysis might reuse registers between two edges of a branch.
Describe the solution you'd like
I'd like the code provided to be valid, and for it to be invalid for an optimizer to shuffle lifetime/registers in a way that modifies wave uniformity concerns. I want this to be valid:
float2 temp_uv = modifyuv(uv);
if (pos.x <= SCREEN_UV) {
ret = tex.Sample(s0, temp_uv);
}
while I am OK with this remaining invalid:
if (pos.x <= SCREEN_UV) {
float2 temp_uv = modifyuv(uv);
ret = tex.Sample(s0, temp_uv);
}
That is, lexical scoping defines the uniformity. If a value is lexically calculated or assigned outside a branch, moving it inside a branch is an invalid optimization when it might affect derivatives/wave uniformity.
It is getting exceptionally difficult to write code that behaves the way I want in the presence of control flow, wave intrinsics, and optimizing compilers, and would like some guarantees that doesn't feel like I'm building on top of quicksand.
Describe alternatives you've considered
If we consider it too costly to make this code valid and want it to remain invalid, then I would like some more concrete specifications and rules for why this code is valid or invalid, and what guarantees we do have, and would like to talk about more language extensions so we can be more explicit (pragmas? annotations?)
"Don't mix wave/texturing operations and control flow" isn't actionable advice.
Additional context
This intersects with other HLSL work on uniformity, NURI, and maximal reconvergence.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status