[comp.sys.ibm.pc] Microsoft C 6.0 BAD code generation

mshiels@tmsoft.uucp (Michael A. Shiels) (06/13/90)

One of my co workers was trying to start using Microsoft C 6.0 but found out
that it's just like Microsfot C 5.1.  You have to disable most of the
optimizations so it will generate correct code.  Here's his very simple sample
code which doesn't have anything to do with loops but is broken when you specify
loop optimizations.

 
/**************************************************************************/
/* cl -c -Gs -Zl -FPc -Oswrl -Awfl -W4 -Fa c6badeg.c                          */
/*                                                                          */
/* NOTE:  THIS WORKS IF THE '-O...l' IS NOT INCLUDED!                     */
/*          I PERSONALLY DON'T KNOW WHAT LOOP OPTIMIZATION HAS TO DO WITH   */
/*          THIS CODE.                                                          */
/*          '-Oswer' DOESN'T WORK EITHER!!                                  */
/**************************************************************************/
 
struct graphd {
    double  mins[2];
    double  maxs[2];
};
 
extern        struct        graphd *CurrentGraph;
 
 
void        check_range(
double *val,
int        range)
{
    if (*val > CurrentGraph->maxs[range])
        CurrentGraph->maxs[range] = *val;
    if (*val < CurrentGraph->mins[range])
        CurrentGraph->mins[range] = *val;
}
 
/**************************************************************************/
/*
;        Static Name Aliases
;
        TITLE        c6badeg.c
        .8087
C6BADEG_TEXT   SEGMENT        WORD PUBLIC 'CODE'
C6BADEG_TEXT   ENDS
_DATA        SEGMENT  WORD PUBLIC 'DATA'
_DATA        ENDS
CONST        SEGMENT  WORD PUBLIC 'CONST'
CONST        ENDS
_BSS        SEGMENT  WORD PUBLIC 'BSS'
_BSS        ENDS
DGROUP        GROUP        CONST, _BSS, _DATA
        ASSUME DS: DGROUP
        ASSUME        SS: NOTHING
EXTRN        __aFeldd:FAR
EXTRN        __aFfcompp:FAR
EXTRN        _CurrentGraph:DWORD
EXTRN        __fltused:NEAR
C6BADEG_TEXT          SEGMENT
        ASSUME        CS: C6BADEG_TEXT
; Line 1
; Line 14
C6BADEG_TEXT          ENDS
CONST           SEGMENT
$T20001 DW SEG _CurrentGraph
CONST           ENDS
C6BADEG_TEXT          SEGMENT
        ASSUME        CS: C6BADEG_TEXT
        PUBLIC        _check_range
_check_range        PROC FAR
        push        bp
        mov        bp,sp
        push        di
        push        si
;        val = 6
;        range = 10
; Line 15
        les        bx,DWORD PTR [bp+6]        ;val
        call        FAR PTR __aFeldd
        mov        es,WORD PTR $T20001
        les        bx,DWORD PTR es:_CurrentGraph
        add        bx,16
        mov        cl,3
        mov        si,WORD PTR [bp+10]        ;range
        shl        si,cl
        lea        bx,WORD PTR [bx][si]
        call        FAR PTR __aFeldd
        call        FAR PTR __aFfcompp
        jae        $I106
; Line 16
        mov        cl,3
        mov        bx,WORD PTR [bp+10]        ;range
        shl        bx,cl
        mov        es,WORD PTR $T20001
        les        si,DWORD PTR es:_CurrentGraph
        mov        ax,WORD PTR [bp+6]        ;val
        mov        dx,WORD PTR [bp+8]
        push        ds
        lea        di,WORD PTR [bx+16][si]
        mov        si,ax
        mov        ds,dx
        ASSUME DS: NOTHING
        movsw
        movsw
        movsw
        movsw
        pop        ds
        ASSUME DS: DGROUP
; Line 17
$I106:
        les        bx,DWORD PTR [bp+6]        ;val
        call        FAR PTR __aFeldd
        mov        es,WORD PTR $T20001
        les        bx,DWORD PTR es:_CurrentGraph
        mov        cl,3
        mov        si,WORD PTR [bp+10]        ;range
        shl        si,cl
        lea        bx,WORD PTR [bx][si]
        call        FAR PTR __aFeldd
        call        FAR PTR __aFfcompp
        jbe        $EX105
; Line 18
        mov        es,WORD PTR $T20001
        les        bx,DWORD PTR es:_CurrentGraph
        mov        si,WORD PTR [bp+6]        ;val
        mov        dx,WORD PTR [bp+8]
        push        ds
        lea        di,WORD PTR [bx][si]
        mov        ds,dx
        ASSUME DS: NOTHING
        movsw
        movsw
        movsw
        movsw
        pop        ds
        ASSUME DS: DGROUP
; Line 19
$EX105:
        pop        si
        pop        di
        mov        sp,bp
        pop        bp
        ret
 
_check_range        ENDP
C6BADEG_TEXT   ENDS
END
*/

west@turing.toronto.edu (Tom West) (06/14/90)

In article <j7c6203r7@tmsoft.uucp> mshiels@tmsoft.UUCP (Michael A. Shiels) writes:
>One of my co workers was trying to start using Microsoft C 6.0 but found out
>that it's just like Microsfot C 5.1.  You have to disable most of the
>optimizations so it will generate correct code.  Here's his very simple sample
>code which doesn't have anything to do with loops but is broken when you 
>specify loop optimizations.

  Unfortunately, I can confirm this.  I have a bug into MS at the moment where
MSC 6.0 will produce code that eventually crashes the machine.  The specifics 
in this case are that if you eliminate the -Oe, it works, or if you 
eliminate the register declaration(!!) in the register long y line, it 
works!  Strange behaviour for an option that supposedly ignores the
register keyword when turned on.  (Specifically, MSC 6.0 doesn't generate
enough FP stack pops and eventually overflows the FP stack).  This bug is
into MS along with another two, but this is the only one that generates bad
code.  This is scary!.  My project is 300k long so I *can't* exhaustively test
it for code generation bugs!  What am I to do?   Unfortunately, I trusted new
technology too much and put in features found only in 6.0.  Now it looks like 
I'll pay for it.
  On the other hand, the poor tech support contact at MS is trying to do his 
best.  It's just there isn't a hell of a lot he can do on circumstances like
this.

---------------------------
cl -Oe main.c
---------------------------
#include <stdio.h>

void TL1 ();

_cdecl main()
{
    for (;;)
    {
	long right = 2;
	double product = 1.0;
	if (right < 0)
	{
	    long x;
	    for (x = right; x <= -1; x++) product /= (double) 3.0;
	}
	else
	{
	    register long y;
	    for (y = right; y >= 1; y--) product *= (double) 3.0;
	};
	TL1 (product);
	printf("%lf\n", product);
    }
}

void TL1 (value)
double  value;
{
}
---------------------------

cramer@optilink.UUCP (Clayton Cramer) (06/15/90)

In article <j7c6203r7@tmsoft.uucp>, mshiels@tmsoft.uucp (Michael A. Shiels) writes:
> One of my co workers was trying to start using Microsoft C 6.0 but found out
> that it's just like Microsfot C 5.1.  You have to disable most of the
> optimizations so it will generate correct code.  Here's his very simple sample
> code which doesn't have anything to do with loops but is broken when you specify
> loop optimizations.

I have had a similar problem, specifying the following flags:

cl -Zi -AL -Gt16 -I../INCLUDE/ -c

The code that I tried to compile was:

			RetCode = (*LFunctions[(int) *pLActions])();
			pLActions++;

Unless I specify -Od to disable all optimizations, pLActions is 
incremented BEFORE the indirection is performed.

I no longer worry about benchmark comparisons of the Microsoft
C compiler -- my experience is that -Od is necessary not only for
debugging, but for execution as well.
-- 
Clayton E. Cramer {pyramid,pixar,tekbspa}!optilink!cramer
Pipe bomb: appropriate technology for living lightly on Mother Earth. :-)
----------------------------------------------------------------------------
Disclaimer?  You must be kidding!  No company would hold opinions like mine!