Bug 39510

Summary: [avr] missed optimisation with IO read and register variables
Product: gcc Reporter: Krzysztof Kościuszkiewicz <k.kosciuszkiewicz+gcc>
Component: rtl-optimizationAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: eric.weddington, gcc-bugs
Priority: P3 Keywords: missed-optimization
Version: 4.3.3   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: 4.3.3 4.3.2 Last reconfirmed: 2009-08-21 20:10:06
Attachments: Second test case with void functions.
Preprocessed source of test case

Description Krzysztof Kościuszkiewicz 2009-03-20 03:13:23 UTC
Code:

#include <avr/io.h>

register uint8_t test asm("r2");

int main(void)
{
    test = TCNT0;
}

Compiled with -Os results in the following instruction sequence:

00000092 <main>:
  92:	82 b7       	in	r24, 0x32	; 50
  94:	28 2e       	mov	r2, r24
  96:	08 95       	ret

This is particularly nasty for naked interrupts, where one would expect the compiler to generate just a single instruction:
  
  in  r2, 0x32

Apparently the compiler behaves correctly when opposite transfer is requested, generating single OUT opcode.
Comment 1 Eric Weddington 2009-03-27 17:06:12 UTC
This bug is invalid.

Your test code is in main() which returns an int. The return value is stored in r24. So the code is correct to store the value in both r2 (test) and r24.

See the avr-libc user manual, FAQ, for more information on the calling convention:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage

Perhaps you need to try this in a function that has void return.
Comment 2 Krzysztof Kościuszkiewicz 2009-03-27 17:46:17 UTC
I can't see how register usage and calling convention affect this.

As I said before, this behaviour bit me in a naked interrupt handler, with no arguments and no return value.

I'm attaching a fixed test case where functions have no arguments and void return type.

#include <avr/io.h>

register uint8_t test asm("r2");

void fun1(void)
{
    test = TCNT0;
}

void fun2(void)
{
    TCNT0 = test;
}

Compile with -Os. Generated instruction sequence:

00000000 <fun1>:
   0:	82 b7       	in	r24, 0x32	; 50
   2:	28 2e       	mov	r2, r24
   4:	08 95       	ret

00000006 <fun2>:
   6:	22 be       	out	0x32, r2	; 50
   8:	08 95       	ret
Comment 3 Krzysztof Kościuszkiewicz 2009-03-27 17:47:27 UTC
Created attachment 17545 [details]
Second test case with void functions.
Comment 4 Andrew Pinski 2009-03-28 05:22:33 UTC
This might be the case hard registers are not always copy propogated except into inline-asm.  Can you provide the preprocessed source?
Comment 5 Krzysztof Kościuszkiewicz 2009-03-28 05:55:00 UTC
Created attachment 17553 [details]
Preprocessed source of test case

Created with "avr-gcc -v -save-temps -mmcu=attiny13 -Os -c test.c -o test.o"
Comment 6 Eric Weddington 2009-08-21 20:10:06 UTC
Confirmed on 4.3.2.