This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/33970] Missed optimization using unsigned char loop variable
- From: "wvangulik at xs4all dot nl" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 6 Nov 2007 19:34:59 -0000
- Subject: [Bug middle-end/33970] Missed optimization using unsigned char loop variable
- References: <bug-33970-15294@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #10 from wvangulik at xs4all dot nl 2007-11-06 19:34 -------
(In reply to comment #9)
>
> I think you will also find that if x is changed from ststic to auto the same
> problem appears.
>
Ok, I tried to find the minimum test case.
And it has nothing todo with static/volatile/inline etc.
==============================================
int sub2(unsigned char); // external function
void foo(void) {
unsigned char x;
for(x=0;x<128; x++)
{
//sub2(x); //x is becomes a int (16bit)
sub2(x+1); //x is char (8bit)
}
}
All is compiled using 4.1.2 and "avr-gcc -Wall -Os -mmcu=avr5 -S test.c"
The output when compiling with "sub2(x)"
=================================================
/* prologue: frame size=0 */
push r28
push r29
/* prologue end (size=2) */
ldi r28,lo8(0)
ldi r29,hi8(0)
.L2:
mov r24,r28 ; << loads as a byte!
call sub2
adiw r28,1 ; << increment as a int
cpi r28,128 ; << compare as a int
cpc r29,__zero_reg__
brne .L2
/* epilogue: frame size=0 */
pop r29
pop r28
ret
The output when compiling with "sub2(x+1)"
================================================================
/* prologue: frame size=0 */
push r17
/* prologue end (size=1) */
ldi r17,lo8(0)
.L2:
subi r17,lo8(-(1))
mov r24,r17
call sub2
cpi r17,lo8(-128)
brne .L2
/* epilogue: frame size=0 */
pop r17
ret
===========================================================
>From compiling with x as a int I got a sort of hint. When using x+1, x is
actually loaded with 1 (and not zero).
So i tried:
======================================================
void foo(void) {
unsigned char x;
for(x=1;x<129; x++)
sub2(x);
}
And it gives the assembler loop check as for the "sub(x+1)" variant of course
the loop is now effectivley the same as "sub2(x+1)". But the the incrementing
of x is now done after the call, so it proofs that this is not the problem. I
also tried different loop lengths, thinking 128 is the nasty one, but it did
not help.
======================================================
/* prologue: frame size=0 */
push r17
/* prologue end (size=1) */
ldi r17,lo8(1)
.L2:
mov r24,r17
call sub2
subi r17,lo8(-(1))
cpi r17,lo8(-127)
brne .L2
/* epilogue: frame size=0 */
pop r17
ret
I am out of knowledge now, I do not know how to further debug GCC on this. Just
hoping this will help someone to pinpoint the problem.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33970