[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::fortran

Title:Digital Fortran
Notice:Read notes 1.* for important information
Moderator:QUARK::LIONEL
Created:Thu Jun 01 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1333
Total number of notes:6734

1149.0. "am I "out of line" to use asm's?" by CUJO::SAMPSON () Fri Jan 24 1997 19:29

$!
$! The program in this DCL command procedure demonstrates that
$! Digital Fortran 77 for OpenVMS Alpha ASM's, when used and
$! enabled by the undocumented and unsupported /SWITCH=FE_ASM,
$! do not interact properly with /OPTIMIZE=INLINE.
$!
$ CREATE OUT_OF_LINE.FOR
C
C Generate the largest unsigned integer that fits
C into the specified number of bytes and/or bits.
C
	integer*8 function max_uint_value(nbytes, nbits)
	implicit none
	integer*4 nbytes, nbits

	integer*8 zapbytes
	integer*4 i
	integer*8 asm

	max_uint_value = 0
	max_uint_value = knot(max_uint_value)

	zapbytes = 0
	if (nbytes .gt. 0) then
	  do i = nbytes,7
	    zapbytes = kior(zapbytes,kibset(kzext(0),kzext(i)))
	  enddo
	endif

	max_uint_value = asm('zap %a0, %a1, %v0',
     +			max_uint_value, zapbytes)

	if ((nbits .ne. 0)
     +.and. ((nbytes .eq. 0)
     +	.or. (nbits .lt. (8*nbytes)))) then
	  do i = nbits,63
	    max_uint_value =
     +		kiand(max_uint_value,knot(kibset(kzext(0),kzext(i))))
	  enddo
	endif

	return
	end
C
C Main program.
C
	program out_of_line
	implicit none

	integer*8 uabove, ubelow, nunique, nsigned
	integer*4 mindvdbits, maxdvdbits
	integer*4 mindvrbits, maxdvrbits

	integer*8 max_uint_value
	external  max_uint_value
C
C Specify the minimum and maximum significant bit counts.
C
	mindvdbits = 64
	maxdvdbits = 64
	mindvrbits = 11
	maxdvrbits = 16
C
C Generate the largest unsigned integer divisor for maximum bits.
C Generate the largest unsigned integer divisor for less than minimum
C bits.  Get the number of possible unique unsigned divisor values.
C
	uabove = max_uint_value(8, maxdvrbits)
	ubelow = max_uint_value(8, mindvrbits-1)
	nunique = uabove - ubelow
	type *,'uabove =',uabove
	if (uabove  .ne. 65535) type *,'(unexpected value)'
	type *,'ubelow =',ubelow
	if (ubelow  .ne.  1023) type *,'(unexpected value)'
	type *,'nunique=',nunique
	if (nunique .ne. 64512) type *,'(unexpected value)'
	end
$!
$! Inlining produces incorrect results:
$!
$ FORTRAN/SWITCH=FE_ASM OUT_OF_LINE
$ LINK OUT_OF_LINE
$ RUN OUT_OF_LINE
$!
$! Disabling inlining produces correct results:
$!
$ FORTRAN/SWITCH=FE_ASM/OPTIMIZE=NOINLINE OUT_OF_LINE
$ LINK OUT_OF_LINE
$ RUN OUT_OF_LINE
$ EXIT
T.RTitleUserPersonal
Name
DateLines
1149.1any takers?CUJO::SAMPSONMon Jan 27 1997 08:413
	BTW, this problem report is for Digital Fortran 77 for OpenVMS
Alpha V7.1 SSB, which appears to be the first release to actually recognize
ASM's.
1149.2QUARK::LIONELFree advice is worth every centMon Jan 27 1997 09:274
Um, a bit of patience would be in order.  You posted .0 at 7:29PM (EST) on
Friday...

					Steve
1149.3just a Monday morning ticklerCUJO::SAMPSONMon Jan 27 1997 09:467
	Steve,

	Patience?  I've got lots of that.  It's now Monday morning.
I guess I've just become accustomed to your usual extremely quick
responses in this conference.  I'm not complaining, you understand.

	Bob Sampson
1149.4Working...TLE::EKLUNDAlways smiling on the inside!Mon Jan 27 1997 10:357
    	I've verified that the bug is still present in our
    current sources, and have passed it along to the right
    people.  Thanks for the small example!
    
    Cheers!
    Dave Eklund
    
1149.5QUARK::LIONELFree advice is worth every centMon Jan 27 1997 11:243
I don't know about you, but we generally don't work on weekends.

				Steve
1149.6FixedTLE::EKLUNDAlways smiling on the inside!Mon Jan 27 1997 16:2610
    	Fixed.  It was a (new) bug in final peepholing in the
    back end.  The ASM caused an unusual pattern, one not seen
    before in the back end.  This is the kind of error we might
    "expect" when we allow users to drop their own code into the
    instruction stream via ASM.  There are going to be things
    that are "unexpected", or at least new and different.  This
    was such a case.  
    
    Cheers!
    Dave Eklund
1149.7Wow! That was *too* fast!CUJO::SAMPSONMon Jan 27 1997 17:1914
	Dave,

	Excellent/Formidable/Muy Bueno/Fantastico/Opus Magnum!
Thank You/Merci/Gracias/Gratzi/Gratias!  Can you identify any
other particular ASM usage patterns and optimizations you might
want internal users to try out and check for problems?

	Steve,

	Of course, no response was expected until at least Monday.
Once again, you folks are doing a great job!

	Thanks,
	Bob Sampson
1149.8TLE::EKLUNDAlways smiling on the inside!Mon Jan 27 1997 17:2821
    	It's impossible to predict.  Moreover, one cannot
    expect ASM code to simply end up intact in the code stream.
    The instructions are totally integrated into the code stream
    which means that they are available to be optimized along with
    the rest of the code stream.  If the optimizer finds a "better"
    way to accomplish the same thing, it will do so...  This means
    that instructions may get rearranged, removed, separated, etc.
    There is NO guarantee that any ASM sequence is retained exactly
    as specified by the user; the code is available to the optimizer
    just like any other code the user writes in Fortran.
    
    Cheers!
    Dave Eklund
    
    PS I cannot really take the credit for this one - I merely
    passed it along to the back end group who are often just as
    speedy as we (front end) are!
    
    Cheers!
    Dave E
    
1149.9but, you're the messenger!CUJO::SAMPSONMon Jan 27 1997 18:0636
	Dave,

>    	It's impossible to predict.  Moreover, one cannot
>    expect ASM code to simply end up intact in the code stream.
>    The instructions are totally integrated into the code stream
>    which means that they are available to be optimized along with
>    the rest of the code stream.  If the optimizer finds a "better"
>    way to accomplish the same thing, it will do so...  This means
>    that instructions may get rearranged, removed, separated, etc.
>    There is NO guarantee that any ASM sequence is retained exactly
>    as specified by the user; the code is available to the optimizer
>    just like any other code the user writes in Fortran.

	That makes sense; I think it has also been true for ASMs in DEC C.
As long as the same result is acheived, it doesn't matter.  If the backend
(GEM?) group doesn't consider any test scenarios to have doubtful outcomes
(after this fix), then I'll just go ahead and use ASMs, without trying to
specifically look for more problems.
    
>    Cheers!
>    Dave Eklund
>    
>    PS I cannot really take the credit for this one - I merely
>    passed it along to the back end group who are often just as
>    speedy as we (front end) are!
>    
>    Cheers!
>    Dave E
    
	Well, *now* you can't, now that you've burst my bubble!
No, seriously, the messenger usually gets the credit (or the blame)!
Please thank the unidentified backend person for me, and tell
him/her that he/she's a GEM!

	Thanks,
	Bob Sampson
1149.10TLE::EKLUNDAlways smiling on the inside!Tue Jan 28 1997 09:347
    	Yes, you can go right ahead with using ASMs.  The backend
    code is the same as for C, where it has had more use than in
    Fortran (obviously).  I guess they never saw this case with C!
    
    Cheers!
    Dave Eklund
    
1149.11seems like I should have seen it in CCUJO::SAMPSONTue Jan 28 1997 22:1511
	Dave,

	Well, I stumbled across this case only after converting a program
(aidx.c; see DECC_BUGS topic 967.15) from DEC C to Digital Fortran 77
(aidx.for; coming soon to this FORTRAN conference).  So, it surprises me
just a little that the bug showed itself only in the Fortran version.
My workaround for the Fortran version was to replace the ZAP ASM in the
max_uint_value function with reasonably-equivalent intrinsic function calls.

	Thanks,
	Bob Sampson
1149.12WIBBIN::NOYCEPulling weeds, pickin' stonesWed Jan 29 1997 08:227
The problem arose because in the inlined copy of this statement:

	max_uint_value = asm('zap %a0, %a1, %v0',
     +			max_uint_value, zapbytes)

zapbytes was known to be zero.  Perhaps in the C version something
prohibited the compiler from knowing that?
1149.13good point, but the mystery thickensCUJO::SAMPSONWed Jan 29 1997 23:3226
>      <<< Note 1149.12 by WIBBIN::NOYCE "Pulling weeds, pickin' stones" >>>
>
>The problem arose because in the inlined copy of this statement:
>
>	max_uint_value = asm('zap %a0, %a1, %v0',
>     +			max_uint_value, zapbytes)
>
>zapbytes was known to be zero.  Perhaps in the C version something
>prohibited the compiler from knowing that?

	Yes, it's true that the actual argument for nbytes has the value of
eight in both of the calls, which renders both the "nbytes" loop and the ZAP
superfluous.  So, for this particular usage, optimization can and should throw
away both.  However, the "nbits" loop still must be implemented properly, and
the function value should be non-zero.

	This also holds true for the C version, but apparently the DEC C
compiler did not apply its optimizations quite so aggressively.  This
optimization really shouldn't make any difference in the result, though.

	The correct result is obtained when compiled with
FORTRAN/SWITCH=FE_ASM/OPTIMIZE=NOINLINE.  The incorrect function
value with /OPTIMIZE=INLINE isn't easy to explain, I guess,
unless you happen to know exactly what went wrong in the backend.

	Bob Sampson
1149.14WIBBIN::NOYCEPulling weeds, pickin&#039; stonesThu Jan 30 1997 08:307
> unless you happen to know exactly what went wrong in the backend.

If you're curious, what happened is that the compiler accidentally
transformed your ZAP max_uint_value, R31, max_uint_value into a
ZAPNOT max_uint_value, R31, max_uint_value.  Of course, it then
noticed that ZAPNOT with Rb=R31 always produces zero, and things
went downhill from there...