- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Has anyone noticed a miscompile producing a segmentation fault in recent versions of the IA64 compiler? I am attempting to compile an electronic structure code, CASTEP on such a system with l_fc_c_9.1.039. On the simplest test, if compiled at -O1, I see SEGVs in two places which go away, one by one, if the modules are recompiled at -O0. In two cases the debugger identifies the offending code as:
if(present(recip_dbetadg)) recip_dbetadg(to_grid(nn),:) = dres_dg
if( present(disp) ) then
s_coord = s_coord + disp
end if
(s_coord and disp are real(8), dimension(3) arrays, s_coord is local)
In the second case the debugger identifies the SIGSEGV as occurring on the line within the IF block. But in neither case is the optional argument present. So it appears that Ifort is taking the wrong branch and evaluating the code which is not safe because the actual argument is not present at the call.
The code is correct and all the caller has an INTERFACE to the callee (through USE), and this exact case works under ifort/x86, ifort x86/64, pathscale, g95, gfortran, Sun f95, CVF, Tru64,nag, lahey, IBM XLF and even Portland compilers.
If anyone has seen this or even has access to the bugs database to check for anything similar I'd appreciate hearing about it.
Keith Refson
Link Copied
- 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
Thanks very much for the helpful response. I have managed to test this and indeed this bug is fixed in 9.1.041.
Intel do deserve some praise for enabling easy userspace installs of the compiler suite. I was able to install, picking up the existing system license without needing to bother the sysadmins at all, and test in an hour rather than days or weeks :)
Keith Refson
- 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
Keith,
Although you have worked around this probem (bug) with an upgrade you might consider a different coding style for argument presentwhereby you test for present at the front of the routine, placing the results of the test into a logical, then use the logical later to bypass code for non-present arguments. Most optimizations tend to be localized. If you find this failing (due to future bug), try adding VOLATILE to the logicals holding the present flags. With this, the compiler should not optimize out the storage of of the TRUE/FALSE of the test for present.
Jim Dempsey.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim's suggestion is interesting, but is not one I'd be quick to recommend. It makes more assumptions about the compiler than the simple PRESENT test. With the bug fixed, a PRESENT test is correct and easy to understand (and is standard).
Depending on how you use optional arguments, you might consider a strategy which is illustrated in the WinPrint sample for the Windows compiler. If you use optional arguments for input values and there's a default if the argument is omitted, declare a local variable for each optional arg and then at the front of the routine, have code like this:
if (present(arg)) then
lcl_arg = arg
else
lcl_arg = default_value
end if
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I seem to be getting this bug on Fedora Core 7, with ifort 10.1 20070913. Here is a program, module, and compilation rule that segfaults at the logical test for the first optional arg.
!=======================================================================
program myprog
use mymod
implicit none
write(0,*) '---------------------------------------------------------'
write(0,*) 'call w/opt arg b: present_test(2)'
call present_test(2)
write(0,*) '---------------------------------------------------------'
write(0,*) 'call w/opt args b and c: present_test(2,b=3,c=4)'
call present_test(2,b=3,c=4)
write(0,*) '---------------------------------------------------------'
write(0,*) 'calling w/opt arg b, w/o opt arg c: present_test(2,b=3)'
call present_test(2,b=3)
write(0,*) '---------------------------------------------------------'
write(0,*) 'calling w/opt arg c, w/o opt arg b: present_test(2,c=4)'
call present_test(2,c=4)
end program myprog
!=======================================================================
!=======================================================================
module mymod
implicit none
contains
!-----------------------------------------------------------------------
subroutine present_test( a, b, c )
integer, intent(IN) :: a
integer, optional :: b, c
write(0,*) 'mandatory argument a=',a
if( present(b) ) then
write(0,*) 'I found optional argument b=',b
else
write(0,*) 'I did not find optional argument b, set it to 1'
b=1
write(0,*) 'I set b to',b
end if
if( present(c) ) then
write(0,*) 'I found optional argument c=',c
else
write(0,*) 'I did not find optional argument c, set it to 1'
c=1
write(0,*) 'I set c to',c
end if
end subroutine present_test
!-----------------------------------------------------------------------
end module mymod
!=======================================================================
ifort -c -assume bscc -assume byterecl -fpp -mtune=pentium4 -O3 -static-intel -vms -w -WB -threads mymod.f90 -o mymod.o
ifort -assume bscc -assume byterecl -fpp -mtune=pentium4 -O3 -static-intel -vms -w -WB -threads mymod.o Myprog.f90 -o present_test
Save the first file as Myprog.f90, the second as mymod.f90, then run the executable with ./present_test
I have a different example with multiple optional arguments. There, I find that the SIGSEGV occurs when I reach the first *unspecified* optional argument, but I can successfully call it if I specify all the optional args.
Weird!
Morgan Brown
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if( present(b) ) then
write(0,*) 'I found optional argument b=',b
else
write(0,*) 'I did not find optional argument b, set it to 1'
b=1
write(0,*) 'I set b to',b
end if
When this code is executed, if b is NOT present, you store 1 into it. This is illegal. You seem to be under the impression that there is a "local copy"of all arguments and that you can supply default values this way. It doesn't work that way in Fortran.
One approach is to declare your own local copy of b and initialize it accordingly. For example:
integer local_b
...
if (present(b)) then
local_b = b
else
local_b = 1
end if
and then reference only local_b in the rest of the code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Interesting explanation. I read your previous post before responding, but somehow did not make the connection. Here is a related question: are the two code blocks equivalent from the compiler's perspective?
integer, optional :: band
integer :: bFor some reason (and I'm not a compiler guy), I'd suspect that the second block of code might make the "local copy" of variable b, whereas the first block of code would not.
optional :: b
Thanks,
Morgan
PS: as an aside, I could swear that I was programming this way when I used the PGF F90 compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is no condition under which the compiler would construct a local copy for an omitted actual argument. I know that some languages, such as PHP, have a model where you have a local copy created with a default value, but not Fortran.
I can't speak for the PGI compiler. They could have such behavior as an extension, but I would find this very odd and contrary to the way dummy arguments work in Fortran.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page