[Mesa-dev] [PATCH] Use signbit() in IS_NEGATIVE and DIFFERENT_SIGNS

Jose Fonseca jfonseca at vmware.com
Mon Sep 17 13:20:11 PDT 2012



----- Original Message -----
> signbit() appears to be available everywhere (even MSVC according to
> MSDN), so let's use it instead of open-coding some messy and
> confusing
> bit twiddling macros.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54805
> Cc: Alan Coopersmith <alan.coopersmith at oracle.com>
> Suggested-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
> I'd prefer to see if we can use this everywhere before we decide to
> keep
> the open-coded macros around for other platforms.
> 
> Alan, does this work for you on Solaris?
> 
>  configure.ac           |    7 +++++++
>  src/mesa/main/macros.h |   21 ++-------------------
>  2 files changed, 9 insertions(+), 19 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 4193496..f23bfb8 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -499,6 +499,13 @@ AC_SUBST([DLOPEN_LIBS])
>  dnl See if posix_memalign is available
>  AC_CHECK_FUNC([posix_memalign], [DEFINES="$DEFINES
>  -DHAVE_POSIX_MEMALIGN"])
>  
> +dnl signbit() is a macro in glibc's math.h, so AC_CHECK_FUNC fails.
> To handle
> +dnl this, use AC_CHECK_DECLS and fallback to AC_CHECK_FUNC in case
> it fails.
> +AC_CHECK_DECLS([signbit],[],
> +               AC_CHECK_FUNC([signbit],[],
> +                             AC_MSG_ERROR([could not find
> signbit()])),
> +               [#include <math.h>])
> +
>  dnl SELinux awareness.
>  AC_ARG_ENABLE([selinux],
>      [AS_HELP_STRING([--enable-selinux],
> diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
> index 04d59d7..7b7fd1b 100644
> --- a/src/mesa/main/macros.h
> +++ b/src/mesa/main/macros.h
> @@ -693,31 +693,14 @@ NORMALIZE_3FV(GLfloat v[3])
>  static inline GLboolean
>  IS_NEGATIVE(float x)
>  {
> -#if defined(USE_IEEE)
> -   fi_type fi;
> -   fi.f = x;
> -   return fi.i < 0;
> -#else
> -   return x < 0.0F;
> -#endif
> +   return signbit(x) != 0;
>  }

I'd vote by simply using "x < 0.0F". A modern compiler should generate the best code for that instruction already.

Furthermore signbit(-0.0f) != signbit(0.0f)

>  /** Test two floats have opposite signs */
>  static inline GLboolean
>  DIFFERENT_SIGNS(GLfloat x, GLfloat y)
>  {
> -#if defined(USE_IEEE)
> -   fi_type xfi, yfi;
> -   xfi.f = x;
> -   yfi.f = y;
> -   return !!((xfi.i ^ yfi.i) & (1u << 31));
> -#else
> -   /* Could just use (x*y<0) except for the flatshading
> requirements.
> -    * Maybe there's a better way?
> -    */
> -   return ((x) * (y) <= 0.0F && (x) - (y) != 0.0F);
> -#endif
> +   return signbit(x) != signbit(y);

This is not the same thing: DIFFERENT_SIGNS(-0.0f, 0.0f) was returning false, and now it will return TRUE.

For me, replacing the current code with signbit seems a waste of time. I'd much prefer leave it alone (given it is known to work as is), or just use normal floating point operators.

Jose


More information about the mesa-dev mailing list