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?

Reply via email to