From: zsd@axe.drea.dnd.ca (Jim Diamond)
Newsgroups: comp.sys.sgi
Subject: YA optimizer bug
Date: 28 Jul 92 17:13:25 GMT

I'm sure there's some SGI guy who is interested, so...

The following program demonstrates a bug in 4.0.2 on an Indigo as well
as on 4.0.4 on an R4000/50 (Elan and GTX graphics, respectively, altho
I expect that is irrelevant).  (Profuse apologies for not chopping it
down into a small program.)  The program works as expected with no
optimization or -O1 optimization, but -O, -O3 and -O4 all have
problems.  Specifically, choosing the "pastels" entry of the color
sub-menu causes the "gold" colors to be chosen, and choosing the
"gold" option kills the program.  Note that uncommenting the printf()
near the end of do_color_set() causes the bug to go away... so much
for debugging statements!

Is this fixed in the much-awaited 4.0.5?

		Jim Diamond
		zsd@axe.drea.dnd.ca

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

/*
From dave@ivem1.ucsd.edu 
Article 1007 of comp.sys.sgi:
Received: Mon, 29 Apr 91 17:01:55 ADT from vmb.brl.mil by pig.drea.dnd.ca (5.52/5.6)
Received: from vmb.brl.mil by VMB.BRL.MIL id ab16762; 29 Apr 91 15:12 EDT
Received: from ucsd.edu by VMB.BRL.MIL id aa16517; 29 Apr 91 14:57 EDT
Received: from ivem1.ucsd.edu by ucsd.edu; id AA05497
	sendmail 5.64/UCSD-2.1-sun via SMTP
	Mon, 29 Apr 91 11:04:45 -0700 for info-iris@vmb.brl.mil
Received: by ivem1.UCSD.EDU (4.1/UCSDGENERIC.3)
	id AA11381 to info-iris@vmb.brl.mil; Mon, 29 Apr 91 11:01:00 PDT
Date: Mon, 29 Apr 91 11:01:00 PDT
>From: Dave <dave@ivem1.ucsd.edu>
Message-Id: <9104291801.AA11381@ivem1.UCSD.EDU>
To: info-iris@vmb.brl.mil

/*
 *	macic_dust - magic dustles spew forth from the cursor
 *
 *	David Hessler 4/25/91
 *
 *      cc -O3 -o magic_dust magic_dust.c -lgl_s
 */

#include "gl.h"
#include "device.h"

#define DEF_N		1000	/* max number of dustles */
int	N    = DEF_N;
#define DEF_NDPC	3.	/* new dustles per cycle */
float	NDPC = DEF_NDPC;
#define DEF_GRAV	.3	/* gravitational acceleration */
float	GRAV = DEF_GRAV;
#define DEF_MVEL	-.1	/* amount of mouse vel imparted to new dustle */
float	MVEL = DEF_MVEL;
#define DEF_IVEL	4.	/* magnitude of initial random velocity */
float	IVEL = DEF_IVEL;
#define DEF_VODV	.2	/* vertical offset of dustle velocity */
float	VODV = DEF_VODV;
#define DEF_CMIN	90	/* index of minmum  dustle color */
int	CMIN = DEF_CMIN;
#define DEF_CMAX	94	/* index of maximum dustle color */
int	CMAX = DEF_CMAX;

/* get a random float from -1. to 1. */
#define frandom() (((random()%10001)-5000)/5000.)

void (*clear_fn)();	/* clear function pointer */

/*
 * clear function to be used on personal iris -- clear() doesn't
 * work right when a pi window is in background mode.
 *
 * !!! I don't have a pi so I don't know if this worx. !!!
 *
 */
void pi_clear()
{
	rectfi(0, 0, XMAXSCREEN, YMAXSCREEN);
}

/* one dustle */
typedef struct {
	float x, y;	/* it's location */
	float dx, dy;	/* it's velocity */
	int cidx;	/* it's color */
} dustle;

/* dustle storage */
dustle dustles[DEF_N];		/* the dustles */
int ndustles = 0;		/* number of active dustles */

main()
{
	char gv_buf[80];
	int back, control;
	long dev; short val;

	srandom(time(0));

	/* set up control window */
	noborder();
	prefposition(0, 19, 0, 19);
	control = winopen("magic dust");
	prefsize(20, 20);
	winconstraints();
	draw_control_window();
	init_menus();

	/* Be nice */
	nice(19);

	/* set up background window */
	prefposition(0, XMAXSCREEN, 0, YMAXSCREEN);
	imakebackground();
	back = winopen("magic dust");
	doublebuffer();
	linewidth(3);
	gconfig();

	/*
	 * set up clear function appropriate for this machine
	 * gversion returnsa string of the form 'GL4DPI...'
	 * on a personal iris, and something else on non-p.i.s...
	 */
	gversion(gv_buf);
	if (gv_buf[4] == 'P')
	  clear_fn = pi_clear;
	else
	  clear_fn = clear;

	/* go! */
	qdevice(QKEY);
	qdevice(REDRAW);
	qdevice(WINTHAW);
	qdevice(WINFREEZE);
	qdevice(RIGHTMOUSE);
	while(1) {

	  while(qtest()) {
	    dev = qread(&val);

	    switch(dev) {

	      /* quit */
	      case(QKEY):
		exit(0);

	      /* re-do command window */
	      case(REDRAW):
		if (val == control) {
		  winset(control);
		  draw_control_window();
		}
		break;

	      /* do menus */
	      case(RIGHTMOUSE):
		do_menus();
		break;

	    }
	  }

	  winset(back);
	  color(BLACK);
	  clear_fn();
	  do_dustles();
	  swapbuffers();
	}
}

do_dustles()
{
	static int first=1;
	static float ox, oy;	/* x & y from last time */
	static float step=0.;
	register dustle *dptr;
	register int i;
	static float x, y;

	/* where'z the cursor? */
	x = getvaluator(MOUSEX);
	y = getvaluator(MOUSEY);

	/*
	 * initially, we don't have ox & oy,
	 * so we just make 'em the same as x & y
	 */
	if (first) {
	  ox = x;
	  oy = y;
	  first = 0;
	}

	/* add new dustles */
	step += NDPC;
	while  ((ndustles<N) && (step>0.)) {
	  dptr = &dustles[ndustles++];

	  dptr->x = x;
	  dptr->y = y;
	  dptr->dx = MVEL*(x-ox) + frandom()*IVEL;
	  dptr->dy = MVEL*(y-oy) + frandom()*IVEL + VODV*IVEL;
	  dptr->cidx = (random()%(CMAX-CMIN+1))+CMIN;

	  step -= 1.;
	}

	/* save cursor location */
	ox = x;
	oy = y;

	/* do dustles */
	dptr = dustles;
	for (i=0; i<ndustles;) {

	  /* set color */
	  color(dptr->cidx);

	  /* old location */
	  x = dptr->x;
	  y = dptr->y;
	  move2(x, y);

	  /* new location */
	  dptr->x = (x += dptr->dx);
	  dptr->y = (y += dptr->dy);
	  draw2(x, y);

	  /* gravitational acceleration */
	  dptr->dy -= GRAV;

	  /* toss dustles that have left the screen */
	  if ((x<0)||(x>XMAXSCREEN)
	           ||((GRAV<=0.)&&(y>YMAXSCREEN))||((GRAV>=0.)&&(y<0)))
	    *dptr = dustles[--ndustles];
	  else {
	    dptr++;
	    i++;
	  }
	}
}

/* draw the control window : a box surrounding a wand w/sparx */
draw_control_window()
{
	static Object o = -1;

	if (o == -1) {

	  makeobj(o=genobj());

	  /* clear it */
	  color(BLACK);
	  clear();

	  /* some sparkles */
	  linewidth(1);
	  color(90);
	  move2i(9, 15); draw2i(7, 16);
	  move2i(16, 12); draw2i(17, 14);
	  color(92);
	  move2i(8, 12); draw2i(6, 12);
	  move2i(15, 9); draw2i(16, 7);
	  color(94);
	  move2i(12, 8); draw2i(12, 6);
	  move2i(12, 16); draw2i(14, 17);
  
	  /* border */
	  color(16);
	  recti(0, 0, 19, 19);
  
	  /* ball */
	  circfi(12, 12, 2);

	  /* and stick */
	  linewidth(2);
	  move2i(3, 3);
	  draw2i(12, 12);

	  closeobj();
	}

	callobj(o);

}

/* menus to change operational parameters */
static int main_menu;
do_menus()
{
	switch(dopup(main_menu)) {

	  /* quit */
	  case(1):
	    exit(0);

	  /* reset parameters */
	  case(2):
	    N    = DEF_N;
	    NDPC = DEF_NDPC;
	    GRAV = DEF_GRAV;
	    MVEL = DEF_MVEL;
	    IVEL = DEF_IVEL;
	    VODV = DEF_VODV;
	    CMIN = DEF_CMIN;
	    CMAX = DEF_CMAX;
	    break;
	}
}

/* change number of dustles */
do_num_dustles(op)
	int op;
{
	N = op;

	if (N > DEF_N) N = DEF_N;
	if (N < 1) N = 1;

	if (N < ndustles)
	  ndustles = N;
}

/* change new dustle rate */
do_new_dustle_rate(op)
	int op;
{
	NDPC = op/10.;
}

/* adjust gravity */
do_gravity(op)
	int op;
{
	GRAV = op/10.;
}

/* change initial dustle velocity bound */
do_initial_velocity(op)
	int op;
{
	IVEL = op/10.;
}

/* alter mouse's effect on inital dustle velovity */
do_mvel(op)
	int op;
{
	MVEL = op/10.;
}

/* alter vertical offsert to inital dustle velocity */
do_vodv(op)
	int op;
{
	VODV = op/10.;
}

/* select which colorz get used */
do_color_set(op)
	int op;
{
printf("do_color_set: op = %d\n", op);
	switch(op) {
	  case(1): CMIN =  90; CMAX =  94; break; /* gold */
	  case(2): CMIN =   9; CMAX =  14; break; /* pastels */
	  case(3): CMIN =   1; CMAX =   7; break; /* primaries */
	  case(4): CMIN =  32; CMAX =  56; break; /* greys */
	  case(5): CMIN =  57; CMAX = 255; break; /* rainbow */
	  case(6): CMIN =   7; CMAX =   7; break; /* white */
	  case(7): CMIN = 512; CMAX = 767; break; /* 512-767 */
	}
/*printf("CMIN = %d,  CMAX = %d\n", CMIN,  CMAX);*/
}

/* set up all them menus */
init_menus()
{
	static int ndus_menu;
	static int ndpc_menu;
	static int grav_menu;
	static int ivel_menu;
	static int mvel_menu;
	static int vodv_menu;
	static int color_menu;

	ndus_menu = newpup();
	addtopup(ndus_menu, "Number of Dustles %t %F", do_num_dustles);
	addtopup(ndus_menu, "1000 %x1000");
	addtopup(ndus_menu, "500 %x500");
	addtopup(ndus_menu, "200 %x200");
	addtopup(ndus_menu, "100 %x100");
	addtopup(ndus_menu, "50 %x50");
	addtopup(ndus_menu, "20 %x20");
	addtopup(ndus_menu, "10 %x10");
	addtopup(ndus_menu, "5 %x5");
	addtopup(ndus_menu, "2 %x2");
	addtopup(ndus_menu, "1 %x1");

	ndpc_menu = newpup();
	addtopup(ndpc_menu, "New Dustle Rate %t %F", do_new_dustle_rate);
	addtopup(ndpc_menu, "8 %x80");
	addtopup(ndpc_menu, "4 %x40");
	addtopup(ndpc_menu, "2 %x20");
	addtopup(ndpc_menu, "1 %x10");
	addtopup(ndpc_menu, "1/2 %x5");
	addtopup(ndpc_menu, "1/5 %x2");
	addtopup(ndpc_menu, "1/10 %x1");

	grav_menu = newpup();
	addtopup(grav_menu, "Gravity %t %F", do_gravity);
	addtopup(grav_menu, "5. %x50");
	addtopup(grav_menu, "2. %x20");
	addtopup(grav_menu, "1. %x10");
	addtopup(grav_menu, ".7 %x7");
	addtopup(grav_menu, ".5 %x5");
	addtopup(grav_menu, ".3 %x3");
	addtopup(grav_menu, ".1 %x1");
	addtopup(grav_menu, "0. %x0");
	addtopup(grav_menu, "-.1 %x-1");
	addtopup(grav_menu, "-.3 %x-3");
	addtopup(grav_menu, "-.5 %x-5");
	addtopup(grav_menu, "-.7 %x-7");
	addtopup(grav_menu, "-1. %x-10");
	addtopup(grav_menu, "-2. %x-20");
	addtopup(grav_menu, "-5. %x-50");

	ivel_menu = newpup();
	addtopup(ivel_menu, "Initial Velocity %t %F", do_initial_velocity);
	addtopup(ivel_menu, "20. %x200");
	addtopup(ivel_menu, "10. %x100");
	addtopup(ivel_menu, "6. %x60");
	addtopup(ivel_menu, "4. %x40");
	addtopup(ivel_menu, "3. %x30");
	addtopup(ivel_menu, "2. %x20");
	addtopup(ivel_menu, "1. %x10");
	addtopup(ivel_menu, ".5 %x5");
	addtopup(ivel_menu, "0. %x0");

	vodv_menu = newpup();
	addtopup(vodv_menu, "Vertical Velocity Offset %t %F", do_vodv);
	addtopup(vodv_menu, "2. %x20");
	addtopup(vodv_menu, "1. %x10");
	addtopup(vodv_menu, ".5 %x5");
	addtopup(vodv_menu, ".2 %x2");
	addtopup(vodv_menu, "0. %x0");
	addtopup(vodv_menu, "-.2 %x-2");
	addtopup(vodv_menu, "-.5 %x-5");
	addtopup(vodv_menu, "-1. %x-10");
	addtopup(vodv_menu, "-2. %x-20");

	mvel_menu = newpup();
	addtopup(mvel_menu, "Mouse Throw %t %F", do_mvel);
	addtopup(mvel_menu, "2. %x20");
	addtopup(mvel_menu, "1. %x10");
	addtopup(mvel_menu, ".5 %x5");
	addtopup(mvel_menu, ".3 %x3");
	addtopup(mvel_menu, ".1 %x1");
	addtopup(mvel_menu, "0. %x0");
	addtopup(mvel_menu, "-.1 %x-1");
	addtopup(mvel_menu, "-.3 %x-3");
	addtopup(mvel_menu, "-.5 %x-5");
	addtopup(mvel_menu, "-1. %x-10");
	addtopup(mvel_menu, "-2. %x-20");

	color_menu = newpup();
	addtopup(color_menu, "Colors %t %F", do_color_set);
	addtopup(color_menu, "Gold %x1");
	addtopup(color_menu, "Pastels %x2");
	addtopup(color_menu, "Primaries %x3");
	addtopup(color_menu, "Greys %x4");
	addtopup(color_menu, "Rainbow %x5");
	addtopup(color_menu, "Boring White %x6");
	addtopup(color_menu, "512-767 %x7");

	main_menu = newpup();
	addtopup(main_menu, "Magic Dust %t");
	addtopup(main_menu, "Quit|Reset %l");
	addtopup(main_menu, "Number of Dustles %m", ndus_menu);
	addtopup(main_menu, "New Dustle Rate %m", ndpc_menu);
	addtopup(main_menu, "Gravity %m", grav_menu);
	addtopup(main_menu, "Initial Velocity %m", ivel_menu);
	addtopup(main_menu, "Mouse Throw %m", mvel_menu);
	addtopup(main_menu, "Vertical Velocity Offset %m", vodv_menu);
	addtopup(main_menu, "Colors %m", color_menu);
}
Newsgroups: comp.sys.sgi