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).
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; }
Assigning to myself, this should be easy to fix.
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
"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.
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
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
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).