From: Dave Airlie <[email protected]>

SPIR-V defines the f32->f16 operation as flushing denormals to 0,
this compares the class using amd class opcode.

Thanks to Matt Arsenault for figuring it out.

This fixes:
dEQP-VK.spirv_assembly.instruction.compute.opquantize.flush_to_zero

Signed-off-by: Dave Airlie <[email protected]>
---
 src/amd/common/ac_nir_to_llvm.c |  9 ++++++++-
 src/amd/common/sid.h            | 13 +++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 77e3a85..ac80677 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1027,11 +1027,18 @@ static LLVMValueRef emit_f2f16(struct 
nir_to_llvm_context *ctx,
 {
        LLVMValueRef result;
        LLVMValueRef cond;
+       LLVMValueRef args[2];
        src0 = to_float(ctx, src0);
        result = LLVMBuildFPTrunc(ctx->builder, src0, ctx->f16, "");
-       result = ac_build_intrinsic(&ctx->ac, "llvm.canonicalize.f16", 
ctx->f16, &result, 1, AC_FUNC_ATTR_READNONE);
+       LLVMValueRef mask = LLVMConstInt(ctx->i32, N_SUBNORMAL | P_SUBNORMAL, 
false);
+       
+       args[0] = result;
+       args[1] = mask;
+       cond = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.class.f16", ctx->i1, 
args, 2, AC_FUNC_ATTR_READNONE);
+
        /* need to convert back up to f32 */
        result = LLVMBuildFPExt(ctx->builder, result, ctx->f32, "");
+       result = LLVMBuildSelect(ctx->builder, cond, ctx->f32zero, result, "");
        return result;
 }
 
diff --git a/src/amd/common/sid.h b/src/amd/common/sid.h
index 7789add..fa20690 100644
--- a/src/amd/common/sid.h
+++ b/src/amd/common/sid.h
@@ -9063,5 +9063,18 @@
 #define    CIK_SDMA_PACKET_SRBM_WRITE              0xe
 #define    CIK_SDMA_COPY_MAX_SIZE                  0x3fffe0
 
+enum amd_cmp_class_flags {
+       S_NAN = 1 << 0,        // Signaling NaN
+       Q_NAN = 1 << 1,        // Quiet NaN
+       N_INFINITY = 1 << 2,   // Negative infinity
+       N_NORMAL = 1 << 3,     // Negative normal
+       N_SUBNORMAL = 1 << 4,  // Negative subnormal
+       N_ZERO = 1 << 5,       // Negative zero
+       P_ZERO = 1 << 6,       // Positive zero
+       P_SUBNORMAL = 1 << 7,  // Positive subnormal
+       P_NORMAL = 1 << 8,     // Positive normal
+       P_INFINITY = 1 << 9    // Positive infinity
+};
+
 #endif /* _SID_H */
 
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to