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

Any known bugs with IA64 and optional arguments.

keith-refson
Beginner
911 Views

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

0 Kudos
10 Replies
Steven_L_Intel1
Employee
911 Views
I have a vague memory of a reference to an optional argument being incorrectly moved to above the present test by an older version of the compiler. 9.1.041 is current. If you can still reproduce it in that version, please send us a test case.
0 Kudos
keith-refson
Beginner
911 Views
Dear Steve,

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
0 Kudos
Steven_L_Intel1
Employee
911 Views
Glad to hear it.
0 Kudos
jimdempseyatthecove
Honored Contributor III
911 Views

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.

0 Kudos
Steven_L_Intel1
Employee
911 Views

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

0 Kudos
mpbro
Beginner
911 Views
Hello folks,

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



0 Kudos
Steven_L_Intel1
Employee
911 Views
You didn't find a compiler bug, but a bug in your own code. You have this:

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.
0 Kudos
mpbro
Beginner
911 Views
Steve,

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 :: b
and
integer :: b
optional :: b

For 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.

Thanks,
Morgan

PS: as an aside, I could swear that I was programming this way when I used the PGF F90 compiler.
0 Kudos
Steven_L_Intel1
Employee
911 Views
The two blocks of code have identical meaning. In Fortran, you can specify attributes for variables in a single or multiple declarations, as long as you don't specify the same attribute more than once. Some attributes are not available as statements (INTENT, for example).

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.
0 Kudos
Steven_L_Intel1
Employee
911 Views
For further reading, see an article I wrote many years ago on The Virtues of Omission.
0 Kudos
Reply