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

2019-11-22 Thread burnus at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

Tobias Burnus  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #7 from Tobias Burnus  ---
Better description and updated links in PR 92628. Hence, close this one.

*** This bug has been marked as a duplicate of bug 92628 ***

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

2011-07-14 Thread burnus at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #6 from Tobias Burnus  2011-07-14 
09:25:31 UTC ---
(In reply to comment #5)
> Ah, so passing the non-aliasing-var to a function which takes a POINTER
> argument, returning that pointer and modifying it in the function that
> takes the non-aliasing-var is ok then?

POINTER in the C/middle-end or in the Fortran sense?

Passing a non-(Fortran-)POINTER variable as actual argument to a
(Fortran-)POINTER dummy argument is only valid, if the dummy is INTENT(IN) and
if the actual argument is TARGET. The INTENT(IN) makes sure that one does not
change the address to which the pointer points - and the TARGET avoids aliasing
issues. (Cf. "12.5.2.7 Pointer dummy variables".)

Thus, "non-aliasing-var" may not be passed passed to a POINTER dummy argument.


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

2011-07-14 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #5 from Richard Guenther  2011-07-14 
09:03:58 UTC ---
Ah, so passing the non-aliasing-var to a function which takes a POINTER
argument, returning that pointer and modifying it in the function that
takes the non-aliasing-var is ok then?

The Fortran semantics seem unclear enough to me to doubt that there is a
clean orthogonal representation for the middle-end.


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

2011-07-13 Thread burnus at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #4 from Tobias Burnus  2011-07-13 
14:42:43 UTC ---
(In reply to comment #3)
> is
[...]
> invalid then?

Yes, the does not even have the correct syntax. I assume you means something
like:

module m
  integer :: global
end module m

program main
  use m
  implicit none
  call test(global)
contains
  subroutine mod_global()
global = 7
  end subroutine mod_global
  subroutine mod2(y)
integer :: y
y = 9
  end subroutine mod2
  subroutine test(x)
integer :: x
x = 5
call mod_global() ! Invalid, modifies "x"
global = 8  ! Also invalid
call mod2(global) ! Ditto.
print *, x  ! May print 5, 7, 8, 9, or other garbage
  end subroutine
end program main

 ! or even
 ! sub (non_aliasing_var)
   if (non_aliasing_var /= 5) call foobar()

Well, "call sub (non_aliasing_var)" *may* modify "non_aliasing_var" - but it
may not modify a global variable directly, if it is associated with the actual
argument.

(And for recursion: That's only allowed if the procedure is marked as
RECURSIVE.)


As written, the Fortran standard states (quote in comment 0):

If A is used as actual argument to the dummy argument D then:

a) Anything which *modifies* "A" should only be done by using explicitly "D",
unless "D" is a POINTER or "D" has the TARGET attribute (and some other
conditions).

b) Anything which *reads* "A": If the value is modified through "D", only "D"
may be used to access the value. (With same exceptions for TARGET and POINTER -
and, of course, only applying until the function with the dummy "D" returns).


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

2011-07-13 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #3 from Richard Guenther  2011-07-13 
14:17:38 UTC ---
is

  program test

  integer :: a

  subroutine bar()
  a = 1
  end

  subroutine sub(non_aliasing_var)
  integer :: non_aliasing_var
  non_aliasing_var = 5
  bar()
  if (non_aliasing_var /= 5) call foobar()
  end

  sub(a)
  end

invalid then?  GCC assumes that any function can modify any global
variable unless interprocedural analysis can prove otherwise.

It gets more interesting when you consider

  subroutine sub(non_aliasing_var)
  integer :: non_aliasing_var
  non_aliasing_var = 5
  sub(a)
! or even
! sub (non_aliasing_var)
  if (non_aliasing_var /= 5) call foobar()
  end

(or even hide the recursion by going through an external dispatcher)

Does that make the variable "aliased"?  Or is that invalid as well
(ok, add whatever is required to allow sub be called recursively - what then?)


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

2011-07-13 Thread burnus at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #2 from Tobias Burnus  2011-07-13 
14:06:17 UTC ---
(In reply to comment #1)
> C test case matching the Fortran one, which also shows that the "if" is not
> optimized away.

According to Ian (cf. thread linked to in comment 0), C99's restrict does not
guarantee that the value remains the same after a function call. Assuming
that's the case, then C does not seem to have an equivalent qualifier to
Fortran's nontarget/nonasynchronous/nonpointer* variables. - And, hence, some
tree flag is missing to for such nonpointer* Fortran variables. (* pointer in
the Fortran sense.)

I failed to see this from C99's "6.7.3.1 Formal definition of restrict", which
is written in a rather convoluted way.


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

2011-07-13 Thread burnus at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49733

--- Comment #1 from Tobias Burnus  2011-07-13 
13:42:26 UTC ---
C test case matching the Fortran one, which also shows that the "if" is not
optimized away.

void some_function(void);

void
sub (int *restrict non_aliasing_var)
{
  *non_aliasing_var = 5;
  some_function ();
  if (*non_aliasing_var != 5)
foobar_();
}