[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