|From:||Peter A. Zuur|
|Subject:||[avr-gcc-list] AVR GCC Version 3.3 20030421 - taget mega128|
|Date:||Wed, 6 Aug 2003 08:53:23 +0200|
I have found a bug in the AVR-GCC compiler (target mega128) when used with any other optimization level than -O0 .
The following function which updates a crc-8 with <octet> always returns 0 when compiled with optimization switched on.
The reason for that is that the compiler erroneously optimizes the <then> clause of the <if> statement out.
unsigned char crc8(unsigned char crc, unsigned char octet)
unsigned char j, tmp;
while(j < 8)
tmp= crc ^ octet;
if(tmp & 0x01) // optimized out
crc^= 0x18; // optimized out
crc>>= 1; // optimized out
crc|= 0x80; // optimized out
crc>>= 1; // always executed
octet>>= 1; // optimized out
The offending line seems to be the _expression_
if(tmp & 0x01)
With the -O0 (no optimization) this line is compiled to:
line 1: ldd r24,Y+4 // Y+4 is <tmp>
line 2: clr r25
line 3: andi r24,lo8(1)
line 4: andi r25,hi8(1)
line 5: sbiw r24,0
line 6: breq .L11 // Jump to else clause if Z flag set
The compiler correctly expands the 8-bit unsigned char to a 16-bit int for the _expression_ evaluation.
HOWEVER !!! What the optimizer (using -O1 or -O2 or -O3) seems to do is:
1 - Get rid of line 5 because it thinks that subtracting 0 has no effect.
2 - Get rid of line 6 + the <true> part of the <if> clause because line 4 will always result in the Z flag to be set.
It seems to me that the machine definition of the target (mega128) is wrong.
It probably tells the compiler that the sbiw command does not affect the Z flag.
Could anybody tell me whether I'm smoking my socks or confirm (and preferably fix) this bug ?
|[Prev in Thread]||Current Thread||[Next in Thread]|