This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/11706] std::pow(T, int) implementation pessimizes code


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11706



------- Additional Comments From rguenth at tat dot physik dot uni-tuebingen dot de  2003-07-29 12:53 -------
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

> Richard, can you test this and see if it helps?  It's still not as good as
> pow(x,2)->x*x but it's darn close and with loop unrolling it might even get to that.

It helps, as now all calls to __cmath_power are inlined at -O2 with
gcc3.4, but this is not what we want, I think. Look at the following
testcase:

  template<typename _Tp>
    inline _Tp
    __cmath_power(_Tp __x, unsigned int __n)
    {
      _Tp __y = __n % 2 ? __x : 1;

      while (__n >>= 1)
        {
          __x = __x * __x;
          if (__n % 2)
            __y = __y * __x;
        }

      return __y;
    }

  template<typename _Tp>
    inline _Tp
    __pow_helper(_Tp __x, int __n)
    {
      return __n < 0
        ? _Tp(1)/__cmath_power(__x, -__n)
        : __cmath_power(__x, __n);
    }

double foo0(double x)
{
        return pow(x, 0);
}
double foo1(double x)
{
        return pow(x, 1);
}
double foo2(double x)
{
        return pow(x, 2);
}
double foo3(double x)
{
        return pow(x, 3);
}

This creates (with -O2 -funroll-loops -ffast-math):

.globl _Z4foo0d
        .type   _Z4foo0d, @function
_Z4foo0d:
.LFB8:
        pushl   %ebp    #
.LCFI0:
        movl    %esp, %ebp      #,
.LCFI1:
        fld1
        popl    %ebp    #
        ret

nice.

.globl _Z4foo1d
        .type   _Z4foo1d, @function
_Z4foo1d:
.LFB10:
        pushl   %ebp    #
.LCFI2:
        movl    %esp, %ebp      #,
.LCFI3:
        fldl    8(%ebp) # x
        popl    %ebp    #
        ret

nice.

_Z4foo2d:
.LFB12:
        pushl   %ebp    #
.LCFI4:
        movl    %esp, %ebp      #,
.LCFI5:
        fldl    8(%ebp) # x
        fld1
        movl    $1, %eax        #, __n
        jmp     .L62    #
        .p2align 4,,7
.L73:
        fxch    %st(1)  #
.L62:
        fxch    %st(1)  #
        testb   $1, %al #, __n
        fmul    %st(0), %st     #,
        je      .L59    #,
        fmul    %st, %st(1)     #,
.L59:
        shrl    %eax    # __n
        jne     .L73    #,
        fstp    %st(0)  #
        popl    %ebp    #
        ret

WTF? It seems CSE/GCSE/CPROP dont do their jobs. We dont want to inline
in the case we get to the loop implementation.

The proper fix is to use __builtin_constant_p() for selected __n.

Richard.

--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]