[gnu.gcc.bug] Bad code generated by gcc1.30, Sun3 when not optimising

paul@UUNET.UU.NET (Paul Hudson) (12/01/88)

The following programs generates incorrect code, as indicated below.
It is correct when optimising.

Paul Hudson 

Snail mail: Monotype ADG	Email:	...!ukc!acorn!moncam!paul
	    Science Park,		paul@moncam.co.uk
	    Milton Road,	"Sun Microsysytems:
	    Cambridge,		 The Company is Arrogant (TM)"
	    CB4 4FQ

Compiled with ...
gnucc -g  -W -Wall -Wunused -m68020 -mc68020

typedef  int FixedPt;			 
typedef int TransFixedPt;
typedef struct CdpCB
{
    int command;		    
    union
    {
	struct				 
	{
	    void *base;		 
	    TransFixedPt tolerance;	 
	     
	    unsigned int max_points;
	     
	    unsigned int max_maxima;
	}   Initialise;
	struct				 
	{
	    TransFixedPt transform[3][2];	 
	     
	    int magic;
	    int fill_rule;
	    int inputType;		 
	    unsigned int *char_data;	 
	    int outputType;		 
	    short outputData;		 
	}   Fill;
	struct				 
	{
	    int status;			 
	    int outputType;		 
	    short lastBlock;		 
	    unsigned short left, right, top, bottom;
	    int edges;			 
	}   Return;
    }   u;
}   CdpCB;
typedef struct Point
{
    int x;
    int y;
} Point;
typedef struct pathBBox
{
    Point top_right;
    Point bottom_left;
} PathBBox;
extern PathBBox path_bbox();
void cdp(CdpCB *cb, CdpCB *reply)
{
    int status;
    switch (cb->command)
    {
      case 1		:
	if (path_init(cb->u.Initialise.max_points,31) &&
	    initialise_paint(cb->u.Initialise.max_maxima) &&
	    initialise_runs(cb->u.Initialise.max_maxima) &&
	    initialise_flatten(cb->u.Initialise.tolerance) &&
	    initialise_output(cb->u.Initialise.base))
	    reply->u.Return.status = 0 ;
	else
	    reply->u.Return.status = 1 ;
	return;
	
      case 2		:
	status = rasterise(cb);
	switch (status)
	{
	    
	  case 2 :
	  case 0 :
	     
	     
	    {
		PathBBox pb = path_bbox();
		reply->u.Return.status	   = status;
		reply->u.Return.outputType = (status == 2 
					      ? 3		
					      : cb->u.Fill.outputType);
		reply->u.Return.lastBlock  = currentblock();
		reply->u.Return.left	   = ((((pb.bottom_left.x) &~((1 << 	6		) - 1) ) ) >> 	6		) ;
/* >>> The following statement is compiled incorrectly <<< */
		reply->u.Return.right	   = (((((pb.top_right.x) + ((1 << 	6		) - 1) ) &~((1 << 	6		) - 1) )  ) >> 	6		) ;
		reply->u.Return.top	   = (((((pb.top_right.y) + ((1 << 	6		) - 1) ) &~((1 << 	6		) - 1) )  ) >> 	6		) ;
		reply->u.Return.bottom	   = ((((pb.bottom_left.y) &~((1 << 	6		) - 1) ) ) >> 	6		) ;
	    }
	    break;
	    
	     
	  case 6 :
	    reply->u.Return.status    = 8 ;
	    break;
	     
	  case 3 :
	  case 4 :
	  case 5 :
	    reply->u.Return.status    = status;
	    break;
	  default:
	    reply->u.Return.status    = 6 ;
	    break;
	}
	return;
      case 3		:
      default:
	reply->u.Return.status = 7 ;
	return;
    }
}

(Some of ) the assembler is given below

L8:
L9:
LBB3:
	.stabd 68,0,75
	moveq #-20,d0
	addl a6,d0
	movel d0,a1
	jbsr _path_bbox
	.stabd 68,0,76
	movel a6@(12),a0
	movel a6@(-4),a0@(4)
	.stabd 68,0,79
	movel a6@(12),a0
	moveq #2,d1
	cmpl a6@(-4),d1
	jne L10
	moveq #3,d1
	movel d1,a0@(8)
	jra L11
L10:
	movel a6@(8),a1
	movel a1@(44),a0@(8)
L11:
	.stabd 68,0,80
	jbsr _currentblock
	movel d0,d0
	movel a6@(12),a0
	movew d0,a0@(12)
	.stabd 68,0,81
	movel a6@(12),a0
	moveq #-64,d0
	andl a6@(-12),d0
	asrl #6,d0
	movew d0,a0@(14)
	.stabd 68,0,82
	movel a6@(12),a0
	moveq #63,d1
	addl a6@(d0:l),d1 	<<< what's this d0:l, then?
	movel d1,d0
	moveq #-64,d1
	andl d1,d0
	asrl #6,d0
	movew d0,a0@(16)
	.stabd 68,0,83
	movel a6@(12),a0
	moveq #63,d0
	addl a6@(-16),d0
	andl d1,d0
	asrl #6,d0
	movew d0,a0@(18)
	.stabd 68,0,84
	movel a6@(12),a0
	moveq #-64,d0
	andl a6@(-8),d0
	asrl #6,d0
	movew d0,a0@(20)