- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jimdempseyatthecove wrote: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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We have 1.5M LoC to refactor (too sad)
No one will do refactoring
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Opps, wrong thread. this is in reference to this follow on thread https://community.intel.com/t5/Intel-Fortran-Compiler/pointer-to-procedure-is-constant-while-should-not/m-p/1634195
I combined the sources to one source to help with the analysis.
cat common.f90 alloc.f90 test.f90 main.f90 >> repro.f90
Indeed, ifx is behaving differently. Using opt-bisect-limit I've isolated the difference at opt phase
EarlyCSEPass
There is a LLVM bug report on this function but it seems completely unrelated to your test case.
EarlyCSEPass In my compiler is optimization 421. 420 naturally abides.
If you've not used opt-bisect-limit here is how to do it - binary search on the optimization numbers
ifx -O3 -mllvm -opt-bisect-limit=420 repro.f90 && ./a.out
this works, 420 friendly ( I can't make this stuff up)
and this does not
ifx -O3 -mllvm -opt-bisect-limit=421 repro.f90 && ./a.out
I have what I need to dig in deeper. This issue is also present in the 2025.0 branch and the main branch "2025.1".
I will now see if I can reduce this test case down some more.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh! Thank you! I will try to use opt-bisect for next bug reports
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page