http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56937



             Bug #: 56937

           Summary: Unnecessarily temporary with array-vector assignments

    Classification: Unclassified

           Product: gcc

           Version: 4.9.0

            Status: UNCONFIRMED

          Keywords: missed-optimization

          Severity: normal

          Priority: P3

         Component: fortran

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: bur...@gcc.gnu.org





For assignments of the form



   array(vec_idx) = array(vec_idx) + nonaliasing_expr



no temporary should be generated.



In other words, the following program should print "1.0" and not "0.5". It

prints "1.0" with PGI and Intel (which do this optimization) and prints "0.5"

with pathf95, g95, gfortran and NAG, which don't:



real :: r(4), p(4)

integer :: idx(4)

p = [0.25, 0.25, 0.25, 0.25]

idx = [2,2,3,2]

r = 0

r(idx) = r(idx) + p

print *, sum(r)

end



The reason for the value is that gfortran (et al.) create a temporary and use:

  tmp(2) = r(1) + 0.25  ! r(1:4) == 0

  tmp(2) = r(2) + 0.25

  tmp(3) = r(3) + 0.25

  tmp(2) = r(4) + 0.25

  r(2) = tmp(2)         ! = 0.25

  r(2) = tmp(2)         ! = 0.25

  r(3) = tmp(3)         ! = 0.25

  r(2) = tmp(2)         ! = 0.25

-> sum(r) = 0.5



Without temporary one gets:

  r(2) = 0 + 0.25

  r(2) = (0.25) + 0.25

  r(3) = 0 + 0.25

  r(4) = (0.75) + 0.25

-> sum(r) = 1.0





The reason that the optimization is valid is given by the following restriction

in the Fortran standard:



"If a vector subscript has two or more elements with the same value, an array

section with that vector subscript shall not appear in a variable definition

context (16.6.7)."   (Fortran 2008, 6.5.3.3.2 Vector subscript, paragraph 3)

Reply via email to