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

Jose Fonseca jfonseca at vmware.com
Mon Sep 17 13:33:27 PDT 2012



----- Original Message -----
> 
> 
> ----- 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.

Nevermind. DIFFERENT_SIGNS(-0.0f, 0.0f) returns false and your code is correct.

Jose


More information about the mesa-dev mailing list