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 

Faulty code generated with /opt /64

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



Joined: 31 Oct 2006
Posts: 1004

PostPosted: Mon Oct 29, 2018 3:49 am    Post subject: Faulty code generated with /opt /64 Reply with quote

The expected output of this short program:
Code:
program bugchk
   implicit none
   integer, parameter :: N = 5
   integer :: i,m,m1
   integer :: ia(N+1), wn(N)

   ia   = (/ 1,  11,  21,  31,  41,  51 /)
!
   m1 = ia(1)
   do i = 1 , n
      m = m1
      m1 = ia(i+1)
      wn(i) = m1 - m        ! BAD CODE GENERATED FOR THIS
   end do
   print '(1x,A,5i4)','WN : ',wn

end program

is
Code:
 WN :   10  10  10  10  10

Compiling and running the program with FTN95 8.30.279 produces the correct output except when the /opt and /64 options are both specified, in which case the output is
Code:
 WN :    0   0   0   0   0

Examination of the /exp listing shows how the bug occurs (please see comments added to the relevant lines of the listing):
Code:
   0011         m = m1                                                                           AT 67
   0012         m1 = ia(i+1)                                                                     AT 67
   0013         wn(i) = m1 - m        ! BAD CODE GENERATED FOR THIS                              AT 67
   0014      end do                                                                              AT 67
   0015      print '(1x,A,5i4)','WN : ',wn                                                       AT 67
   0016                                                                                          AT 67
   0017   end program                                                                            AT 67
00000067(#1,51,17):      Loading variables and other into registers prior to loop
00000067(#1,52,17):      MOVSX_Q   R8,I
0000006c(#1,53,17):      MOVSX_Q   RDI,M
00000071(#1,54,17):      MOVSX_Q   RSI,M1
00000076(#43,14,10):      ALIGN16
00000080(#43,15,10):      N_3:
00000080(#50,16,11):      Removed instruction
00000080(#50,17,11):      MOV_Q     RDI,RSI         # m = m1
00000083(#110,18,12):      Removed instruction
00000083(#56,19,12):      MOVSX_Q   R14,IA[4*R8]    # IA(I+1)
00000088(#56,20,12):      MOV_Q     RSI,R14         # m1 = IA(I+1)
0000008b(#117,21,13):      SUB_Q     R14,RSI        # BUG HERE, should have been SUB_Q   R14, RDI
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Mon Oct 29, 2018 7:58 am    Post subject: Reply with quote

Thank you for this report. I have logged it as needing attention.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Thu Nov 08, 2018 12:03 pm    Post subject: Reply with quote

I have had a look at this program and the coding has indeed fooled the FTN95 Fortran loop optimiser. The optimisation is number 1 so a work-around is to use /opt with /inhibit_opt 1.

It turns out that in this case the programmer's optimising strategy makes the program run more slowly. It is in fact faster to simply write wn(i) = ia(i+1)-ia(i) (comparing the runtimes for the two approaches both without /opt).

I don't know how much work would be involved in making the optimiser cleverer in this context. The danger is that we end up suppressing optimisations that are valid.
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 1854
Location: Yateley, Hants, UK

PostPosted: Thu Nov 08, 2018 12:37 pm    Post subject: Reply with quote

Paul,

Surely the point is that an optimisation should produce (a) a change in execution speed, and at worst (b) changed roundoff, not wrong code. Those who use optimisation features in a compiler should know that sometimes, the changed execution speed is for the worse with particular constructs.

The example I am most familiar with is the removal of common subexpressions. If the compiler does that procedure relatively diligently, the programmer can still fool it, if, for example, a**2 + b**2 appears in one place, but b**2 + a**2 in another. In any case, setting c = a**2 + b**2 and using c instead may be better or worse, depending on how far ahead the optimiser can look, and whether or not it replaces exponentiation with repeated multiplication, for example, if c = a*a + b*b, or how registers are allocated. Just a guess, but probably not using the 8087 stack makes the third of these more difficult.

Those of us whose experience began long before optimisation via the compiler was a realistic possibility are often diligent in removing common subexpressions, particularly those with expensive functions. Whether or not it leads to adverse changes in execution time is far less important than the risk of producing wrong answers.

Eddie
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Thu Nov 08, 2018 2:08 pm    Post subject: Reply with quote

Eddie

Yes one would naturally aim for correct code and this seems relatively straight forward for most things with common subexpressions as a particular example.

The situation for "Fortran loops" is much more tricky and I am beginning to think that we need to make /opt "safe" by removing things like "Fortran loop" optimisation whilst making them available (in some other way) as a separate "unsafe" option. For example we could have /opt (as the "safe" option) and /optx with everything included (together with a health warning).
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sat Nov 10, 2018 10:58 am    Post subject: Reply with quote

Correction:

The temporary "fix" is to use /inhibit_opt 40.

It turns out that number 1 cuts out a whole raft of optimisations.
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1004

PostPosted: Sat Nov 10, 2018 1:51 pm    Post subject: Re: Reply with quote

PaulLaidler wrote:
Correction:

The temporary "fix" is to use /inhibit_opt 40.

It turns out that number 1 cuts out a whole raft of optimisations.

Thanks, Paul, that works!

Is the number specified after /inhibit_opt an ordinal number, or is it a bit-mask obtained by OR-ing individual bits that represent individual optimisations?

In either case, it would help to have a list of the meanings (of all or at least an important subset of) the various optimisation numbers/flags.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sat Nov 10, 2018 2:32 pm    Post subject: Reply with quote

It is an ordinal number.

I am trying to get hold of a list.
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1004

PostPosted: Sat Nov 10, 2018 3:08 pm    Post subject: Reply with quote

Thank you!
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