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: unassig...@gcc.gnu.org ReportedBy: bur...@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."