Bug 11706 - std::pow(T, int) implementation pessimizes code
Summary: std::pow(T, int) implementation pessimizes code
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.0
: P3 enhancement
Target Milestone: 4.0.0
Assignee: Paolo Carlini
URL:
Keywords: missed-optimization, patch
Depends on: 11710 19401 19402
Blocks:
  Show dependency treegraph
 
Reported: 2003-07-29 12:03 UTC by Richard Biener
Modified: 2005-02-13 10:26 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-02-07 14:19:34


Attachments
patch (361 bytes, patch)
2005-01-12 15:11 UTC, Richard Biener
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2003-07-29 12:03:28 UTC
The std::__pow_helper() implementation ends up emitting a call to
std::__cmath_power() for all constant powers as f.i. in the call to
std::pow(x, 2). This severly pessimizes code and can be cured by teaching
optimal computation to std::__pow_helper() via the __builtin_constant_p
mechanism of gcc.

See http://gcc.gnu.org/ml/gcc/2003-07/msg01950.html for an example improved
implementation.

The same problem exists on the 3.3 branch.
Comment 1 Steven Bosscher 2003-07-29 12:39:42 UTC
__cmath_power() should probably be declared inline, something like this:

---- 8< ---- 8< ---- 8< ---- 8< ----
Index: libstdc++-v3/include/c_std/cmath.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/c_std/cmath.tcc,v
retrieving revision 1.3
diff -c -3 -p -r1.3 cmath.tcc
*** libstdc++-v3/include/c_std/cmath.tcc        23 Jul 2003 15:28:44 -0000      1.3
--- libstdc++-v3/include/c_std/cmath.tcc        29 Jul 2003 12:36:26 -0000
***************
*** 35,41 ****
  namespace std
  {
    export template<typename _Tp>
!     _Tp
      __cmath_power(_Tp __x, unsigned int __n)
      {
        _Tp __y = __n % 2 ? __x : 1;
--- 35,41 ----
  namespace std
  {
    export template<typename _Tp>
!     inline _Tp
      __cmath_power(_Tp __x, unsigned int __n)
      {
        _Tp __y = __n % 2 ? __x : 1;
---- 8< ---- 8< ---- 8< ---- 8< ----

Or are there reasons bigger than us that prevent such an implementation from
being correct?

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.
Comment 2 Richard Biener 2003-07-29 12:53:09 UTC
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/

Comment 3 Richard Biener 2003-07-29 13:01:15 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On 29 Jul 2003, steven at gcc dot gnu dot org wrote:

> 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.

Given recent discussion on gcc list and gcc3.4s ability to optimize
::pow, we should just drop __pow_helper() and __cmath_power() and change

  inline double
  std::pow(double __x, int __i)
  { return __pow_helper(__x, __i); }

to

  inline double
  std::pow(double __x, int __i)
  { return ::pow(__x, __i); }


Maybe for all other overloads, too.

Richard.

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

Comment 4 Gabriel Dos Reis 2003-07-29 13:19:16 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"steven at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| Or are there reasons bigger than us that prevent such an implementation from
| being correct?

The expansion of pow() as an inline function may be quite large and
have negative impact on the overall program.  That is why it does not
suffice to examine the assembler output nor just a single (kind) of
application -- be it scientific.

This is not meant to dismiss the report.  I'll take care of it.

-- Gaby
Comment 5 Richard Biener 2003-09-29 14:29:14 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On 29 Jul 2003, gdr at integrable-solutions dot net wrote:

> "steven at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:
>
> | Or are there reasons bigger than us that prevent such an implementation from
> | being correct?
>
> The expansion of pow() as an inline function may be quite large and
> have negative impact on the overall program.  That is why it does not
> suffice to examine the assembler output nor just a single (kind) of
> application -- be it scientific.
>
> This is not meant to dismiss the report.  I'll take care of it.

Any progress on this? I still think this is a show stopper. What about the
suggested replacement of the __pow_helper() with ::pow() which is now
optimized by an appropriate builtin?

Thanks,

Richard.

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

Comment 6 Gabriel Dos Reis 2003-09-29 14:36:56 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Any progress on this? I still think this is a show stopper. What about the
| suggested replacement of the __pow_helper() with ::pow() which is now
| optimized by an appropriate builtin?

<cmath> should not use ::pow -- it is not supposed to be available there.
The issue should now be reevaluated with the recent work on inlining.
I did not have time to work on it though.

-- Gaby
Comment 7 Richard Biener 2003-09-29 14:41:33 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On 29 Sep 2003, gdr at integrable-solutions dot net wrote:

> 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 gdr at integrable-solutions dot net  2003-09-29 14:36 -------
> Subject: Re:  std::pow(T, int) implementation pessimizes code
>
> "rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:
>
> | Any progress on this? I still think this is a show stopper. What about the
> | suggested replacement of the __pow_helper() with ::pow() which is now
> | optimized by an appropriate builtin?
>
> <cmath> should not use ::pow -- it is not supposed to be available there.
> The issue should now be reevaluated with the recent work on inlining.
> I did not have time to work on it though.

Its still the very same. The (pending?) fix for PR11707 should help a
little bit, but as PR11710 will not be fixed this wont help the underlying
problem.

Why exactly should cmath not use ::pow (or __builtin_pow())? Has it to
work with other compilers than the gcc it shipped with?

Richard.

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

Comment 8 Gabriel Dos Reis 2003-09-29 15:05:14 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Why exactly should cmath not use ::pow

we should not use ::pow because there is no ::pow in <cmath> -- at
least in principle.

| (or __builtin_pow())?

I remember Roger supplied builtins for various T in pow(T, int).
They should help.

-- Gaby
Comment 9 Richard Biener 2003-09-29 15:29:23 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On 29 Sep 2003, gdr at integrable-solutions dot net wrote:

> 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 gdr at integrable-solutions dot net  2003-09-29 15:05 -------
> Subject: Re:  std::pow(T, int) implementation pessimizes code
>
> "rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:
>
> | Why exactly should cmath not use ::pow
>
> we should not use ::pow because there is no ::pow in <cmath> -- at
> least in principle.

It is - see line 556 in <cmath> which unconditionally uses ::pow. The
problem are just the integer overloads of pow, as if using the regular
float ones we optimize according to the gcc builtins added by Roger.

So we can f.i. just drop the integer overloads of std::pow.

Richard.

> | (or __builtin_pow())?
>
> I remember Roger supplied builtins for various T in pow(T, int).
> They should help.


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

Comment 10 Gabriel Dos Reis 2003-09-29 16:17:03 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| It is - see line 556 in <cmath> which unconditionally uses ::pow. The

It is a bug, feel free to submit a due PR :-)

| problem are just the integer overloads of pow, as if using the regular
| float ones we optimize according to the gcc builtins added by Roger.
| 
| So we can f.i. just drop the integer overloads of std::pow.

No, we should not.

-- Gaby
Comment 11 Richard Biener 2003-11-13 21:42:45 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On Mon, 29 Sep 2003, gdr at integrable-solutions dot net wrote:

> ------- Additional Comments From gdr at integrable-solutions dot net  2003-09-29 16:17 -------
> Subject: Re:  std::pow(T, int) implementation pessimizes code
>
> "rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:
>
> | It is - see line 556 in <cmath> which unconditionally uses ::pow. The
>
> It is a bug, feel free to submit a due PR :-)

Can we please have progress on the std::pow(T, int) issue? For those who
dont remember, look at the code generated for std::pow(x, 2) compared to
::pow(x, 2).

The most clean solution would be __builtin_powi(), __builtin_powfi(), __builtin_powli()
functions, but just replacing __cmath_power() usage in
cmath.h:__pow_helper() by ::pow() or __builtin_pow() for constant
exponents solves the optimization issues for gcc 3.4. So __pow_helper()
would look like:

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

or replace the uses of __pow_helper() in the pow() overloads according to
the above transformation (using appropriate ::pow(), ::powf() and ::powl()
if available).

Thanks,

Richard.
Comment 12 Benjamin Kosnik 2003-12-05 23:52:43 UTC
Can you provide a patch for this, or give current status? Have you asked Roger
Sayle about this, who seems to be the guru of builtin math functions? There also
are changes to std_cmath.h for pow, see:

2003-11-15  Roger Sayle  <roger@eyesopen.com>

	* include/c_std/std_cmath.h: Don't import C99's float transcendentals
	into the __gnu_cxx::__c99_binding namespace.
	(acos, asin, atan, atan2, ceil, cosh, exp, floor, fmod, frexp,
	ldexp, log, log10, modf, pow, sinh, tan, tanh): Implement using
	GCC's math builtins, i.e. __builtin_foo.
	* libmath/stubs.c (acosf, acosl, asinf, asinl, atanf, atanl,
	ceilf, ceill, floorf, floorl, fmodf, fmodl, frexpf, frexpl,
	ldexpf, ldexpl, modff, modfl): Provide stub implementations.


Can we get this resolved, folks? I think all that needs to be done now is
examine cmath.tcc for inline-ability (ie, is __cmath_power to be inlined now?)
Please let me know how I can help.

best,
benjamin
Comment 13 Richard Biener 2003-12-06 18:26:35 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On Sat, 5 Dec 2003, bkoz at gcc dot gnu dot org wrote:

>
> ------- Additional Comments From bkoz at gcc dot gnu dot org  2003-12-05 23:52 -------
>
> Can you provide a patch for this, or give current status? Have you asked Roger
> Sayle about this, who seems to be the guru of builtin math functions? There also
> are changes to std_cmath.h for pow, see:
>
> 2003-11-15  Roger Sayle  <roger@eyesopen.com>
>
> 	* include/c_std/std_cmath.h: Don't import C99's float transcendentals
> 	into the __gnu_cxx::__c99_binding namespace.
> 	(acos, asin, atan, atan2, ceil, cosh, exp, floor, fmod, frexp,
> 	ldexp, log, log10, modf, pow, sinh, tan, tanh): Implement using
> 	GCC's math builtins, i.e. __builtin_foo.
> 	* libmath/stubs.c (acosf, acosl, asinf, asinl, atanf, atanl,
> 	ceilf, ceill, floorf, floorl, fmodf, fmodl, frexpf, frexpl,
> 	ldexpf, ldexpl, modff, modfl): Provide stub implementations.

Uh, now even the ::pow(x, 2) call creates unoptimized code...:

_Z3food:
.LFB162:
        pushl   %ebp    #
.LCFI2:
        xorl    %edx, %edx      #
        movl    %esp, %ebp      #,
.LCFI3:
        subl    $24, %esp       #,
.LCFI4:
        movl    $1073741824, %eax       #,
        fldl    8(%ebp) # x
        movl    %edx, 8(%esp)   #,
        movl    %eax, 12(%esp)  #,
        fstpl   (%esp)  #
        call    pow     #
        leave
        ret

the std::pow(x, 2) one is still the same. Not quite uptodate
g++-3.4 (GCC) 3.4 20031124 (experimental)

> Can we get this resolved, folks? I think all that needs to be done now is
> examine cmath.tcc for inline-ability (ie, is __cmath_power to be inlined now?)
> Please let me know how I can help.

Inlining __cmath_power won't help, as gcc is unable to optimize the loop
in it which has a non-linear biv. Some time ago it did help to call
__builtin_pow() from inside the integer overloads of pow, but I suspect
this is no longer true. Another possibility is to use __builtin_constant()
to check for constant exponent and manually optimize for this.

Btw., the ::pow() behavior is now a regression towards gcc 3.3

Richard.
Comment 14 Gabriel Dos Reis 2003-12-06 19:26:29 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Inlining __cmath_power won't help, as gcc is unable to optimize the loop
| in it which has a non-linear biv. Some time ago it did help to call
| __builtin_pow() from inside the integer overloads of pow, but I suspect
| this is no longer true. Another possibility is to use __builtin_constant()
| to check for constant exponent and manually optimize for this.

Just a note.  I'm *for* a good approach that makes the situation better.
I excluse any use of __builtin_constant from any such approach. 

| Btw., the ::pow() behavior is now a regression towards gcc 3.3

You should probably fill a separate PR for that,

-- Gaby
Comment 15 Richard Biener 2003-12-06 19:50:15 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On Sat, 6 Dec 2003, gdr at integrable-solutions dot net wrote:

> "rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:
>
> | Inlining __cmath_power won't help, as gcc is unable to optimize the loop
> | in it which has a non-linear biv. Some time ago it did help to call
> | __builtin_pow() from inside the integer overloads of pow, but I suspect
> | this is no longer true. Another possibility is to use __builtin_constant()
> | to check for constant exponent and manually optimize for this.
>
> Just a note.  I'm *for* a good approach that makes the situation better.
> I excluse any use of __builtin_constant from any such approach.

Of course - use of __builtin_constant would be acceptable for me only, if
we can come up with a __cmath_power implementation for constant exponent
which would then be optimzed ok in all cases (and of course, inlined). My
hack to only optimize for powers of 2 and 3 is obviously a hack.

Richard.
Comment 16 Richard Biener 2003-12-06 20:05:31 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

On Sat, 5 Dec 2003, bkoz at gcc dot gnu dot org wrote:

> Can we get this resolved, folks? I think all that needs to be done now is
> examine cmath.tcc for inline-ability (ie, is __cmath_power to be inlined now?)
> Please let me know how I can help.

Ok, so I checked todays mainline and g++-3.3 (GCC) 3.3.3 20031114
(prerelease), with gcc 3.3, for both, ::pow(x,2) and std::pow(x,2) we
generate a call to libm, for mainline this is the same - except if we
compile with -ffast-math, in which case the first call is expanded to
optimal asm. So it seems this transformation is guarded with
-funsafe-math-optimizations -- why?

Richard.
Comment 17 Gabriel Dos Reis 2003-12-06 20:33:48 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"rguenth at tat dot physik dot uni-tuebingen dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Additional Comments From rguenth at tat dot physik dot uni-tuebingen dot de  2003-12-06 20:05 -------
| Subject: Re:  std::pow(T, int) implementation pessimizes
|  code
| 
| On Sat, 5 Dec 2003, bkoz at gcc dot gnu dot org wrote:
| 
| > Can we get this resolved, folks? I think all that needs to be done now is
| > examine cmath.tcc for inline-ability (ie, is __cmath_power to be inlined now?)
| > Please let me know how I can help.
| 
| Ok, so I checked todays mainline and g++-3.3 (GCC) 3.3.3 20031114
| (prerelease), with gcc 3.3, for both, ::pow(x,2) and std::pow(x,2) we
| generate a call to libm, for mainline this is the same - except if we
| compile with -ffast-math, in which case the first call is expanded to
| optimal asm. So it seems this transformation is guarded with
| -funsafe-math-optimizations -- why?

I guess, it is because we don't trust the asm version of math
functions by default and use them only if -funsafe-math-optimizations.
There have been lengthy discussions in the past, and the general
decision was to generate asms onlyk if -funsafe-math-optimizations.

-- Gaby


Comment 18 Paolo Carlini 2004-03-10 15:14:56 UTC
... trying to reach some sort of closure on the long standing issue...
Comment 19 Gabriel Dos Reis 2004-03-10 15:34:30 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ... trying to reach some sort of closure on the long standing issue...

Plesse, don't rush into this.  See several reports on this issue
(they were probably not recorded by bugzilla), in particular a report
saying the builtins no longer optimized as the reporter claimed
before.  The issue is actually solved in tree--ssa (or was reported as
such at some point in the past).  I believe this should be targetted
for 3.5.0.  It really is compiler-optimization issue even though it is
not labelled as scuh.

-- Gaby
Comment 20 Paolo Carlini 2004-03-10 15:43:24 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:

>Plesse, don't rush into this.
>
Gaby, of you write "don't rush", about 9 months after having promised to 
care
of the issue, I can only laugh.

>The issue is actually solved in tree--ssa (or was reported as
>such at some point in the past).  I believe this should be targetted
>for 3.5.0.  It really is compiler-optimization issue even though it is
>not labelled as scuh.
>  
>
This is very good to know, if confirmed: do you have a pointer?

Anyway, I'm going to update my tree-ssa, double check and take appropriate
actions.

Paolo.
Comment 21 Gabriel Dos Reis 2004-03-10 19:51:21 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| gdr at integrable-solutions dot net wrote:
| 
| >Plesse, don't rush into this.
| >
| Gaby, of you write "don't rush", about 9 months after having promised to 
| care
| of the issue, I can only laugh.

Have a good time at laughing, but I meant what I said.

| >The issue is actually solved in tree--ssa (or was reported as
| >such at some point in the past).  I believe this should be targetted
| >for 3.5.0.  It really is compiler-optimization issue even though it is
| >not labelled as scuh.
| >  
| >
| This is very good to know, if confirmed: do you have a pointer?

Don't have a pointer handy but, google for messages from Richard G. with the
complain that the ::pow() is no longer "inlined".

-- Gaby
Comment 22 Paolo Carlini 2004-03-10 20:01:04 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:

>| >The issue is actually solved in tree--ssa (or was reported as
>| >such at some point in the past).  I believe this should be targetted
>| >for 3.5.0.  It really is compiler-optimization issue even though it is
>| >not labelled as scuh.
>| >  
>| >
>| This is very good to know, if confirmed: do you have a pointer?
>
>Don't have a pointer handy but, google for messages from Richard G. with the
>complain that the ::pow() is no longer "inlined".
>  
>
Anyway, the issue is *not* solved in tree-ssa, because __cmath_power 
cannot be
unrolled due to its non-linear iv. The blocker is the unroller not the 
inliner, see
PR 11710. Zdenek confirmed in private email that the unroller *could* be 
fixed,
in principle, but nobody is working on the issue.

Short-term the only feasible approach seems the one outlined by Richard 
here:

    http://gcc.gnu.org/ml/gcc/2003-07/msg01950.html

Luckily, I have plenty of time, since for this PR "rush" is defined as 
something of
order 1-2 months :-P

Paolo.
Comment 23 Gabriel Dos Reis 2004-03-10 20:19:25 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Additional Comments From pcarlini at suse dot de  2004-03-10 20:01 -------
| Subject: Re:  std::pow(T, int) implementation pessimizes
|  code
| 
| gdr at integrable-solutions dot net wrote:
| 
| >| >The issue is actually solved in tree--ssa (or was reported as
| >| >such at some point in the past).  I believe this should be targetted
| >| >for 3.5.0.  It really is compiler-optimization issue even though it is
| >| >not labelled as scuh.
| >| >  
| >| >
| >| This is very good to know, if confirmed: do you have a pointer?
| >
| >Don't have a pointer handy but, google for messages from Richard G. with the
| >complain that the ::pow() is no longer "inlined".
| >  
| >
| Anyway, the issue is *not* solved in tree-ssa, because __cmath_power 

Did you get the report that ::pow() is no longer inlined?

| Luckily, I have plenty of time, since for this PR "rush" is defined as 
| something of
| order 1-2 months :-P

This I don't understand.

-- Gaby
Comment 24 Paolo Carlini 2004-03-10 20:26:38 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:

>Did you get the report that ::pow() is no longer inlined?
>  
>
Why, now you are discussing ::pow, if in your comment #6 and #8 you
emphasized that we should not use ::pow?

Otherwise, we could do away with __cmath_power and use ::pow, which
*is* already optimized well in mainline when -ffast-math (#16 and #17)

Paolo.
Comment 25 Gabriel Dos Reis 2004-03-10 20:43:42 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Additional Comments From pcarlini at suse dot de  2004-03-10 20:26 -------
| Subject: Re:  std::pow(T, int) implementation pessimizes
|  code
| 
| gdr at integrable-solutions dot net wrote:
| 
| >Did you get the report that ::pow() is no longer inlined?
| >  
| >
| Why, now you are discussing ::pow, if in your comment #6 and #8 you
| emphasized that we should not use ::pow?

I'm discussing ::pow() because that is what the reporter wanted V3 to
use. I emphasize against those, and I would strongly advise against
any patch that does that.  Which is why I'm telling you that upfront
before you waste your time in that direction.
The only fix that I should have applied is to make __cmath_power()
inline.  Any other if or #if are just papering over the fundamental
problem. That is not fix.

-- Gaby
Comment 26 Paolo Carlini 2004-03-10 22:27:40 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:

>The only fix that I should have applied is to make __cmath_power()
>inline.
>
So, after all, Steven (#1) was right, why didn't you acknowldege that 6
months ago?

>  Any other if or #if are just papering over the fundamental
>problem. That is not fix.
>  
>
Yes, your usual stance, almost *everything* is papering over for you and
in the mean time you do nothing to solve the hard problems we are facing.

Paolo.
Comment 27 Gabriel Dos Reis 2004-03-10 22:39:18 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| Subject: Re:  std::pow(T, int) implementation pessimizes
|  code
| 
| gdr at integrable-solutions dot net wrote:
| 
| >The only fix that I should have applied is to make __cmath_power()
| >inline.
| >
| So, after all, Steven (#1) was right, why didn't you acknowldege that 6
| months ago?

Because 

  (1) some data was provided later, not before.

  (2) It is less harm than what you'd like to do.

| >  Any other if or #if are just papering over the fundamental
| >problem. That is not fix.
| >  
| >
| Yes, your usual stance,

Why don't you go and sign the petition circulating?

| almost *everything* is papering over for you and

No, you're wrong on that one.

| in the mean time you do nothing to solve the hard problems we are facing.

You *believe* I do not do anything.  Yes, I'm not in rush into
papering over problems; but it does not mean I do nothing.

Comment 28 Wolfgang Bangerth 2004-03-10 22:45:00 UTC
Folks, would you cool down a little and reconvene for this discussion 
after a night of sleep? Hurting and finger pointing helps nobody, even 
of you believe you have a point. 
 
Thanks 
  W. 
Comment 29 Paolo Carlini 2004-03-10 22:47:08 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:

>| >The only fix that I should have applied is to make __cmath_power()
>| >inline.
>| >
>| So, after all, Steven (#1) was right, why didn't you acknowldege that 6
>| months ago?
>
>Because 
>
>  (1) some data was provided later, not before.
>  
>
The last data was provided December, 6th, three full months. Do you 
think free
software implies slow feedback?

>  (2) It is less harm than what you'd like to do.
>  
>
I have decided nothing, I have time 'til at least the summer.

>You *believe* I do not do anything.  Yes, I'm not in rush into
>papering over problems; but it does not mean I do nothing.
>  
>
Of course, mine was a rethorical exageration: you do "nothing" in proportion
to what you could actually do, given your background and your role.

Paolo.
Comment 30 Gabriel Dos Reis 2004-03-10 23:39:44 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes code

"pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:

| gdr at integrable-solutions dot net wrote:
| 
| >| >The only fix that I should have applied is to make __cmath_power()
| >| >inline.
| >| >
| >| So, after all, Steven (#1) was right, why didn't you acknowldege that 6
| >| months ago?
| >
| >Because 
| >
| >  (1) some data was provided later, not before.
| >  
| >
| The last data was provided December, 6th, three full months. Do you 
| think free
| software implies slow feedback?

"slow" is in the eye of the beholder.
I donate my volunteer free time to GCC as much as I can.  If you're in
hurry of papering over real problems, three months is "slow".  
If you have squeezed schedule, three months look like three days.

-- Gaby
Comment 31 CVS Commits 2004-03-11 10:42:32 UTC
Subject: Bug 11706

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	paolo@gcc.gnu.org	2004-03-11 10:42:27

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/c_std: cmath.tcc 

Log message:
	2004-03-11  Steven Bosscher  <s.bosscher@student.tudelft.nl>
	
	PR libstdc++/11706
	* include/c_std/cmath.tcc (__cmath_power): Define inline.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2395&r2=1.2396
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/c_std/cmath.tcc.diff?cvsroot=gcc&r1=1.5&r2=1.6

Comment 32 CVS Commits 2004-03-11 11:37:31 UTC
Subject: Bug 11706

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	paolo@gcc.gnu.org	2004-03-11 11:37:22

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/c_std: cmath.tcc 

Log message:
	2004-03-11  Steven Bosscher  <s.bosscher@student.tudelft.nl>
	
	PR libstdc++/11706
	* include/c_std/cmath.tcc (__cmath_power): Define inline.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.2224.2.59&r2=1.2224.2.60
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/c_std/cmath.tcc.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.5&r2=1.5.4.1

Comment 33 Richard Biener 2004-03-11 18:55:56 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:
> ------- Additional Comments From gdr at integrable-solutions dot net  2004-03-10 20:19 -------
> Subject: Re:  std::pow(T, int) implementation pessimizes code
> 
> "pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:
> 
> | ------- Additional Comments From pcarlini at suse dot de  2004-03-10 20:01 -------
> | Subject: Re:  std::pow(T, int) implementation pessimizes
> |  code
> | 
> | gdr at integrable-solutions dot net wrote:
> | 
> | >| >The issue is actually solved in tree--ssa (or was reported as
> | >| >such at some point in the past).  I believe this should be targetted
> | >| >for 3.5.0.  It really is compiler-optimization issue even though it is
> | >| >not labelled as scuh.
> | >| >  
> | >| >
> | >| This is very good to know, if confirmed: do you have a pointer?
> | >
> | >Don't have a pointer handy but, google for messages from Richard G. with the
> | >complain that the ::pow() is no longer "inlined".
> | >  
> | >
> | Anyway, the issue is *not* solved in tree-ssa, because __cmath_power 
> 
> Did you get the report that ::pow() is no longer inlined?

This was fixed by Roger already.  It was basically ::pow(x, a) where a 
is 1, 2, -1 was not optimized without -ffast-math.

Sorry to be so late in the discussion - just returned from one week 
vacation.

Richard.

Comment 34 Richard Biener 2004-03-11 19:04:35 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

cvs-commit at gcc dot gnu dot org wrote:
> Log message:
> 	2004-03-11  Steven Bosscher  <s.bosscher@student.tudelft.nl>
> 	
> 	PR libstdc++/11706
> 	* include/c_std/cmath.tcc (__cmath_power): Define inline.

Folks, this is not the right fix.  It doesn't help at all and moves the 
problem to a place where it is harder to fix than before.  Namely now we 
need
- a loop unroller capable of non-linear iv handling
- a inliner that will inline pow(x, c) for c == -1, 0, 1, 2 all the 
time, for constant c if not -Os and otherwise not (probably based on 
profile-feedback).

This ain't gonna happen, even in 3.5 timeframe.  The simplest fix for 
3.4 is replacing the __cmath_power() call with ::pow(), if c is 
constant.  I.e.

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

This is sitting in my 3.3, 3.4 and ssa trees for month now.

Please remove the SUSPENDED state of the bug.

Richard.
Comment 35 Richard Biener 2004-03-11 20:14:10 UTC
Subject: Re:  std::pow(T, int) implementation pessimizes
 code

gdr at integrable-solutions dot net wrote:
> ------- Additional Comments From gdr at integrable-solutions dot net  2004-03-10 20:43 -------
> Subject: Re:  std::pow(T, int) implementation pessimizes code
> 
> "pcarlini at suse dot de" <gcc-bugzilla@gcc.gnu.org> writes:
> 
> | ------- Additional Comments From pcarlini at suse dot de  2004-03-10 20:26 -------
> | Subject: Re:  std::pow(T, int) implementation pessimizes
> |  code
> | 
> | gdr at integrable-solutions dot net wrote:
> | 
> | >Did you get the report that ::pow() is no longer inlined?
> | >  
> | >
> | Why, now you are discussing ::pow, if in your comment #6 and #8 you
> | emphasized that we should not use ::pow?
> 
> I'm discussing ::pow() because that is what the reporter wanted V3 to
> use. I emphasize against those, and I would strongly advise against
> any patch that does that.  Which is why I'm telling you that upfront
> before you waste your time in that direction.
> The only fix that I should have applied is to make __cmath_power()
> inline.  Any other if or #if are just papering over the fundamental
> problem. That is not fix.

As I said numerous times, inlining __cmath_power() will make things 
worse, because you need a _very_ clever inliner to notice the profitable 
cases.  My preffered solution would be a added __builtin_cmath_power() 
with appropriate folders.

Richard.

Comment 36 Zdenek Dvorak 2004-03-12 01:43:34 UTC
http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00995.html

might be relevant (although it of course does not solve the
problem by itself; there still remains the inlining part which
is nontrivial)
Comment 37 Andrew Pinski 2004-09-23 18:22:14 UTC
The only thing which needs to happen now for the mainline is to enable IV-cannon.
Comment 38 Andrew Pinski 2004-10-02 04:06:17 UTC
Most of the problems here are fixed, the one thing left is the inlining problem (there are other inlining 
bugs already).
Comment 39 Richard Biener 2005-01-12 15:11:59 UTC
Created attachment 7936 [details]
patch
Comment 40 Richard Biener 2005-01-12 16:17:34 UTC
Current status is that with -O2 on mainline we generate the same
(better) code for ::pow(x, 2) and std::pow(x, 2.0) than for
std::pow(x, 2) which looses because of the lack of unrolling
(PR19401).

Also, ::pow(x, 27) and other exponents will always generate better
code than the std::pow(x, 27) variant due to the technically
superior implementation of gcc/builtins.c:expand_powi.

The attached patch solves all of these problems, unfortunately
in ways the libstdc++ maintainer(s) do not like.
Comment 41 Richard Biener 2005-02-07 14:19:34 UTC
Patch:
http://gcc.gnu.org/ml/gcc-patches/2005-02/msg00243.html

depends on __builtin_powi (PR19402).
Comment 42 Richard Biener 2005-02-09 22:15:06 UTC
I'll let one of the libstdc++ maintainers sort this one out.  With __builtin_powi
available now, it should be easy.
Comment 43 Paolo Carlini 2005-02-09 22:55:49 UTC
Ok... I will. Just matter of adding a few testcases to your patch, actually.
Comment 44 CVS Commits 2005-02-13 10:25:13 UTC
Subject: Bug 11706

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	paolo@gcc.gnu.org	2005-02-13 10:25:02

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/c_std: std_cmath.h 
Added files:
	libstdc++-v3/testsuite/26_numerics/cmath: powi.cc 

Log message:
	2005-02-13  Richard Guenther  <rguenth@gcc.gnu.org>
	Paolo Carlini  <pcarlini@suse.de>
	
	PR libstdc++/11706
	* include/c_std/std_cmath.h (pow): Use __builtin_powi[lf]
	for integer overloads.
	
	* testsuite/26_numerics/cmath/powi.cc: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2893&r2=1.2894
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/c_std/std_cmath.h.diff?cvsroot=gcc&r1=1.17&r2=1.18
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/26_numerics/cmath/powi.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 45 Paolo Carlini 2005-02-13 10:26:21 UTC
Fixed for 4.0.