Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28455 Discussions

common variable passed as argument of function is overoptimized

foxtran
New Contributor I
814 Views

The following 4 files compiled with ifx 2023.2.0 (ifx (IFX) 2023.2.0 20230622), gives different answers without and with optimization:

==> alloc.f90 <==

integer function alloc(n)
  use common_mod
  integer n
  alloc = imem + n
  imem = imem + n
end function alloc

==> common.f90 <==

module common_mod
  common/actmem/imem
  integer imem
end module common_mod

==> main.f90 <==

program main
  common/actmem/imem
  integer imem
  imem=0
  call test(imem)
end program main

==> test.f90 <==

subroutine test(imem)
  integer :: res
  print *, imem
  res = alloc(8)
  print *, imem
end subroutine test

 Compilation & execution:

$ ifx common.f90 alloc.f90 test.f90 main.f90 -O0 && ./a.out
           0
           8
$ ifx common.f90 alloc.f90 test.f90 main.f90 -O1 && ./a.out
           0
           0


With ifort (ifort (IFORT) 2021.10.0 20230609) it works fine at any level of optimisation. 

Possible solution is to make imem in test routine volatile. Then, with ifx the code works fine.

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
808 Views

The other solution is to write code that doesn't violate the standard. In subroutine test, the compiler can't see that imem is modified in the call to alloc, and this breaks:

Screenshot 2024-02-17 115355.png 

 

View solution in original post

7 Replies
Steve_Lionel
Honored Contributor III
809 Views

The other solution is to write code that doesn't violate the standard. In subroutine test, the compiler can't see that imem is modified in the call to alloc, and this breaks:

Screenshot 2024-02-17 115355.png 

 

foxtran
New Contributor I
797 Views

Thank you, @Steve_Lionel !

0 Kudos
mecej4
Honored Contributor III
633 Views

In addition to the points discussed so far, please note another: the type of the function ALLOC is implicitly taken as REAL in subroutine TEST. In the larger code that underlies the tiny examples that you displayed, check that such mismatched function types do not exist.

0 Kudos
jimdempseyatthecove
Honored Contributor III
789 Views

@Steve_Lionel 

When a common block is specified in a module is the common block contained in the scope of the module? (accessible only via use module name)

If so, then the above code has two different common blocks, one global (provided in PROGRAM MAIN) and the other contained within module common_mod.

 

@foxtran 

The correct way for your code to run is to remove common/actmem/imem from common_mod in common.f90 and in program main in main.f90, then add "use common_mod" to program main.

 

Jim Dempsey

 

0 Kudos
Steve_Lionel
Honored Contributor III
782 Views

@jimdempseyatthecove wrote:

@Steve_Lionel 

When a common block is specified in a module is the common block contained in the scope of the module? (accessible only via use module name)

No - a COMMON block is a global identifier. I'll also note that COMMON is obsolescent and imem should have been a module variable. But even if it was, the same rule applies, so even changing it to a module variable would not fix the issue. The better choice, though obviously this is a made-up example, is to not pass global or module variables as procedure arguments if they can be modified in the called procedure.

0 Kudos
FortranFan
Honored Contributor II
582 Views

 


@foxtran wrote:

..

Possible solution is to make imem in test routine volatile. Then, with ifx the code works fine.


@foxtran ,

Re: "Possible solution is to make imem in test routine volatile" - this is all playing with "fire", sooner or later someone or something is going to get "burnt".

You may be better off sticking to IFORT with such legacy code for now but strongly consider refactoring the code ASAP to be standard-compliant and to migrate to IFX.

 

0 Kudos
foxtran
New Contributor I
569 Views

We have 1.5M LoC to refactor (too sad)

No one will do refactoring

0 Kudos
Reply