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.

Reply via email to