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 

Incorrect results with /opt

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



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Mon Apr 10, 2017 8:08 pm    Post subject: Incorrect results with /opt Reply with quote

The Fortran package ENLSIP solves nonlinear least squares problems with constraints ( http://plato.asu.edu/ftp/other_software/ENLSIP.tar.gz ). It has about 8000 lines of code, and contained (until it was corrected yesterday) two calls to a subroutine, one of which involved aliasing. The subroutine heading is
Code:
SUBROUTINE ADDIT(OA,OI,T,Q,K)
where OA and OI are integer arrays, T, Q and K are scalar integers. The subroutine modifies OA, OI, T and Q, but not K. The call in question read
Code:
CALL ADDIT(OA,OI,T,Q,Q)
One way of removing the aliasing is to replace this line by
Code:
CALL ADDIT(OA,OI,T,Q,(Q))
Placing the last argument within parentheses creates an anonymous variable whose value is set to the value of the expression within the parentheses, and passes that anonymous variable as the actual fifth argument to the subroutine. With FTN95 (32 or 64-bit), this artifice does not work when /opt is used.

Here is a test program:
Code:
      PROGRAM ALIASBUG
      INTEGER :: T = 2, Q = 5
      INTEGER :: OA(3) = (/ 1,2,0 /)
      INTEGER :: OI(6) = (/ 3,4,5,7,1,0 /)
      !
      CALL ADDIT(OA,OI,T,Q,(Q))  ! <<== WAS CALL ADDIT(OA,OI,T,Q,Q)
      PRINT *,'AFTER ADDIT, T,Q = ',T,Q

      CONTAINS
      SUBROUTINE ADDIT(OA,OI,T,Q,K)
      INTEGER T,Q,K,OA(T+1),OI(Q+1)
C
C     ADD A CONSTRAINT TO THE ACTIVE SET
C
      INTEGER I
      T = T + 1
      OA(T) = OI(K)
      DO I = K, Q
         OI(I) = OI(I+1)
      END DO
      Q = Q - 1
      RETURN
      END SUBROUTINE ADDIT
      END PROGRAM

FTN95 with /opt gives the output
Code:
 After Addit, T,Q =            3           5

rather than the correct result
Code:
 After Addit, T,Q =            3           4
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Apr 11, 2017 6:59 am    Post subject: Reply with quote

Thank you for the feedback.

Is the package provided as a DLL or have you compiled it using FTN95?
I am guessing that the /opt only relates to the program that you have posted.
Presumably it is 32 bits.

I have made a note of this issue.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Tue Apr 11, 2017 9:29 am    Post subject: Reply with quote

The ENLSIP package is provided in source form, and includes a main program (driver) for a test problem (Hock-Schittkowski #65). I compiled it into an EXE using FTN95. The program gave correct output without /opt, but aborted with an access violation when I used /opt. After investigating and locating the problem, I pared the code down to obtain the reproducer that I posted above.

The /opt bug occurs with the ENLSIP test program as well as with the reproducer, using FTN95 8.1 32-bit on Windows 10. The bug disappears if I specify INTENT(IN) for the fifth subroutine argument, K.


Last edited by mecej4 on Tue Apr 11, 2017 10:23 am; edited 2 times in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Apr 11, 2017 10:00 am    Post subject: Reply with quote

Many thanks.

Paul
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Tue Apr 11, 2017 11:30 am    Post subject: Reply with quote

Paul, this is a rather tricky bug, and I appreciate your patience.

It turns out that the current compiler generates incorrect code, with or without /opt, with or without /64, for actual arguments that are expressions consisting of a variable name surrounded by parentheses. By coincidence, there are harmful effects only with /opt in 32-bit mode because of the way in which the compiler makes local copies of subroutine arguments, works with the local copies in the body of the subroutine, and updates the arguments just before returning from the subroutine, to reflect the changes to the local copies. These are the reasons why this compiler bug is elusive. The bug has probably gone unnoticed because it is rare that we use the source code pattern (<variable>) as an actual argument.

Consider the code generated by the compiler for the line
Code:
CALL ADDIT(OA,OI,T,Q,(Q))

In 32-bit mode, the assembly code is
Code:
   0006         CALL ADDIT(OA,OI,T,Q,(Q))                  AT 20
      00000020(16/3/95)          push      ebx ; For eight-byte alignment
      00000021(17/4/94)          lea       eax,Q
      00000027(18/3/95)          push      eax
      00000028(19/4/93)          lea       ecx,Q
      0000002e(20/3/95)          push      ecx
      0000002f(21/4/92)          lea       edi,T
      00000035(22/3/95)          push      edi
...etc...

Please note that the address of Q is pushed twice. In effect, the compiler is disregarding the parentheses around the second Q in the CALL.

Similarly, in 64-bit mode,
Code:
00000021(#104,6):      LEA       R15,Q
00000028(#103,7):      LEA       R9,Q
0000002f(#102,8):      LEA       R8,T
00000036(#101,9):      LEA       RDX,OI
0000003d(#100,10):      LEA       RCX,OA
00000044(#105,11):      MOV_Q     [RSP+32],R15
00000049(#105,12):      CALL      ALIASBUG~ADDIT

Note for readers unfamiliar with the Windows 64-bit ABI: The first four integer arguments are passed in registers RCX, RDX, R8, R9. Subsequent arguments are passed on the stack. In the present case, the fifth argument, (Q), i.e., a copy of Q, should have been passed on the stack. The compiler is passing Q itself, instead.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Apr 11, 2017 1:09 pm    Post subject: Reply with quote

mecej4

Your analysis is very helpful and much appreciated.
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


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

PostPosted: Wed Apr 26, 2017 9:13 am    Post subject: Reply with quote

The incorrect behaviour for an argument of the form (Q) has now been fixed for the next release except for the case where Q is a complex value and /64 is used. This case remains outstanding.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Sat Apr 29, 2017 1:26 am    Post subject: Reply with quote

Paul, thanks for the expeditious resolution of the problem.

Although this thread is about a bug in the compiler, it is worthwhile to note the important role played by a compiler with excellent error-hunting capabilities such as FTN95 in isolating and fixing errors in widely used software.

More significantly, FTN95 already includes many facilities that may be used to diagnose bugs in the compiler itself.

Please consider, as a long-term goal, adding a compiler option to check for and report instances of argument aliasing in user code. As far as I am aware, no current and widely used compiler provides such a facility.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Sat Apr 29, 2017 7:19 am    Post subject: Reply with quote

Thanks. Can you explain what "argument aliasing" is may with an example.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Sat Apr 29, 2017 1:35 pm    Post subject: Reply with quote

Great! I have started a new thread with a "request for feature" in a new thread:

http://forums.silverfrost.com/viewtopic.php?p=21819#21819

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


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

PostPosted: Thu Dec 13, 2018 6:08 pm    Post subject: Reply with quote

mecej4

I have revisited the issue that was reported as "outstanding" above and have not been able to find a fault. I am assuming that this particular issue is now completely fixed.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1884

PostPosted: Thu Dec 13, 2018 7:34 pm    Post subject: Reply with quote

Paul,

Thanks for asking. The example code that I presented involved only integer variables, and one of those variables is used as the upper limit of a DO index.

When I read your response of 26 April 2017 that the only case outstanding was the one where an actual argument was a complex variable surrounded by parentheses, I was slightly puzzled. There are several such example codes that could be constructed, and I did not know which one you had used.

I put together a new example, and tried 8.30.279 on it. The 32-bit EXEs from it give the correct result, but the 64-bit EXEs do not.
Code:
program aliasbug
   complex :: p = (1.0,2.0)
!
   call addit(p,(p))  ! <<== (p) used to prevent aliasing
   print *,'after addit, p = ',p

contains
   subroutine addit(p,q)
      complex :: p,q
      p=p+q
      return
   end subroutine addit
end program
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Fri Dec 14, 2018 12:28 am    Post subject: Reply with quote

mecej4

Many thanks for your help with this.

The complex example that you have posted above did not work with v8.40 but has now been fixed for the next release.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support 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