Special float NaN/Inf checks on fp16 types are implicitly extended to fp32
Description
It seems that any fp16 NaN/Inf check with dx.op.isSpecialFloat is implicitly extended (fpext) to dx.op.isSpecialFloat.f32.
Validation seems to accept dx.op.isSpecialFloat.f16 with a fully signed shader. However, certain vendor/drivers crash on dx.op.isSpecialFloat.f16, despite it seeming valid. I assume due to lack of test coverage. If I mirror this extension myself, fpext -> dx.op.isSpecialFloat.f32, all's well.
Steps to Reproduce
Compile the below with "-T lib_6_5 -enable-16bit-types".
export bool Foo(half v) {
return isinf(v);
}
export bool Foo(float v) {
return isinf(v);
}
https://godbolt.org/z/hYvoesxjf
Actual Behavior
Notice the fpext:
define i1 @"\01?Foo@@YA_N$f16@@Z"(half %v) #0 {
%1 = fpext half %v to float
%IsInf = call i1 @dx.op.isSpecialFloat.f32(i32 9, float %1)
ret i1 %IsInf
}
; Function Attrs: nounwind readnone
define i1 @"\01?Foo@@YA_NM@Z"(float %v) #0 {
%IsInf = call i1 @dx.op.isSpecialFloat.f32(i32 9, float %v)
ret i1 %IsInf
}
Environment
- DXC version - 1.8.2502
- Host Operating System - Windows 11 24H2
We've identified a problem generating the fp16 overloads of IsSpecialFloat on a lot of drivers in the market today. I've filed an issue on our specs repo to track fixing SM 6.9 (https://github.com/microsoft/hlsl-specs/issues/521). In the meantime we can teach DXC (and Clang) to emulate the operation with LLVM IR instructions.
I've closed this issue, but the validator, as pointed out here, needs to be updated still to disallow ' dx.op.isSpecialFloat.f16' in SM6.8 and before.