avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [avr-gcc-list] GCC does useless 16-bit operations


From: Eric Weddington
Subject: RE: [avr-gcc-list] GCC does useless 16-bit operations
Date: Fri, 06 Jul 2007 16:48:51 -0600


> -----Original Message-----
> From:
> address@hidden
> [mailto:address@hidden
> org] On Behalf Of Daniel Barkalow
> Sent: Thursday, May 10, 2007 1:56 PM
> To: address@hidden
> Subject: [avr-gcc-list] GCC does useless 16-bit operations
>
> For the C code:
>
> uint8_t tx_producer_index;
> ...
> {
>   ...
>   uint8_t temp = (tx_producer_index + 1) % 64;
>
> I get the assembly from gcc 3.4.4:
>
>     13a2:       e0 91 f7 00     lds     r30, 0x00F7
>     13a6:       8e 2f           mov     r24, r30
>     13a8:       99 27           eor     r25, r25
>     13aa:       01 96           adiw    r24, 0x01       ; 1
>     13ac:       9c 01           movw    r18, r24
>     13ae:       80 7c           andi    r24, 0xC0       ; 192
>     13b0:       93 70           andi    r25, 0x03       ; 3
>     13b2:       28 1b           sub     r18, r24
>
> >From gcc 4.1.2, it's even worse:
>
>     1658:       80 91 f8 00     lds     r24, 0x00F8
>     165c:       e8 2f           mov     r30, r24
>     165e:       ff 27           eor     r31, r31
>     1660:       cf 01           movw    r24, r30
>     1662:       01 96           adiw    r24, 0x01       ; 1
>     1664:       60 e4           ldi     r22, 0x40       ; 64
>     1666:       70 e0           ldi     r23, 0x00       ; 0
>     1668:       e9 d2           rcall   .+1490          ;
> 0x1c3c <__divmodhi4>
>     166a:       28 2f           mov     r18, r24
>
> The C code:
>
>   uint8_t temp = (tx_producer_index + 1U) % 64;
>
> is much much better with 3.4.4:
>
>     16de:       e0 91 f7 00     lds     r30, 0x00F7
>     16e2:       ef 5f           subi    r30, 0xFF       ; 255
>     16e4:       9e 2f           mov     r25, r30
>     16e6:       9f 73           andi    r25, 0x3F       ; 63
>
> But
>
>   uint8_t temp = (tx_producer_index + (uint8_t) 1) % 64;
>
> is the same as without the cast. So two issues:
>
> 1) Shouldn't the type of "(uint8_t) 1" be strictly no larger
> than the type
>    of 1U?
>
> 2) gcc 4.1.2 generates unuseably bad code for int16_t %
> int8_t when the
>    int8_t is a positive power-of-2 constant.
>
> 3) I'm not totally sure, but I think it shouldn't need 16-bit
> math in any
>    of this. And gcc 4.1.2 does use 16-bit math for the
> addition with the
>    64 unchanged, but doesn't if the 64 is replaced with 64U,
> which must
>    be an error of some sort.
>
> Is there something I should do to figure out what GCC thinks
> it's doing?

At this point, all I can recommend is that you file a bug report with the
GCC project with the keyword missed-optimization. I agree that the current
situation is not ideal.

However, I am curious. What do you get with this:

uint8_t temp = (tx_producer_index++) % 64;

Thanks,
Eric






reply via email to

[Prev in Thread] Current Thread [Next in Thread]