[Mesa-dev] [PATCH] llvmpipe: fix lp_test_arit denorm handling

Jose Fonseca jfonseca at vmware.com
Mon Nov 24 14:51:37 PST 2014


Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

Jose

On 24/11/14 22:37, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> llvmpipe disables denorms on purpose (on x86/sse only), because denorms are
> generally neither required nor desired for graphic apis (and in case of d3d10,
> they are forbidden).
> However, this caused some arithmetic tests using denorms to fail on some
> systems, because the reference did not generate the same results anymore.
> (It did not fail on all systems - behavior of these math functions is sort
> of undefined when called with non-standard floating point mode, hence the
> result differing depending on implementation and in particular the sse
> capabilities.)
> So, for the reference, simply flush all (input/output) denorms manually
> to zero in this case.
>
> This fixes https://bugs.freedesktop.org/show_bug.cgi?id=67672.
> ---
>   src/gallium/drivers/llvmpipe/lp_test_arit.c | 38 ++++++++++++++++++++++++++++-
>   1 file changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/drivers/llvmpipe/lp_test_arit.c b/src/gallium/drivers/llvmpipe/lp_test_arit.c
> index 3fc64ce..290c523 100644
> --- a/src/gallium/drivers/llvmpipe/lp_test_arit.c
> +++ b/src/gallium/drivers/llvmpipe/lp_test_arit.c
> @@ -33,6 +33,7 @@
>   #include "util/u_pointer.h"
>   #include "util/u_memory.h"
>   #include "util/u_math.h"
> +#include "util/u_cpu_detect.h"
>
>   #include "gallivm/lp_bld.h"
>   #include "gallivm/lp_bld_debug.h"
> @@ -333,6 +334,38 @@ build_unary_test_func(struct gallivm_state *gallivm,
>
>
>   /*
> + * Flush denorms to zero.
> + */
> +static float
> +flush_denorm_to_zero(float val)
> +{
> +   /*
> +    * If we have a denorm manually set it to (+-)0.
> +    * This is because the reference may or may not do the right thing
> +    * otherwise because we want the result according to treating all
> +    * denormals as zero (FTZ/DAZ). Not using fpclassify because
> +    * a) some compilers are stuck at c89 (msvc)
> +    * b) not sure it reliably works with non-standard ftz/daz mode
> +    * And, right now we only disable denorms with jited code on x86/sse
> +    * (albeit this should be classified as a bug) so to get results which
> +    * match we must only flush them to zero here in that case too.
> +    */
> +   union fi fi_val;
> +
> +   fi_val.f = val;
> +
> +#if defined(PIPE_ARCH_SSE)
> +   if (util_cpu_caps.has_sse) {
> +      if ((fi_val.ui & 0x7f800000) == 0) {
> +         fi_val.ui &= 0xff800000;
> +      }
> +   }
> +#endif
> +
> +   return fi_val.f;
> +}
> +
> +/*
>    * Test one LLVM unary arithmetic builder function.
>    */
>   static boolean
> @@ -374,10 +407,13 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test)
>
>         test_func_jit(out, in);
>         for (i = 0; i < num_vals; ++i) {
> -         float ref = test->ref(in[i]);
> +         float testval, ref;
>            double error, precision;
>            bool pass;
>
> +         testval = flush_denorm_to_zero(in[i]);
> +         ref = flush_denorm_to_zero(test->ref(testval));
> +
>            if (util_inf_sign(ref) && util_inf_sign(out[i]) == util_inf_sign(ref)) {
>               error = 0;
>            } else {
>



More information about the mesa-dev mailing list