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)