[Bug middle-end/49733] New: Missed optimization: Variable value not propagated to remove "if" condition

burnus at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jul 13 13:10:00 GMT 2011


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

           Summary: Missed optimization: Variable value not propagated to
                    remove "if" condition
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: burnus@gcc.gnu.org


Based on the discussion at http://gcc.gnu.org/ml/gcc/2011-07/msg00208.html.

In Fortran, the "if" condition can be removed in the following example as "call
some_function()" may not modify it. This optimization is done by the Fortran
compilers of NAG, Cray, Sun, Open64 and PathScale. But gfortran (and Intel's
and PGI's compiler) do not optimize the "if" away, which can be seen from the
presence of the "foobar_" function in the dump.


   subroutine sub(non_aliasing_var)
     interface
       subroutine some_function()
       end subroutine some_function
     end interface


     integer :: non_aliasing_var
     non_aliasing_var = 5
     call some_function()
     if (non_aliasing_var /= 5) call foobar_()
   end subroutine sub

Optimized dump:

sub (integer(kind=4) & restrict non_aliasing_var)
{
  integer(kind=4) D.1550;
<bb 2>:
  *non_aliasing_var_1(D) = 5;
  some_function ();
  D.1550_2 = *non_aliasing_var_1(D);
  if (D.1550_2 != 5)
    goto <bb 3>;
  else
    goto <bb 4>;
<bb 3>:
  foobar_ (); [tail call]
<bb 4>:
  return;
}


NOTE: Fortran has a case (coarrays, ASYNCHRONOUS), where the current behaviour
is correct: That is, no aliasing of variables in the scoping unit, but the
value might change due to asynchronous I/O / data communication (ASYNCHRONOUS)
- or via one-sided communication (coarrays), where the "WAIT" or SYNC might be
hidden in some function call. For those cases, the current behaviour with
"restrict" is correct.
Cf. ASYNCHRONOUS: F2008, Sect. 5.3.4 and PDTR 29113
(ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1866.pdf)
Cf. Coarray: F2008; especially Section 8.5 and, in particular, Subsection
8.5.2.


Regarding the example above, one finds in the Fortran standard (F2008,
ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1866.pdf) the following, which applies
as the dummy argument "non_aliasing_var" is neither a POINTER nor has it the
TARGET attribute.

"While an entity is associated with a dummy argument, the following
restrictions hold.
[...]
"(3) Action that affects the value of the entity or any subobject of it shall
be taken only through the dummy argument unless
(a) the dummy argument has the POINTER attribute or
(b) the dummy argument has the TARGET attribute, the dummy argument does not
have INTENT(IN), the dummy argument is a scalar object or an assumed-shape
array without the CONTIGUOUS attribute, and the actual argument is a target
other than an array section with a vector subscript.

(4) If the value of the entity or any subobject of it is affected through the
dummy argument, then at any time during the invocation and execution of the
procedure, either before or after the definition, it may be referenced only
through that dummy argument unless
(a) the dummy argument has the POINTER attribute or
(b) the dummy argument has the TARGET attribute, the dummy argument does not
have INTENT(IN), the dummy argument is a scalar object or an assumed-shape
array without the CONTIGUOUS attribute, and the actual argument is a target
other than an array section with a
vector subscript."



More information about the Gcc-bugs mailing list