forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Common block problem

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> 64-bit
View previous topic :: View next topic  
Author Message
DietmarSiepmann



Joined: 03 Jun 2013
Posts: 91

PostPosted: Wed Mar 15, 2017 1:24 pm    Post subject: Common block problem Reply with quote

The following code (named test_common_block1.for) uses a common block; the 64 bit executable created from test_common_block1.for via ftn95 8.10 produces strange results at runtime and strange behaviour when debugging.

Both the strange results and behaviour do not occur if compiling a 32 bit executable (with ftn95 8.10) or if deactivating/commenting the common block statement for the 64 bit executable.

Code of progamme test_common_block1.for:
Code:

      LOGICAL*2 LOGLLT,LOGHSP

      COMMON /COMIW2/ LOGLLT
     
      LOGLLT=.FALSE.
      LOGHSP=.FALSE.

      write(*,*) 'LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      IF(LOGLLT .OR. LOGHSP) THEN
       write(*,*) 'In if: LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      ENDIF
      END

Problem: the 64 bit executable executes the write statement within the second if clause although both LOGLLT and LOGHSP are set to .FALSE.

Moreover when debugging (using sdbg64), line 9 which is "IF(LOGLLT .OR. LOGHSP) THEN" is not marked with a dot at the leftmost position shown in the debugger.

Now, if I comment out the line with the common block (resulting in file test_common_block2.for), the second print statement is not executed
(as I would expect) and the line mentioned above is marked properly with a dot within the debugger.

Code of progamme test_common_block2.for:
Code:

      LOGICAL*2 LOGLLT,LOGHSP

C      COMMON /COMIW2/ LOGLLT
     
      LOGLLT=.FALSE.
      LOGHSP=.FALSE.

      write(*,*) 'LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      IF(LOGLLT .OR. LOGHSP) THEN
       write(*,*) 'In if: LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      ENDIF
      END

Moreover, if I change the if clause in test_common_block1.for in line 9 from "IF(LOGLLT .OR. LOGHSP) THEN" to "IF(LOGLLT) THEN" , resulting in file test_common_block3.for, then the second write statement is not excuted for the 64 bit executable created; however, the debugger sdbg64 does not mark the if clause with a dot.
Code:
      LOGICAL*2 LOGLLT,LOGHSP

      COMMON /COMIW2/ LOGLLT
     
      LOGLLT=.FALSE.
      LOGHSP=.FALSE.

      write(*,*) 'LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      IF(LOGLLT) THEN
       write(*,*) 'In if: LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      ENDIF
      END

Compile statements for file test_common_block1.for:
ftn95 /64 test_common_block1.for /debug /link
ftn95 test_common_block1.for /debug /link

ftn95 version information: (ftn95 -Vers)
Version: 8.10.0
Built: Sat Feb 11 12:23:39 2017

Regards,
Dietmar
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 673

PostPosted: Wed Mar 15, 2017 2:22 pm    Post subject: Reply with quote

There is a quirk in the X64 instruction set that FTN95-64 does not account for. The 16-bit logical variable is loaded from the base of the common block into register RBX with the instructions

MOV_Q R15,Address of /COMIW2/ Block 0
MOV_H RBX,[R15]

The mnemonic used by Silverfrost tends to obscure the reality that only the 16-bit portion, i.e., BX, is being loaded, and in the X64 architecture, see https://msdn.microsoft.com/en-us/library/windows/hardware/ff561499(v=vs.85).aspx,
Quote:
Operations that output to a 32-bit subregister are automatically zero-extended to the entire 64-bit register. Operations that output to 8-bit or 16-bit subregisters are not zero-extended

Thus, the (unnamed) upper 16 bits of EBX contain junk, which will cause the subsequent comparison of EBX to malfunction.

The fix is to have the compiler emit a MOVZX instruction instead of a MOVH instruction.

This property also applies to 32-bit code, but FTN95 correctly generates a MOVZX ECX instruction in that mode.

On the user's side, it is best to avoid 8-bit and 16-bit variables in 64-bit programs, i.e., use LOGICAL instead of LOGICAL*2, etc.


Last edited by mecej4 on Wed Mar 15, 2017 3:08 pm; edited 4 times in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4814
Location: Salford, UK

PostPosted: Wed Mar 15, 2017 2:36 pm    Post subject: Reply with quote

Thank you for this report. I have logged it as a bug that needs to be fixed.

I assume that default LOGICAL (rather than LOGICAL*2) works OK.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4814
Location: Salford, UK

PostPosted: Wed Mar 15, 2017 5:33 pm    Post subject: Reply with quote

This bug in 64 bit FTN95 has been fixed for the next release.
The problem with SDBG64 has been noted.
Back to top
View user's profile Send private message
DietmarSiepmann



Joined: 03 Jun 2013
Posts: 91

PostPosted: Wed Mar 15, 2017 6:19 pm    Post subject: Reply with quote

Paul,

yes, the code generation works and produces the correct output, if I change LOGICAL*2 to LOGICAL. However, the debugger (sdbg64) still does not show the correct dots.

Code:

      LOGICAL LOGLLT,LOGHSP
      COMMON /COMIW2/ LOGLLT
     
      LOGLLT=.FALSE.
      LOGHSP=.FALSE.

      write(*,*) 'LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      IF(LOGLLT .OR. LOGHSP) THEN
       write(*,*) 'In if: LOGLLT=',LOGLLT,', LOGHSP=',LOGHSP
      ENDIF
      END


Lines 1,5,7,9,10,11 of the code begin with a dot in the debugger session, lines 2,3,4,6,8 do not! This is very confusing to me because I do not know if the if clause is active or not in a debuger session. I know I can check this out by using the cmd tool and assinging value .TRUE. to e.g. LOGLLT via the let statement within the debugger.

Oops, I have seen, the ftn95 problem will have been solved in the next release. Thanks.

mecej4,

thanks for the information. For the time being I would try using LOGICAL instead of LOGICAL*2. But we are highly interested to create 64 bit executables because we would like to make use of the bigger address space (in comparison to the 32 bit version of the same code). If I mapped LOGICAL*2 to LOGICAL , wouldn't I reduce the space for other data to be loaded unneccessarily? I should say that we make the effort of porting one of our 32 executables to 64 bit, because we would like to load as much dtat to memory as possible.

Regards,
Dietmar

Regards,
Dietmar
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 673

PostPosted: Wed Mar 15, 2017 7:16 pm    Post subject: Re: Reply with quote

DietmarSiepmann wrote:
If I mapped LOGICAL*2 to LOGICAL , wouldn't I reduce the space for other data to be loaded unneccessarily? ... because we would like to load as much data to memory as possible.

Yes. However, you want your 64-bit program to run as fast as possible with bigger data sets, no? And that is where you have to make a compromise.

In theory, you could make logical variables occupy just one bit -- a LOGICAL*1/8, so to speak. Since X64 uses 32- and 64-bit registers in most instructions, with smaller data sizes you would have to extend the input bit/byte/half-word into a register, do processing, and update memory with the contents of a small part of a register. All this sizing up/down, if done many times, can slow down your program considerably.

Perhaps, you could run some tests to help yourself to decide whether to use default LOGICAL or LOGICAL*2.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> 64-bit All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group