Bug 32239 - optimize power in loops, use __builtin_powi instead of _gfortran_pow_r4_i4
Summary: optimize power in loops, use __builtin_powi instead of _gfortran_pow_r4_i4
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Janne Blomqvist
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2007-06-07 05:10 UTC by Joost VandeVondele
Modified: 2018-03-03 13:31 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-06-17 06:39:39


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Joost VandeVondele 2007-06-07 05:10:45 UTC
Current trunk generates always a call to 
_gfortran_pow_r4_i4 for this code

SUBROUTINE T(a,b,F,n)
 REAL :: a,b,F(n)
 INTEGER :: n
 INTEGER :: i
 DO i=1,n
    a=a+F(i)*b**i
 ENDDO
END SUBROUTINE

which could, however, be transformed by the compiler (at least in -ffast-math, but even otherwise for Fortran) in the much more efficient equivalent code

SUBROUTINE T_opt(a,b,F,n)
 REAL :: a,b,F(n)
 INTEGER :: n
 INTEGER :: i
 REAL    :: tmp

 tmp=1.0
 DO i=1,n
    tmp=tmp*b
    a=a+F(i)*tmp
 ENDDO
END SUBROUTINE

I think it is a pretty common situation (just from grepping in our code, most non-constant integer powers we have are loop indices).
Comment 1 Richard Biener 2007-06-08 10:11:40 UTC
Confirmed.  Instead of calls to _gfortran_pow_r4_i4, gfortran should use
__builtin_powi in this case.  __builtin_powi is either expanded inline or
implemented by the libgcc powi function which looks like

TYPE
NAME (TYPE x, int m)
{
  unsigned int n = m < 0 ? -m : m;
  TYPE y = n % 2 ? x : 1;
  while (n >>= 1)
    {
      x = x * x;
      if (n % 2)
        y = y * x;
    }
  return m < 0 ? 1/y : y;
}
Comment 2 Janne Blomqvist 2007-06-17 06:39:39 UTC
Assigning to myself, this should be easy to fix.
Comment 3 patchapp@dberlin.org 2007-06-17 11:40:27 UTC
Subject: Bug number PR32239

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-06/msg01172.html
Comment 4 Tobias Burnus 2007-06-25 19:52:56 UTC
"At the moment the vectorizer only vectorizes builtin_pow if the exponent is
either 2 or 0.5. whereas if we expand constant exponents in the gfortran
frontend (gfc_conv_cst_int_power) it vectorizes for other constant integer
powers as well"

I've filled PR middle-end/32503 for this.
Comment 5 Janne Blomqvist 2007-07-01 16:24:48 UTC
Subject: Bug 32239

Author: jb
Date: Sun Jul  1 16:24:38 2007
New Revision: 126175

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126175
Log:
gcc/fortran:
	
2007-07-01  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* trans-expr.c (gfc_conv_power_op): Use builtin_powi for
	real**int4 powers.
	* f95-lang.c (gfc_init_builtin_functions): Add builtin_powi to the
	builtins table.

	
libgfortran:
	
2007-07-01  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* Makefile.am: Don't generate real**int4 pow functions.
	* gfortran.map: Remove real**int4 pow symbols.
	* Makefile.in: Regenerated.

testsuite

2007-07-01  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
	(test_4): Use proper test for floating point equality.
	(test_8): Likewise.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/f95-lang.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/Makefile.am
    trunk/libgfortran/Makefile.in
    trunk/libgfortran/gfortran.map

Comment 6 Janne Blomqvist 2007-07-02 16:21:47 UTC
Subject: Bug 32239

Author: jb
Date: Mon Jul  2 16:21:37 2007
New Revision: 126215

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126215
Log:
Forgot to delete these during yesterdays commit.

2007-07-02  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* generated/pow_r*_i4.c: Removed.


Removed:
    trunk/libgfortran/generated/pow_r10_i4.c
    trunk/libgfortran/generated/pow_r16_i4.c
    trunk/libgfortran/generated/pow_r4_i4.c
    trunk/libgfortran/generated/pow_r8_i4.c
Modified:
    trunk/libgfortran/ChangeLog

Comment 7 Janne Blomqvist 2007-07-02 20:46:41 UTC
Closing as Fortran FE is fixed. There is 32503 for better vectorization of builtin_powi, and if we want the strength reduction optimization from comment #0 a new missed-optimization PR should be filed against the middle-end (or tree-optimization).