[RFC] [BZ15384] Enchance finite and isfinite.

Ondřej Bílka neleai@seznam.cz
Fri Apr 26 16:25:00 GMT 2013


On Sun, Apr 21, 2013 at 08:41:33PM +0200, Marc Glisse wrote:
> On Sun, 21 Apr 2013, Ondřej Bílka wrote:
> 
> >On Sun, Apr 21, 2013 at 03:35:19PM +0200, Marc Glisse wrote:
> >>On Sun, 21 Apr 2013, Ondřej Bílka wrote:
> >>>However on x64 even gcc without optimizations expands finite to inline
> >>>version which is slower than my version(see benchmark).
> >>

Following should generic version be tried on other archs. I could get
20% speedup on sparc on this benchmark. 

run with
for i in `seq 0 7`; do echo finite$i;  gcc finite_bench.c -O3 -Wall -W -fno-builtin-finite -Dfinite=finite$i; for j in `seq 1 8`; do /usr/bin/time -f "%U" ./a.out; done; done
-------------- next part --------------
#include <stdint.h>
#include <math.h>

typedef union
{
  double value;
  struct
  {
    uint32_t lsw;
    uint32_t msw;
  } parts;
  uint64_t word;
} ieee_double_shape_type;
# define GET_HIGH_WORD(i,d)                                     \
  do {                                                            \
    ieee_double_shape_type gh_u;                                  \
    gh_u.value = (d);                                             \
    (i) = gh_u.parts.msw;                                         \
  } while (0)
#define EXTRACT_WORDS64(i, d)                                                 \
  do {                                                                        \
    ieee_double_shape_type gh_u;                                  \
    gh_u.value = (d);                                             \
    (i) = gh_u.word;                                         \
  } while (0)
int finite0(double x)
{
  int32_t hx;
  GET_HIGH_WORD(hx,x);
  return (int)((uint32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
}
int finite1(double x)
{
  int32_t hx;
  GET_HIGH_WORD(hx,x);
  return (int)((uint32_t)((hx&0x7ff00000)-0x7ff00000)>>31);
}
int finite2(double x)
{
  int64_t lx;
  EXTRACT_WORDS64(lx,x);
  return (int)((uint64_t)((lx&INT64_C(0x7ff0000000000000))-INT64_C(0x7ff0000000000000))>>63);
}
uint64_t finite3(double x)
{
  int64_t lx;
  EXTRACT_WORDS64(lx,x);
  return (lx&INT64_C(0x7ff0000000000000))!=INT64_C(0x7ff0000000000000);
}
int finite4(double x)
{
  uint64_t lx;
  EXTRACT_WORDS64(lx,x);
  lx=lx>>52;
  return (((lx&0x7ff)==0x7ff));

}
int finite5(double x)
{
  double y=x-x;
  return y==y;
}
int finite6(double x)
{
  return __builtin_finite(x);
}


int finite7(double x)
{
  uint64_t lx;
  EXTRACT_WORDS64(lx,x);
  lx=lx>>52;
  return ((((lx+1)&0x7ff));

}

double finite_wrap(double x) __attribute__((noinline,noclone));
double finite_wrap(double x){
	if(finite(x)) return 0;
	else return x;
}

int main(){

  int i;
	int r;
  double x=3;
  double cnt=0;
  for(i=0;i<100000000;i++) {
    cnt+=finite_wrap(x);
    x+=0.323;
  }
	if (cnt==1)
  return 1;
	else return 0;
}


More information about the Libc-alpha mailing list