This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] (Partial) fix for libstdc++/11706
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 11 Mar 2004 00:43:30 +0100
- Subject: [Patch] (Partial) fix for libstdc++/11706
Hi,
I'd like to commit to mainline and 3.4 too, since absolutely safe, the
following (partial) fix for 11706. Ideally, we should unroll the loop in
__cmath_power, but, unfortunately, this is not going to happen "tomorrow"
(i.e., nobody is working on that on the tree-ssa branch, see also 11710),
due to the non-linear induction variable
Anyway, as already explained in comment #2, this is a remarkable
improvement. Compare (x86, -O2):
double f(double a)
{
return std::pow(a, 1);
}
current
-------
00000000 <f(double)>:
0: 55 push %ebp
1: b8 01 00 00 00 mov $0x1,%eax
6: 89 e5 mov %esp,%ebp
8: 83 ec 18 sub $0x18,%esp
b: dd 45 08 fldl 0x8(%ebp)
e: 89 44 24 08 mov %eax,0x8(%esp)
12: dd 1c 24 fstpl (%esp)
15: e8 fc ff ff ff call 16 <f(double)+0x16>
1a: c9 leave
1b: c3 ret
Disassembly of section .gnu.linkonce.t._ZSt13__cmath_powerIdET_S0_j:
00000000 <double std::__cmath_power<double>(double, unsigned int)>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 10 mov 0x10(%ebp),%eax
6: dd 45 08 fldl 0x8(%ebp)
9: a8 01 test $0x1,%al
b: d9 c0 fld %st(0)
d: 75 08 jne 17 <double
std::__cmath_power<double>(double, unsigned int)+0x17>
f: dd d8 fstp %st(0)
11: d9 e8 fld1
13: eb 02 jmp 17 <double
std::__cmath_power<double>(double, unsigned int)+0x17>
15: d9 c9 fxch %st(1)
17: d1 e8 shr %eax
19: 74 19 je 34 <double
std::__cmath_power<double>(double, unsigned int)+0x34>
1b: eb 05 jmp 22 <double
std::__cmath_power<double>(double, unsigned int)+0x22>
1d: 8d 76 00 lea 0x0(%esi),%esi
20: d9 c9 fxch %st(1)
22: d9 c9 fxch %st(1)
24: a8 01 test $0x1,%al
26: d8 c8 fmul %st(0),%st
28: 74 eb je 15 <double
std::__cmath_power<double>(double, unsigned int)+0x15>
2a: dc c9 fmul %st,%st(1)
2c: d1 e8 shr %eax
2e: 75 f0 jne 20 <double
std::__cmath_power<double>(double, unsigned int)+0x20>
30: dd d8 fstp %st(0)
32: eb 02 jmp 36 <double
std::__cmath_power<double>(double, unsigned int)+0x36>
34: dd d9 fstp %st(1)
36: 5d pop %ebp
37: c3 ret
patched
-------
00000000 <f(double)>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: dd 45 08 fldl 0x8(%ebp)
6: 5d pop %ebp
7: c3 ret
=============
And, for:
double f(double a)
{
return std::pow(a, 2);
}
current
-------
00000000 <f(double)>:
0: 55 push %ebp
1: b8 02 00 00 00 mov $0x2,%eax
6: 89 e5 mov %esp,%ebp
8: 83 ec 18 sub $0x18,%esp
b: dd 45 08 fldl 0x8(%ebp)
e: 89 44 24 08 mov %eax,0x8(%esp)
12: dd 1c 24 fstpl (%esp)
15: e8 fc ff ff ff call 16 <f(double)+0x16>
1a: c9 leave
1b: c3 ret
Disassembly of section .gnu.linkonce.t._ZSt13__cmath_powerIdET_S0_j:
00000000 <double std::__cmath_power<double>(double, unsigned int)>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 10 mov 0x10(%ebp),%eax
6: dd 45 08 fldl 0x8(%ebp)
9: a8 01 test $0x1,%al
b: d9 c0 fld %st(0)
d: 75 08 jne 17 <double
std::__cmath_power<double>(double, unsigned int)+0x17>
f: dd d8 fstp %st(0)
11: d9 e8 fld1
13: eb 02 jmp 17 <double
std::__cmath_power<double>(double, unsigned int)+0x17>
15: d9 c9 fxch %st(1)
17: d1 e8 shr %eax
19: 74 19 je 34 <double
std::__cmath_power<double>(double, unsigned int)+0x34>
1b: eb 05 jmp 22 <double
std::__cmath_power<double>(double, unsigned int)+0x22>
1d: 8d 76 00 lea 0x0(%esi),%esi
20: d9 c9 fxch %st(1)
22: d9 c9 fxch %st(1)
24: a8 01 test $0x1,%al
26: d8 c8 fmul %st(0),%st
28: 74 eb je 15 <double
std::__cmath_power<double>(double, unsigned int)+0x15>
2a: dc c9 fmul %st,%st(1)
2c: d1 e8 shr %eax
2e: 75 f0 jne 20 <double
std::__cmath_power<double>(double, unsigned int)+0x20>
30: dd d8 fstp %st(0)
32: eb 02 jmp 36 <double
std::__cmath_power<double>(double, unsigned int)+0x36>
34: dd d9 fstp %st(1)
36: 5d pop %ebp
37: c3 ret
patched
-------
00000000 <f(double)>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: dd 45 08 fldl 0x8(%ebp)
6: d9 e8 fld1
8: b8 01 00 00 00 mov $0x1,%eax
d: eb 03 jmp 12 <f(double)+0x12>
f: 90 nop
10: d9 c9 fxch %st(1)
12: d9 c9 fxch %st(1)
14: a8 01 test $0x1,%al
16: d8 c8 fmul %st(0),%st
18: 74 02 je 1c <f(double)+0x1c>
1a: dc c9 fmul %st,%st(1)
1c: d1 e8 shr %eax
1e: 75 f0 jne 10 <f(double)+0x10>
20: dd d8 fstp %st(0)
22: 5d pop %ebp
23: c3 ret
Paolo.
//////////////////////
2004-03-11 Steven Bosscher <s.bosscher@student.tudelft.nl>
PR libstdc++/11706
* include/c_std/cmath.tcc (__cmath_power): Define inline.
diff -urN libstdc++-v3-orig/include/c_std/cmath.tcc libstdc++-v3/include/c_std/cmath.tcc
--- libstdc++-v3-orig/include/c_std/cmath.tcc 2003-12-09 04:44:35.000000000 +0100
+++ libstdc++-v3/include/c_std/cmath.tcc 2004-03-11 00:13:07.000000000 +0100
@@ -1,6 +1,6 @@
// -*- C++ -*- C math library.
-// Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -35,7 +35,7 @@
namespace std
{
template<typename _Tp>
- _Tp
+ inline _Tp
__cmath_power(_Tp __x, unsigned int __n)
{
_Tp __y = __n % 2 ? __x : 1;