|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Mon Apr 10, 2017 8:08 pm Post subject: Incorrect results with /opt |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Tue Apr 11, 2017 6:59 am Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue Apr 11, 2017 9:29 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Tue Apr 11, 2017 10:00 am Post subject: |
|
|
Many thanks.
Paul |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Tue Apr 11, 2017 11:30 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Tue Apr 11, 2017 1:09 pm Post subject: |
|
|
mecej4
Your analysis is very helpful and much appreciated. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Wed Apr 26, 2017 9:13 am Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Sat Apr 29, 2017 1:26 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Sat Apr 29, 2017 7:19 am Post subject: |
|
|
Thanks. Can you explain what "argument aliasing" is may with an example. |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Thu Dec 13, 2018 6:08 pm Post subject: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Thu Dec 13, 2018 7:34 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Fri Dec 14, 2018 12:28 am Post subject: |
|
|
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 |
|
|
|
|
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
|