sundman@ttds.UUCP (Bo Sundman) (01/22/85)
C The following piece of code is extracted from a numerical routine for which C I am not guilty. However, I am expected to make it work on f77 under C UNIX and I do not understand why it does not work. C The code works perfectly on a number of machines, including Fortran C on VAX/VMS, but f77 does not give the correct value on the same VAX. C C The intention of the code is, I believe, to store integer indices for matrix C elements in the only available workspace, a real array. I guess the reason C for the equivalence is to avoid conversion from real to integer and back C either to increase speed or to avoid rounding off errors. C IMPLICIT DOUBLE PRECISION (A-H,O-Z) DIMENSION W(10),NW(2) EQUIVALENCE (WW,NW(1)),(NQ,NW(2)) C MEMORY MAP OF WW, NW AND NQ C WORD: 1 2 C WW (..............) C NW (...1..)(...2..) C NQ (......) C C Storing an integer value into NQ is thus equivalent to storing the same C bit pattern into the least significant word of WW. C WRITE(*,*)'Test 1' NQ=10 WRITE(*,*)'Values should be 0 10:',NW W(5)=WW NQ=100 WRITE(*,*)'Values should be 0 100:',NW WW=1. WRITE(*,*)'Values should be 16512 0:',NW WW=W(5) WRITE(*,*)'Values should be 0 10:',NW,' <<< wrong' WRITE(*,*)'Test 2, WW=1.' WW=1. NQ=10 WRITE(*,*)'Values should be 16512 10:',NW W(5)=WW NQ=100 WRITE(*,*)'Values should be 16512 100:',NW WW=1. WRITE(*,*)'Values should be 16512 0:',NW WW=W(5) WRITE(*,*)'Values should be 16512 10:',NW END C C Output: C Test 1 Values should be 0 10: 0 10 Values should be 0 100: 0 100 Values should be 16512 0: 16512 0 Values should be 0 10: 0 0 <<< THIS IS WRONG Test 2, WW=1. Values should be 16512 10: 16512 10 Values should be 16512 100: 16512 100 Values should be 16512 0: 16512 0 Values should be 16512 10: 16512 10 My conclusion is that the run time system is "smart" and when it shall make the assignment WW=W(5) it discovers that the exponent of W(5) is zero, which normally means that W(5) IS zero, and it assigns zero to WW rather than copying the value of W(5) to WW. It may save some nanoseconds of execution time but is nontrivial in a case like this. -- Bo Sundman (..mcvax!enea!ttds!sundman) Thermo-Calc group, Division of Physical Metallurgy The Royal Institute of Technology Stockholm, Sweden
donn@utah-gr.UUCP (Donn Seeley) (01/27/85)
Bo Sundman (sundman@ttds.UUCP) and Steve Correll (sjc@angband.UUCP) write about a problem with equivalences. Steve Correll is correct in pointing out that the basic problem is that the VAX has floating point move instructions which normalize data; these instructions also may cause reserved operand faults for malformed data. The 4.2 BSD compiler generates floating point move instructions for floating point assignments when optimization is not enabled. In the examples, the 'wrong' result is achieved by taking a variable last defined as an INTEGER, treating it as a DOUBLE PRECISION value and assigning it to a DOUBLE PRECISION variable, then treating the result as an INTEGER. Jerry Berkman at Berkeley has a change, implemented in recent versions of the compiler, which causes integer move instructions to be substituted for floating point move instructions in all situations, not just when optimizing. The change is fairly complicated and is one of many that I haven't posted since I began using code from post-4.2 BSD versions of the C compiler... At any rate, both Sundman's and Correll's examples work 'correctly' with the local version of f77 because an integer move is a straightforward copy with no normalization or checks for well-formedness. Of course the behavior of the examples under the 4.2 compiler is technically in accord with the standard. Section 17.3 of ANSI X3.9-1978, subsection 2, states: 'When an entity of a given type becomes defined, all totally associated entities of different type become undefined.' You are strongly advised not to write code that assumes that undefined values are predictable. But (sigh) there are lots of old programs written by people who 'knew' there would never be a problem, so the next release of the compiler will support them. Before Jerry's fix, I used to arrange for 'make' to run 'sed' on the assembler output of the compiler when not optimizing so that all 'movf' and 'movd' instructions were changed to 'movl' and 'movq' instructions. It's something to think about... If you're really desperate, write me for a copy of the new compiler. FTP is encouraged, tapes are tolerated but have a long turnaround... Donn Seeley University of Utah CS Dept donn@utah-cs.arpa 40 46' 6"N 111 50' 34"W (801) 581-5668 decvax!utah-cs!donn