[comp.sys.apollo] Casting bug in C compiler 68K Rev 6.7

peterf@arp.anu.oz.au (Peter Fletcher) (07/17/90)

There's a frustrating little bug in the Apollo 'c' compiler
which has been there since at least before Rev 6.6.  The
following program should always output '65535', but if
compiled with no optimization, it gets the answer wrong.

>hera$ rm cbug ; make CC=/bin/cc cbug
>/bin/cc     cbug.c   -o cbug
>hera$ cbug
>65280
>hera$ rm cbug ; make CC=/bin/cc CFLAGS=-O cbug
>/bin/cc -O    cbug.c   -o cbug
>hera$ cbug
>65535
>hera$ cat cbug.c
>main()
>
>{
>    unsigned short a;
>    int off;
>    float scale;
>    unsigned short result;
>
>    a = 0;
>    off = -1;
>    scale = 1.0;
>
>    result = ((unsigned short)(((a)+off)*scale));
>
>    printf("%1u\n",result);
>}
>hera$ /com/cc -version
>C compiler 68K Rev 6.7(316)

peter fletcher

rehrauer@apollo.HP.COM (Steve Rehrauer) (07/17/90)

In article <1990Jul17.044917.20375@arp.anu.oz.au> peterf@arp.anu.oz.au (Peter Fletcher) writes:
>There's a frustrating little bug in the Apollo 'c' compiler
>which has been there since at least before Rev 6.6.  The
>following program should always output '65535', but if
>compiled with no optimization, it gets the answer wrong.

This has been fixed in CR1.0 (cc 6.8).

--
   >>"Aaiiyeeee!  Death from above!"<<     | (Steve) rehrauer@apollo.hp.com
"Spontaneous human combustion - what luck!"| Apollo Computer (Hewlett-Packard)

buchs@MAYO.EDU (Kevin J. Buchs) (07/17/90)

Peter Fletcher reports:

> There's a frustrating little bug in the Apollo 'c' compiler
> which has been there since at least before Rev 6.6.  The
> following program should always output '65535', but if
> compiled with no optimization, it gets the answer wrong.

I took his program and compiled it with the 'Aegis' C Compiler, which I
always thought was the same as the Unix compiler, with a different front
end.  Here are the results, note the difference in binary size and in
which one fails to execute properly:

--------------------------

xwing[296] sh -x script
+ cat cbug.c
main()

{
    unsigned short a;
    int off;
    float scale;
    unsigned short result;

    a = 0;
    off = -1;
    scale = 1.0;

    result = ((unsigned short)(((a)+off)*scale));

    printf("%1u\n",result);
}
+ /bin/cc cbug.c -o cbug1
+ /bin/cc -O cbug.c -o cbug2
+ /com/cc cbug.c
No errors, no warnings, 2 info msgs, C compiler 68K Rev 6.6(28)
+ bind cbug.bin -b cbug3
All Globals are resolved.
+ /com/cc cbug.c -opt 4
No errors, no warnings, 2 info msgs, C compiler 68K Rev 6.6(28)
+ bind cbug.bin -b cbug4
All Globals are resolved.
+ /com/cc cbug.c -dba
No errors, no warnings, 2 info msgs, C compiler 68K Rev 6.6(28)
+ bind cbug.bin -b cbug5
All Globals are resolved.
+ /com/cc cbug.c -ndb
No errors, no warnings, 2 info msgs, C compiler 68K Rev 6.6(28)
+ bind cbug.bin -b cbug6
All Globals are resolved.
+ ls -l cbug1 cbug2 cbug3 cbug4 cbug5 cbug6
-rwxr-xr-x   1 buchs        2890 Jul 17 11:44 cbug1
-rwxr-xr-x   1 buchs        2782 Jul 17 11:44 cbug2
-rwxr-xr-x   1 buchs        1497 Jul 17 11:44 cbug3
-rwxr-xr-x   1 buchs        1497 Jul 17 11:45 cbug4
-rwxr-xr-x   1 buchs        2297 Jul 17 11:45 cbug5
-rwxr-xr-x   1 buchs        1029 Jul 17 11:45 cbug6
+ cbug1
65280
+ cbug2
65535
+ cbug3
65535
+ cbug4
65535
+ cbug5
65280
+ cbug6
65535

--------------------------

So, apparently, the Aegis C compiler is MUCH more efficient in space.
Should we switch back to Aegis?   Why is this?

I also compared the assembly code between cbug3, the plain Aegis
compile, and cbug5, the -dba Aegis compile which fails to execute
correctly.  Looks like the problem is in the floating point
instructions, which I know nothing about.

cbug3:
-------------------------

 (0032)     off = -1;
 (0033)     scale = 1.0;
 (0034)
 (0035)     result = ((unsigned short)(((a)+off)*scale));
 (0036)
 (0037)     printf("%1u\n",result);
     0010:2F3C0000FFFF                 MOVE.L    #65535,-(SP)
     0016:4855                         PEA       <string-constant>(DB)
     0018:4EB900000000                 JSR       <transfer vector> printf
--------------------------


cbug5:
-------------------------

     0016:3D7C0000FFFA                 MOVE.W    #0,a(SB)
 (0032)     off = -1;
     001C:70FF                         MOVEQ.L   #-1,D0
     001E:2D40FFF4                     MOVE.L    D0,off(SB)
 (0033)     scale = 1.0;
     0022:2D7C3F800000FFF0             MOVE.L    #  1.000000   ,scale(SB)
 (0034)
 (0035)     result = ((unsigned short)(((a)+off)*scale));
     002A:7000                         MOVEQ.L   #0,D0
     002C:302EFFFA                     MOVE.W    a(SB),D0
     0030:D0AEFFF4                     ADD.L     off(SB),D0
     0034:2F2EFFF0                     MOVE.L    scale(SB),-(SP)
     0038:2F00                         MOVE.L    D0,-(SP)
     003A:4EB900000000                 JSR       <transfer vector> fpp_$
     0040:01D4                         SLUV
     0042:0024                         FSMV
     0044:0258                         SUTLX
     0046:3D40FFEE                     MOVE.W    D0,result(SB)
 (0036)
 (0037)     printf("%1u\n",result);
     004A:7000                         MOVEQ.L   #0,D0
     004C:302EFFEE                     MOVE.W    result(SB),D0
     0050:2F00                         MOVE.L    D0,-(SP)
     0052:4855                         PEA       <string-constant>(DB)
     0054:4EB900000000                 JSR       <transfer vector> printf
  
--------------------------

-------------------------------------------------------------
Kevin Buchs          Internet: buchs@mayo.edu
Mayo Foundation              Is this my life or is it just an
Rochester, MN 55905          incredible, high-speed, simulation?
(507) 284-0009                         -S. R. Cleaves
-------------------------------------------------------------

rehrauer@apollo.HP.COM (Steve Rehrauer) (07/18/90)

In article <9007171631.AA11696@fermat.Mayo.edu> buchs@MAYO.EDU (Kevin J. Buchs) writes:
>I also compared the assembly code between cbug3, the plain Aegis
>compile, and cbug5, the -dba Aegis compile which fails to execute
>correctly.  Looks like the problem is in the floating point
>instructions, which I know nothing about.

-dba turns off nearly all optimizations, so it's equivalent to
saying -O to /bin/cc.  (-dba turns off even more than -opt 0 does,
if you're curious.  Think of it as "-opt -1" :-)

As I said earlier, this bug has been fixed in CR1.0 (cc 6.8).
I've received some mail asking about this compiler, and thought
perhaps I should answer the questions here.

Yes, CR1.0 is in Beta test now.

No, you won't get CR1.0 with SR10.3.  We've decoupled our OS and
languages releases.  I don't know exactly what the procedure is
these days for getting the new compilers.  Ask your friendly
neighborhood HaPollo rep; they get lonely without frequent
attention...

--
   >>"Aaiiyeeee!  Death from above!"<<     | (Steve) rehrauer@apollo.hp.com
"Spontaneous human combustion - what luck!"| Apollo Computer (Hewlett-Packard)

rehrauer@apollo.HP.COM (Steve Rehrauer) (07/19/90)

In article <4baa2cb3.20b6d@apollo.HP.COM> rehrauer@apollo.HP.COM (Steve Rehrauer) writes:
>-dba turns off nearly all optimizations, so it's equivalent to
>saying -O to /bin/cc.

*sigh*  Talking on auto-pilot again, eh Steve?  That should read,
"equivalent to _not_ saying -O to /bin/cc".  Sorry.  (You all knew
what I meant, right?  Is it Friday yet? :-)

--
   >>"Aaiiyeeee!  Death from above!"<<     | (Steve) rehrauer@apollo.hp.com
"Spontaneous human combustion - what luck!"| Apollo Computer (Hewlett-Packard)