https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125914
Bug ID: 125914
Summary: -1.0**integer should be real(-1**integer)
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: tkoenig at gcc dot gnu.org
Target Milestone: ---
Noted by Harald in
https://gcc.gnu.org/pipermail/fortran/2026-June/064135.html
The (slighyl modified, DO CONCURRENT replaced by DO) test case
program main
use, intrinsic :: iso_fortran_env
implicit none
integer, parameter :: nsplit = 4
integer(int64), parameter :: ne = 10000000
integer(int64) :: stride, low(nsplit), high(nsplit), edof(ne), i
real(real64), dimension(nsplit) :: pi
edof(1::4) = 1
edof(2::4) = 2
edof(3::4) = 3
edof(4::4) = 4
stride = ceiling(real(ne)/nsplit)
do i = 1, nsplit
high(i) = stride*i
end do
do i = 2, nsplit
low(i) = high(i-1) + 1
end do
low(1) = 1
high(nsplit) = ne
pi = 0
do i=1, nsplit
pi(i) = sum(compute( low(i), high(i) ))
end do
print *, "PI", 4*sum(pi)
contains
pure function compute( low, high ) result( tmp )
integer(int64), intent(in) :: low, high
real(real64), dimension(nsplit) :: tmp
integer(int64) :: j, k
tmp = 0
do j = low, high
k = edof(j)
! tmp(k) = tmp(k) + (-1.0_real64)**(j+1) / real( 2*j-1 ) ! This is slow
tmp(k) = tmp(k) + (-1)**(j+1) / real( 2*j-1, real64)
end do
end function compute
with the slow version on my computer, with -O2
$ time ./a.out
PI 3.1415925728000698
real 0m0,486s
user 0m0,467s
sys 0m0,018s
and with the fast version
$ time ./a.out
PI 3.1415925535907734
real 0m0,043s
user 0m0,025s
sys 0m0,018s
For the fast case, the tmp(k) assignment is translated to
*((real(kind=8) *) __result.0 + (sizetype) ((k * stride.0 + offset.1)
* 8)) = *((real(kind=8) *) __result.0 + (sizetype) ((k * stride.0 + offset.1) *
8)) + (real(kind=8)) (1 - (j + 1 << 1 & 2)) / (real(kind=8)) (j * 2 + -1);
so this is obviously fast. We could do something similar in the front end.