From 71961c73a94ceca9dbeb8718acbe2c3c7a7ee717 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 18 Feb 2020 12:34:15 -0800 Subject: [PATCH] nir: Correctly constant fold fsign(NaN) and fsign(-0) GLSL and SPIR-V GLSL.std.450 don't have any requirements for fsign(NaN), and both only require that FSign(-0.0) == 0.0. OpenCL, on the other hand, requires sign(-0.0) be exactly -0.0. It also requires that sign(NaN) be exactly 0.0. In practice, this change is difficult to test. Our GLSL frontend already constant folds sign(NaN) to 0.0 before even getting to NIR. As far as I can tell, glslang does the same. I don't have a good way to run an OpenCL SPIR-V test. Maybe SPIR-V GLSL.std.450 assembly? No shader-db or fossil-db changes on any Intel platform. Acked-by: Rhys Perry Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- src/compiler/nir/nir_opcodes.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py index bc0c7fe2c0b..6a16e280d0c 100644 --- a/src/compiler/nir/nir_opcodes.py +++ b/src/compiler/nir/nir_opcodes.py @@ -208,11 +208,11 @@ unop("inot", tint, "~src0") # invert every bit of the integer # number, and the result is not +0.0, the result should definitely **not** be # NaN. # -# fsign(NaN) = (False ? 0.0 : (False ? 1.0 : -1.0) = -1.0. This is allowed by -# the spec, but it is not the preferred value. +# The values returned for constant folding match the behavior required by +# OpenCL. unop("fsign", tfloat, ("bit_size == 64 ? " + - "((src0 == 0.0) ? 0.0 : ((src0 > 0.0) ? 1.0 : -1.0)) : " + - "((src0 == 0.0f) ? 0.0f : ((src0 > 0.0f) ? 1.0f : -1.0f))")) + "(isnan(src0) ? 0.0 : ((src0 == 0.0 ) ? src0 : (src0 > 0.0 ) ? 1.0 : -1.0 )) : " + + "(isnan(src0) ? 0.0f : ((src0 == 0.0f) ? src0 : (src0 > 0.0f) ? 1.0f : -1.0f))")) unop("isign", tint, "(src0 == 0) ? 0 : ((src0 > 0) ? 1 : -1)") unop("iabs", tint, "(src0 < 0) ? -src0 : src0") unop("fabs", tfloat, "fabs(src0)")