[Bug libstdc++/11706] std::pow(T, int) implementation pessimizes code
rguenth at tat dot physik dot uni-tuebingen dot de
gcc-bugzilla@gcc.gnu.org
Tue Jul 29 12:53:00 GMT 2003
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/
More information about the Gcc-bugs
mailing list