This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

[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;

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