- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We came across the following difference between OpenVMS FORTRAN and Ifort which seem like an ifort compiler bug.
Our Fortran Porting Tool detects and fixes occurrences - but - wanted to share.
I understand that the new fortran spec insists on INT('8000'X,2) = but - if this is a problem the ifort compiler should really "say" something.
PROGRAM rick
INTEGER*2 Int2
INTEGER*2 undef_i2ko
INTEGER*4 Int4
PARAMETER (undef_i2ko = '8000'X) ! DOESNT WORK
!PARAMETER (undef_i2ko = -32768) WORKS
!PARAMETER (undef_i2ko = INT('8000'X,2)) WORKS
Int2 = undef_i2ko
Int4 = Int2
write (*,'(" undef_i2ko : ",1Z4.4,I10)') undef_i2ko, undef_i2ko
write (*,'(" Int2 : ",1Z4.4,I10)') Int2, Int2
write (*,'(" Int4 : ",1Z8.8, I10)') Int4, Int4
! ===========================================================
! seem to substitute X8000 for undef_i2ko and not sign extend
! ===========================================================
IF (Int4 .NE. undef_i2ko) THEN
WRITE(*,*)' IF (Int4 .NE. undef_i2ko) Should not happen'
ELSE
WRITE(*,*)'seems ok'
ENDIF
END
iFORT:
undef_i2ko : 8000 -32768
Int2 : 8000 -32768
Int4 : FFFF8000 -32768
IF (Int4 .NE. undef_i2ko) Should not happen
VMS
undef_i2ko : 8000 -32768
XInt2 : 8000 -32768
XInt4 : FFFF8000 -32768
seems ok
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is indeed a bug here. The IF is comparing an INTEGER(4) with an INTEGER(2). The standard says:
In the numeric relational operation
x1 rel-op x2
if the types or kind type parameters of x1 and x2 differ, their values are converted to the type and kind type parameter of the expression x1 + x2 before evaluation.
(You'd then need to find that rule that basically says convert to the kind with the higher range - INTEGER(4) in this case.)
But if I look at the (x86) assembly code for the comparison, I see this:
;;; ! ===========================================================
;;; ! seem to substitute X8000 for undef_i2ko and not sign extend
;;; ! ===========================================================
;;; IF (Int4 .NE. undef_i2ko) THEN
0019f 8b 45 fc mov eax, DWORD PTR [-4+ebp]
$LN112:
001a2 3d 00 80 00 00 cmp eax, 32768
$LN113:
001a7 74 4f je .B1.10 ; Prob 50%
$LN114:
It's easier to see what's going wrong when you view this in the debugger, but I can't copy from there. The comment has it right - the cmp instruction is comparing the value Z'FFFF8000' from Int4 with the constant Z'00008000' - these are not equal. The compiler is failing to promote the INTEGER(2) named constant to INTEGER(4), as the standard says it must.
Now, I agree that this program is VERY non-standard, but I firmly believe that this is a bug and should be reported through the Online Service Center.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ifort /stand test.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Build 20201112_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
test.f90(5): warning #6924: Fortran 2018 does not allow this constant. ['8000'X]
PARAMETER (undef_i2ko = '8000'X) ! DOESNT WORK
------------------------^
test.f90(2): warning #6916: Fortran 2018 does not allow this length specification. [2]
INTEGER*2 Int2
--------^
test.f90(3): warning #6916: Fortran 2018 does not allow this length specification. [2]
INTEGER*2 undef_i2ko
--------^
test.f90(4): warning #6916: Fortran 2018 does not allow this length specification. [4]
INTEGER*4 Int4
--------^
Microsoft (R) Incremental Linker Version 14.16.27039.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test.exe
-subsystem:console
test.obj
You are expecting non-standard Fortran from one compiler to behave in the same non-standard way in another compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PROGRAM rick
INTEGER(2) :: Int2
INTEGER(2), parameter :: undef_i2ko = int(z'8000', 2)
INTEGER(4) :: Int4
Int2 = undef_i2ko
Int4 = Int2
write (*,'(" undef_i2ko : ",1Z4.4,I10)') undef_i2ko, undef_i2ko
write (*,'(" Int2 : ",1Z4.4,I10)') Int2, Int2
write (*,'(" Int4 : ",1Z8.8, I10)') Int4, Int4
! ===========================================================
! seem to substitute X8000 for undef_i2ko and not sign extend
! ===========================================================
IF (Int4 .NE. undef_i2ko) THEN
WRITE(*,*)' IF (Int4 .NE. undef_i2ko) Should not happen'
ELSE
WRITE(*,*)'seems ok'
ENDIF
END
C:\Users\cadfi\OneDrive\Desktop\zzz>ifort /stand test.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.1 Build 20201112_000000
Copyright (C) 1985-2020 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.16.27039.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:test.exe
-subsystem:console
test.obj
C:\Users\cadfi\OneDrive\Desktop\zzz>test
undef_i2ko : 8000 -32768
Int2 : 8000 -32768
Int4 : FFFF8000 -32768
seems ok
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the interesting point is that printing int2, in4, undef_i2ko ALL print as -32768 SO - WHY is the comparison failing ??
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
it is not standard fortran in fixed or free format. '8000'X is not valid Fortran it is a not standard language extension. Compile with /stand option. The example I showed is standard and works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
a 4 byte integer can't be bitwise identical to a 2 byte integer, they have a different number of bits.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
if undek_i2ko == -32768 and int4 == -32768 they should be exactly the same, regardless of the # of bits.
otherwise you would have to program every "compare" to compare against variables of exactly the same bit width.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
int(z'8000',2) = -32768
int(z'8000',4) = 32768
They are not the same
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is indeed a bug here. The IF is comparing an INTEGER(4) with an INTEGER(2). The standard says:
In the numeric relational operation
x1 rel-op x2
if the types or kind type parameters of x1 and x2 differ, their values are converted to the type and kind type parameter of the expression x1 + x2 before evaluation.
(You'd then need to find that rule that basically says convert to the kind with the higher range - INTEGER(4) in this case.)
But if I look at the (x86) assembly code for the comparison, I see this:
;;; ! ===========================================================
;;; ! seem to substitute X8000 for undef_i2ko and not sign extend
;;; ! ===========================================================
;;; IF (Int4 .NE. undef_i2ko) THEN
0019f 8b 45 fc mov eax, DWORD PTR [-4+ebp]
$LN112:
001a2 3d 00 80 00 00 cmp eax, 32768
$LN113:
001a7 74 4f je .B1.10 ; Prob 50%
$LN114:
It's easier to see what's going wrong when you view this in the debugger, but I can't copy from there. The comment has it right - the cmp instruction is comparing the value Z'FFFF8000' from Int4 with the constant Z'00008000' - these are not equal. The compiler is failing to promote the INTEGER(2) named constant to INTEGER(4), as the standard says it must.
Now, I agree that this program is VERY non-standard, but I firmly believe that this is a bug and should be reported through the Online Service Center.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page