http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55806
Bug #: 55806 Summary: Missed optimization with ANY or ALL Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: fortran AssignedTo: unassig...@gcc.gnu.org ReportedBy: tkoe...@gcc.gnu.org Mike Metcalf complains (correctly) in <44daf54c-3de5-4b1c-a1f7-cb7bf0d49...@googlegroups.com> that using ANY as an idiom instead of .or. for a small number of conditions. Look at this: module mymod contains subroutine bar(a,b,c) integer, dimension(3,3), intent(in) :: a,b integer, intent(out) :: c real, parameter :: acc = 1e-4 integer :: i c = 0 do i=1,3 if (any([abs(a(i,1) - b(i,1)) > acc, & abs(a(i,2) - b(i,2)) > acc, & abs(a(i,3) - b(i,3)) > acc])) cycle c = c + 1 end do end subroutine bar end module mymod This generates a logical array, assigns the values to them, and then loops over the array to generate the values: atmp.1.dtype = 273; atmp.1.dim[0].stride = 1; atmp.1.dim[0].lbound = 0; atmp.1.dim[0].ubound = 2; atmp.1.data = (void * restrict) &A.2; atmp.1.offset = 0; (*(logical(kind=4)[3] * restrict) atmp.1.data)[0] = (real(kind=4)) ABS_EXPR <(*a)[(integer(kind=8)) i + -1] - (*b)[(integer(kind=8)) i + -1]> > 9.99999974737875163555145263671875e-5; (*(logical(kind=4)[3] * restrict) atmp.1.data)[1] = (real(kind=4)) ABS_EXPR <(*a)[(integer(kind=8)) i + 2] - (*b)[(integer(kind=8)) i + 2]> > 9.99999974737875163555145263671875e-5; (*(logical(kind=4)[3] * restrict) atmp.1.data)[2] = (real(kind=4)) ABS_EXPR <(*a)[(integer(kind=8)) i + 5] - (*b)[(integer(kind=8)) i + 5]> > 9.99999974737875163555145263671875e-5; { integer(kind=8) S.4; S.4 = 0; while (1) { if (S.4 > 2) goto L.5; if (NON_LVALUE_EXPR <(*(logical(kind=4)[3] * restrict) atmp.1.data)[S.4]>) { test.0 = 1; goto L.4; } S.4 = S.4 + 1; } L.5:; } L.4:; if (test.0) goto L.1; } L.3:; *c = *c + 1; L.1:; D.1907 = i == 3; i = i + 1; if (D.1907) goto L.2; } The middle-end then fails to remove this array. Compare this to the result of module mymod contains subroutine bar(a,b,c) real, dimension(3,3), intent(in) :: a,b integer, intent(out) :: c real, parameter :: acc = 1e-4 integer :: i c = 0. do i=1,3 if (abs(a(i,1) - b(i,1)) > acc .or. & abs(a(i,2) - b(i,2)) > acc .or. & abs(a(i,3) - b(i,3)) > acc) cycle c = c + 1 end do end subroutine bar end module mymod What the Fortran FE generates here isn't very idiomatic when you write in a language like C. Should we tackle this in the middle end, or would issuing the version with .or instead of the ANY to the middle end be preferred?