Fortran associativity rules

Scanned the forum for this topic and did not see anything, sorry if I missed it and this is a repeat.

We have been using Fortran on many platforms and had converted some of our simulations from Sun Solaris Sparcworks to PGI 5.2 back some time ago. There are numeric shifts but nothing that we could not live with.

Recently we received new Linux RHE4 devices with PGI 7.0 installed. What I thought would be a trivial task of just switching out our current RH9 devices running 5.2 with RHE4 devices running 7.0 was not a drop in.

I was hoping that the new compiler and machine would match the results generated on the 5.0 devices but they do not. Tracing down to see where we get our first numeric shifts indicates differences in how associative rules are applied for both multiplication and division.

Sample code snip (actual values pulled from a complex run used in sample):

REAL A1, B1, C1, Z1
REAL A2, B2, C2, Z2
A1 = 24955.289062500
B1 = 0.998889029
C1 = 0.999865353

A2 = 46.095016
B2 = 4.7642002
C2 = .20989881

Z1 = A1 / B1 / C1
write (6,1) Z1
1 format ( 'Division : A1 / B1 / C1 = Z1 ',F20.9)

Z1 = (A1 / B1) / C1
write (6,2) Z1
2 format ( 'Division : (A1 / B1) / C1 = Z1 ',F20.9)

Z1 = A1 / (B1 / C1)
write (6,3) Z1
3 format ( 'Division : A1 / (B1 / C1) = Z1 ',F20.9)

Z2 = A2 * B2 * C2
write (6,10) Z2
10 format (/,'Muliplication : A2 * B2 * C2 = Z2 ',F20.9)

Z2 = (A2 * B2) * C2
write (6,11) Z2
11 format ( 'Muliplication : (A2 * B2) * C2 = Z2 ',F20.9)

Z2 = A2 * (B2 * C2)
write (6,12) Z2
12 format ( 'Muliplication : A2 * (B2 * C2) = Z2 ',F20.9)


Using new RHE4 and PGI 7.2 (pgf77) :

Division : A1 / B1 / C1 = Z1 24986.408203125
Division : (A1 / B1) / C1 = Z1 24986.410156250
Division : A1 / (B1 / C1) = Z1 24979.679687500

Muliplication : A2 * B2 * C2 = Z2 46.095012665
Muliplication : (A2 * B2) * C2 = Z2 46.095012665
Muliplication : A2 * (B2 * C2) = Z2 46.095016479

Using older RH9 and PGI 5.0 :

Division : A1 / B1 / C1 = Z1 24986.408203125
Division : (A1 / B1) / C1 = Z1 24986.408203125
Division : A1 / (B1 / C1) = Z1 24979.679687500

Muliplication : A2 * B2 * C2 = Z2 46.095016479
Muliplication : (A2 * B2) * C2 = Z2 46.095016479
Muliplication : A2 * (B2 * C2) = Z2 46.095016479

We have literally tens of millions of lines of code that represent every engine Pratt & Whitney has ever created and modifying the code is not even a remote possibility at this point.

Any suggestions on how to handle this situation where converting from 5.2 to 7.0 is altering our results? I have attempted several of the compiler options, pretty much anything that even hinted it might help but to no avail.



We need to know what compilers and options you are using.
32-bit, 32-bit (-tp px???), 64-bit, ??? Which version did you compare with 5.0 or 5.2?


If you compile your program with -tp piii (or with any other -tp option without SSE2 support) then you will get the same result as on PGI 5.x

Thanks for the guidance … The new device does appear to be 64 bit but looked to be compiling for 32 bit already:

pgf77 -V

pgf77 7.0-6 32-bit target on x86-64 Linux
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2007, STMicroelectronics, Inc. All Rights Reserved.

I went through and recompiled the libraries using the first suggesition of -tp=px and that indeed did match results for the older 5.2 compiler.

I had tried -tp=core2 and tp=core2-64 which did not help but had not tried the generic pentium options.

At this point, I think we are good.


Of course I am now questioning what the “correct” answer is at this point. Changing the code to higher precision r*8 variables and using the -r8 option yields yet another answer.

Division : A1 / B1 / C1 = Z1 24986.408845424
Division : (A1 / B1) / C1 = Z1 24986.408845424
Division : A1 / (B1 / C1) = Z1 24979.680608439

Muliplication : A2 * B2 * C2 = Z2 46.095013814
Muliplication : (A2 * B2) * C2 = Z2 46.095013814
Muliplication : A2 * (B2 * C2) = Z2 46.095013814


I would look at:, section “How come we get different answers on one platform vs a linux x86 platform?”


Thanks Hongyon.

the actual link is and I had looked at it previously. Surprisingly the -pc 32/64/80 options had zero effect on the output of that little test case.


Those -pc options will have an impact when you use with -tp px. It may or may not have an effect for 64-bit or -tp k8-32 because we mostly use SSE instructions for those operations.


Can we optionally turns off SSE2/SSE3 for 64bit mode?
May be by editing some *rc files in bin directory…

For 64-bit, we don’t generate x87 instructions.

What is your goal for turning off SSE2/SSE3? If this is for the test above, just use 32-bit.


I will don’t create another topic but asking here:
Where I can to see full TPR list (yet unresolved problems in your products)?

We don’t have a full tpr list available. You can find recent fixed tpr at the end of a release notes and also for older releases at: If you want to get a status of specific tpr, email to and ask of its progress.