Operating System - OpenVMS
1752720 Members
5689 Online
108789 Solutions
New Discussion

Re: Overflow during compile - Fortran compiler on I64

 
SOLVED
Go to solution
abrsvc
Respected Contributor

Overflow during compile - Fortran compiler on I64

With OpenVMS V8.4 and HP Fortran V8.2-104939 on Itanium I get an overflow message during a compile.  This makes no sense as the variable on the left is defined as Integer*4 {Integer (kind=4)}.  Any ideas?

 

Please note that this is only a segment of the statement that has been broken out into multiple lines to isolate the issue.  Normally, I would just assign the resultant value to the variable.  This is legacy code that has similar lines throughout the code.

 

actual statement that failes:

        arcptr=399*195

 

The exact message is a warning:  Overflow occurred while evaluating constant expresion.

 

According to the docs, the expression should be evaluated as an Integer*4.  The actual valuie is 71370 which exceeds an Integer*2 variable, but not Integer*4.

 

Thanks,

Dan

 

8 REPLIES 8
Hein van den Heuvel
Honored Contributor

Re: Overflow during compile - Fortran compiler on I64

1) Minimal reproducer?

 

2) Did you try arcptr=199*195 and 99*195? The first one = 38805 and less is than 16 bits, but negative 

that might confirm your suspicious something told the compiler to expect integer*2

 

3) nowhere they use: SELECTED_INT_KIND

 

4) what does the list mention for type of arcptr

 

5) is the an integer(kind=2) used in the other segments?

 

fwiw, This silly program (of course) works for me:

 

$ type x.for
        PROGRAM test_x
        INTEGER*4 x
        x = 399*195
        TYPE *, 'x=', x
        END
$ fort/ver
HP Fortran V8.2-104939-50H96

 

 

Hein

 

 

John Gillings
Honored Contributor

Re: Overflow during compile - Fortran compiler on I64

Can you compile with /LIST/MACHINE/SHOW=ALL and post the listing from around the error message?

 

It might also be interesting to replace the code with:

 

    INTEGER*4 PARAMETER :: I399=399, I195=195
...
    arcptr=I199*I195

 

Since Fortran now allows typed constants, this will ensure that all the operands in the expression are explicitly typed as 32 bit. Another option would be to use the INT4 function.

 

 

       arcptr=INT4(199)*INT4(195)

 Implicit typing is great when it works, but if it's giving you grief, spell things out for the compiler.

A crucible of informative mistakes
Mike Kier
Valued Contributor

Re: Overflow during compile - Fortran compiler on I64

Or you might specify the kind on the constants in-line (although I prefer the explicit PARAMETER definition or using a SELECTED_INTEGER_KIND symbol)

 

arcptr = 399_4 * 195_4

 

This explicitly makes the RHS 32-bit - the compiler is free to evaluate the RHS without any regard whatsoever to the LHS and it may be the Itanium compiler chooses to do the entire evaluation in 16-bit since the larger of the two constants can fit in 16 (but not 8) bits.  You might try a similar computation with both constants less than 255 but the expected result under 32767 to see if it tries 8-bit (although whatever decision it makes is standard conforming).

 

The Alpha compiler I tested with gives identical (non-overflowing 32-bit) results for both methods.

Practice Random Acts of VMS Marketing
abrsvc
Respected Contributor

Re: Overflow during compile - Fortran compiler on I64

Thanks for the suggestions.  I will provide an update with the experiment results.  Also, please note that the variable ARCPTR is defined as an Integer*4.  This is legacy code and this is one example of similar warnings.  From what I understand, the compiler should be "upgrading" the constants to I*4 temporaries since the result is an I*4.

 

Fortran reference manual section 4.2.2.1 states:

 

==================================

 

If the variable has the same data type as that of the expression on the right,

the statement assigns the value directly. If the data types are different, the

value of the expression is converted to the data type of the variable before it is

assigned.

 

==================================

 

More to follow...

 

Dan

 

abrsvc
Respected Contributor
Solution

Re: Overflow during compile - Fortran compiler on I64

Further investigation reveals the following although I still wonder why the warning.

 

1) The compile line contained  the compiler switch /NOI4 which should default undefined integer variables to be I*2. (Remnant of old code that I am trying to update)

2) Removing the /NOI4 allows for clean compile.

3) Changing the calculation to the resultant value avoids the error (using 71370 rather than 366*195)  I am assuming that the compiler realizes that this requires an I*4 temporary.

 

So the bottom line here is that the temporary is created as an I*2 temporary beacuse of the command line switch.  My objection here is that per the reference manual, the compiler SHOULD up-copnvert this to an I*4 because of the target variable type (if I read it correctly).

 

I think a note to HP support is needed here...

 

Thanks for the suggestions.

 

Dan

John Gillings
Honored Contributor

Re: Overflow during compile - Fortran compiler on I64

>My objection here is that per the reference manual, the compiler SHOULD up-copnvert this

>to an I*4 because of the target variable type (if I read it correctly).

 

I don't think you've read it correctly. The compiler will convert the RESULT of the RHS expression to I4, but, as Mike pointed out, the type of the LHS of the assignment statement is NOT considered when evaluating the RHS expression. Since you told the compiler the constants should be I2, it chose to evaluate the expression as I2. Other compilers may choose to evaluate it as I4, but that's NOT because of the LHS.

 

Since Alpha lacks 16 bit arithmetic operations it needs to perform all arithmetic in 64 bit, then convert back. The Alpha code was probably generated as convert both operands to 64 bit, calculate, then convert back to 16 bit, then convert to 32 bit to store the result. The optimisation phase probably noticed the 64->16->32 and realised the 64->16 step could be dropped. That optimisation obscured your bug - multiplying two 16bit integers which overflow. It might be interesting to see what the Alpha compiler does with /NOOPTIMIZE. 

 

The Itanium compiler chose different code. Personally I prefer the Itanium behaviour because it revealed an invalid assumption and led you to find (and fix) the /NOI4 qualifier.  

A crucible of informative mistakes
abrsvc
Respected Contributor

Re: Overflow during compile - Fortran compiler on I64

Makes sense.  FWIW, the alpha does not generate any errors although on Alpha, the compiler is the F77 one.

 

As an aside, the F90 comipiler has also revealed additional "errors' in the code that were silent using other compilers.  For example, branches into IF blocks.  Legacy code is always a challenge.

 

Thanks for the explanation and corrections.

 

Dan

Mike Kier
Valued Contributor

Re: Overflow during compile - Fortran compiler on I64

This kind of thing is much more pronounced in the floating point world - in F90 and beyond, a floating point literal (e.g., 1.2)  is the default REAL precision - if you are using it in an expression requiring higher precision, since many fixed decimal fractions are repeating fractions in binary, then you need to clearly specify the KIND value.  The compiler will not automatically up-convert a KIND-less literal.

Practice Random Acts of VMS Marketing