September 15, 2003
Hi,

When I turn on the -o+speed switch for the code listed below, the compiler generates 'invalid' code.

Options: -6 -o+speed -mn -WA
Compiler gives one warning:  Warning 12: variable 'struct tagRGBQUAD tempRGB'
used before set


#include <windows.h>

void __stdcall func(const RGBQUAD *pSource, RGBQUAD *pDest, int width, int
height);

int main(void)
{  RGBQUAD  m1[ 4 ][ 4 ], m2[ 4 ][ 4 ];

func( (RGBQUAD *) m1, (RGBQUAD *) m2, 4, 4 );

return 0;
}

void __stdcall func(const RGBQUAD *pSource, RGBQUAD *pDest, int width, int
height)
{  int      pixel_count;
RGBQUAD  tempRGB;

pixel_count = width * height -1;

while (pixel_count >= 0) {
tempRGB = pSource[ pixel_count ];

tempRGB.rgbRed   = (tempRGB.rgbRed & 0xf0)   | (tempRGB.rgbRed >> 4);
tempRGB.rgbGreen = (tempRGB.rgbGreen & 0xf0) | (tempRGB.rgbGreen >> 4);
tempRGB.rgbBlue  = (tempRGB.rgbBlue & 0xf0)  | (tempRGB.rgbBlue >> 4);
pDest[ pixel_count ] =tempRGB;

pixel_count--;
}
}


Generated assembly:
push   eax
mov    edx,[esp+08]
push   ebx
mov    ebx,[esp+14]
push   esi
mov    esi,[esp+14]
imul   ebx,[esp+1C]
dec    ebx
js     L1
mov    cl,[esp+09] ; (1)
and    cl,F0
movzx  eax,byte ptr [esp+09]
sar    eax,04
or     cl,al
mov    [esp+09],cl
mov    cl,[esp+08]
and    cl,F0
movzx  eax,byte ptr [esp+08]
sar    eax,04
or     cl,al
mov    [esp+08],cl
L2: mov    ecx,[edx+4*ebx]
mov    [esp+08],ecx
mov    cl,[esp+0A]
and    cl,F0
movzx  eax,byte ptr [esp+0A]
sar    eax,04
or     cl,al
mov    [esp+0A],cl
mov    ecx,[esp+08]
mov    [esi+4*ebx],ecx
dec    ebx
test   ebx,ebx
jns    L2  ; (2)
L1: pop    esi
pop    ebx
pop    eax
ret    0010

At (1), the data at [esp+09] is unknown.
At (2), the conditional jump jumps to the wrong address although (at L2) it
reads data from the 'right' address and writes this to the stack (this should be
done before (1)).
I don't get the warning when I don't use the switch -o+speed.