[patch] Flag-controlled type conversions/promotions
Zydrunas Gimbutas
zydrunas.gimbutas@gmail.com
Mon Dec 26 19:34:00 GMT 2011
Hi all,
Attached are three test file, that stress the type-promotion patch.
>> The difference between -fdefault-*-8 and -f*-4-*-8 should probably also be documented.
>>
>
> It is documented for the -freal-* options. The manual has, for example,
>
> -freal-4-real-8
> Promote REAL(KIND=4) entities to REAL(KIND=8) entities. If KIND=8 is unavail-
> able, then an error will be issued. All other real kind types are unaffected
> by this option.
>
> The last sentence is the same for the other options. This literally means
> that only REAL(4) is effected by the -freal-4-real-8 option. If one reads
> he description of -fdefault-*, one will that -freal-4-real-8 is equivalent
> to specifying both -fdefault-real-8 and -fdefault-double-8.
>
-freal-4-real-8 is not equivalent to -fdefault-real-8 and -fdefault-double-8.
-freal-4-real-8 interprets any 4-byte real type, whether it is a
default real type or explicitly declared as 4-byte, as a 8-byte double
precision type, and that applies to all variables, functions and
constants.
-fdefault-real-8 will promote only default real type to double
precision and only variables and functions. Since constants are
usually declared explicitly as 4-byte, e.g. 1.01223e0 is an explicitly
defined 4-byte constant in gfortran, they will not be promoted.
$ gfortran -freal-4-real-8 test-r4.f
$ a.out
0.90929742682568171
0.90929742682568171
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
0.0000000000000000
but
$ gfortran -fdefault-real-8 -fdefault-double-8 test-r4.f
$ a.out
0.90929742682568171
0.90929741
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
-2.01522503129325514E-008
Note how constants are truncated to single precision, while using
-fdefault-real-8 -fdefault-double-8.
The same promotion convention applies to other -freal-*-real-*, and
-finteger-*-integer-* flags.
For example, -fdefault-integer-8 is not equivalent to
-finteger-4-integer-8, because integer*4 types and constants are being
interpreted in a different way, see test-i4.f test:
$ gfortran -fdefault-integer-8 test-i4.f
test-i4.f:6.8:
j=2**40
1
Error: Arithmetic overflow converting INTEGER(8) to INTEGER(4) at (1).
This check can be disabled with the option -fno-range-check
The error above is due to inability of standard gfortran to promote
explicitly declared integer*4 type to integer*8.
$ gfortran -finteger-4-integer-8 test-i4.f
$ a.out
1099511627776
1099511627776
This fixes the above problem.
Finally,
$ gfortran -freal-8-real-16 test-r8.f
$ a.out
0.90929742682568169539601986591174487
0.90929742682568169539601986591174487
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
We have nothing to compare this result with since, currently, gfortran
has no facility to promote double precision to real*16 (no
-fdefault-double-16 flag).
>> Last point for this batch is that using '-freal-8-real-10 -freal-8-real-16' does not
>> generate an error, the last option being the one used.
>
> Yes, that is correct. Consider it to be similar to '-Os -O -O2 -O0'. The
> last one wins. Note, there is this combination: '-freal-4-real-8 -freal-8-real-16'
> which will promote both REAL(4) and (8) to REAL(16).
>
One caveat here, we have not attempted to chain constant conversion in
this patch.
This combination will promote real*4 constants to real*8, and real*8
constants to real*16,
$ gfortran -freal-4-real-8 -freal-8-real-16 test-r4.f
$ a.out
0.90929742682568169539601986591174487
0.90929742682568169539601986591174487
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
1.40209065578162555042101269140459185E-0017 <- constant truncation
0.0000000000000000000000000000000000
1.40209065578162555042101269140459185E-0017 <- constant truncation
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
While this combination will promote real*4 constants to real*16, and
real *8 constants to real*16,
$ gfortran -freal-4-real-16 -freal-8-real-16 test-r4.f
$ a.out
0.90929742682568169539601986591174487
0.90929742682568169539601986591174487
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
0.0000000000000000000000000000000000
The second promotion declaration is cleaner, but the declaration
chaining may be worth the effort.
The patch has been tested on Fortran 77 and Fortran 95 codes, so as
for the errors in coarray tests, it is quite possible that we have
simply missed some kind of type processing/declaration since this is a
relative new Fortran feature, sorry about that.
Zydrunas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-r4.f
Type: text/x-fortran
Size: 790 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20111226/3b0d427e/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-r8.f
Type: text/x-fortran
Size: 824 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20111226/3b0d427e/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test-i4.f
Type: text/x-fortran
Size: 118 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20111226/3b0d427e/attachment-0002.bin>
More information about the Fortran
mailing list