IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

How I Found a Bug in a FORTRAN Compiler


IBM Mainframe Forums -> All Other Mainframe Topics
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
Phrzby Phil

Senior Member


Joined: 31 Oct 2006
Posts: 1042
Location: Richmond, Virginia

PostPosted: Thu Feb 22, 2024 6:26 pm
Reply with quote

Here's a story that may be of interest about how, when I was a college student back in 1969, I identified an assembler code generation error in an IBM FORTRAN compiler, also identifying what the compiler programmer overlooked in designing the generated code.

During the summer of 1969, between undergraduate and graduate school, I had a summer programming job at IBM in Poughkeepsie, NY. My major project was to write a FORTRAN program to clean up FORTRAN programs, including re-sequencing statement numbers.

Back in those days, FORTRAN did not have character string variables or even character variable types, so one typically used INTEGER (fullword) or INTEGER*2 (halfword), where in either case one byte stored the character and the remaining byte(s) were blank.

The FORTRAN H (optimizing) compiler, however, had an unpublished variable type, LOGICAL*1, using one byte, so I stored data lines in LOGICAL*1 arrays.

Optimizing compilers want to work with variables in registers when possible, so there is extra code generated to load values into registers.

For INTEGER and INTEGER*2 variables, the register load commands are, respectively, L (Load) and LH (Load Halfword). Important here: for LH, the left half of the register is replaced by zeros or ones to reflect the sign (leftmost bit) of the halfword.

However, and this is what tripped up the compiler programmer, for a LOGICAL*1 variable, the load must be accomplished by two commands:
1) SR (subtract register, subtracting it from itself) to zero the register
2) IC (insert character into rightmost byte)
The two commands are needed because IC leaves the register's leftmost three bytes unchanged.

To analyze a line of code in an array, the program loops down the array row loading the IC's index register with the DO loop variable's value. Due to the small number of available registers, the compiler may need to load each iteration's character into the register that is also the IC's index register (and then later reset the index register before the next iteration).

For INTEGER and INTEGER*2 - no problem. But for LOGICAL*1, needing two commands to load the character into the register, the SR command zeroes what is still the IC's index register, so each iteration's IC's index register value ends up being zero, and therefore (here's the bug) each loop always looks at just the first character (due to zero-based indexing) in the array.
Back to top
View user's profile Send private message
sergeyken

Senior Member


Joined: 29 Apr 2008
Posts: 2023
Location: USA

PostPosted: Thu Feb 22, 2024 8:09 pm
Reply with quote

Phrzby Phil wrote:
Due to the small number of available registers, the compiler may need to load each iteration's character into the register that is also the IC's index register (and then later reset the index register before the next iteration).

Very strange...
The compiler version which mixes up the index register with the data register inside the same loop cannot pass any QA before being released to public use.

Please: any example of the source FORTRAN code part, and corresponding Assembler compilation result?
Back to top
View user's profile Send private message
Phrzby Phil

Senior Member


Joined: 31 Oct 2006
Posts: 1042
Location: Richmond, Virginia

PostPosted: Thu Feb 22, 2024 8:18 pm
Reply with quote

Quote:
Very strange...
The compiler version which messes up the index register with the data register inside the same loop cannot pass any QA before being released to public use.


The LOGICAL*1 WAS an unpublished "feature." Maybe this compiler was never released outside of IBM. Maybe I was given access to a beta version.

And, as I noted, it was OK to reuse the register for full- and half-words because in those cases only one instruction was needed to load the register, not the SR first instruction of the pair in this case.

A most interesting error indeed.

Sorry - never kept copies of source or generated code.

Nonetheless, as a student summer programmer, I was pretty proud of myself for identifying the issue. Even happier that I can remember the details today!
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1306
Location: Vilnius, Lithuania

PostPosted: Thu Feb 22, 2024 11:57 pm
Reply with quote

Sometime in 2007 I found a bug in V3.5 of the Enterprise PL/I compiler. This one was a little bit more obvious than the bug you found, as the compiler would actually fall over with an U-type error, I don't remember which one.

As for the code? I was initialising a field in a based structure with another value to the power of two, i.e. simplified

Code:
dcl 1 struct based(ptr),
      2 field fixed (15) init ((anotherfield**2));

and the compiler choked on it!

The work-around was of course simple, use
Code:
init((anotherfield*anotherfield))

In later versions of Enterprise PL/I the bug was obviously removed. Funny thing was of course that this was not in a company program, but in one of my private programs, that I ran occasionally, so I had to jump through some hoops to pass the problem to IBM.
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Tue Feb 27, 2024 3:08 am
Reply with quote

One time, I found a bug in the current IBM C compiler. And I was an IBMer at the time, so I complained directly to the developers of the compiler. They denied it and told me multiple times that it was working correctly. I asked for a working example, and they would not provide it. Damn them!

Then I retired from IBM and worked briefly for another company. I opened a PMR with the same description. Rejected! But sometime later, I found out from a third party that they first thought a second person was reporting the problem: a non-IBMer. They momentarily started planning a fix until they realized that I was the original complainer. When they realized it was the same person, they rejected the PMR.

----
The problem might be fixed now: the compiler invocation command for C allows to specify a directory that contains the INCLUDE files, but I could never get it to work. The compiler always complained about missing include files. This was from OMVS.

To ever get a compile to work, I had to copy the text directly into the program, rather than to include from another file.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> All Other Mainframe Topics

 


Similar Topics
Topic Forum Replies
No new posts A directory in the pathname was not f... ABENDS & Debugging 0
No new posts I need a 4 lines block where substrin... DFSORT/ICETOOL 12
No new posts Compiler and run JCL for basic PL/I p... PL/I & Assembler 10
No new posts Routine not found... CLIST & REXX 6
No new posts Panel not found on PF3 with libdef of... TSO/ISPF 2
Search our Forums:

Back to Top