D144 - The division pre-scale needs no float controls, and could not have had them

Status: decided (measured on hardware)

D143 left v_div_scale_f32 blocked on what looked like a capability problem: two of its branches ask whether a computed quotient is subnormal, Vulkan lets an implementation flush subnormals to zero, and the fix appeared to be requesting SPV_KHR_float_controls.

The device does not support it. The first thing the new device report said was subnormals flushed - shaderDenormPreserveFloat32 is false on this hardware, which is ordinary for this vendor. Declaring the capability would not have preserved anything; it would have made every module unloadable.

It does not matter. A flushed subnormal and a preserved one give the same answer to the question being asked, because the question is only ever asked where the true result cannot be zero - a reciprocal of a finite non-zero value, or a quotient with a non-zero numerator, both guaranteed by branches that run first. Zero and subnormal share an all-zero exponent field, so one test on the bits answers it on either kind of device:

Testing the bits rather than doing a comparison is what makes this hold - a comparison against the smallest normal would itself be at the mercy of how a flushed operand compares.

So the sequence is translated in full, and it is more portable than the float-controls route would have been: it needs no extension, no capability, and no device support.

The device report stays anyway. It is what found this, and the subgroup width it also carries is what the next piece of work is built on. Asking a device what it can do is worth doing even when the answer turns out to be "not that".

What the reference does not say. The pre-scale's zero-operand branch is written D.f = NAN with no bit pattern, where the fixup gives one explicitly. The canonical quiet NaN is used and the difference is unobservable: this result feeds the reciprocal and then the fixup, which replaces any NaN with a quietened operand of its own.