[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] modulo vs. loop (gcc 4.3.x bug)
From: |
Szikra Istvan |
Subject: |
[avr-gcc-list] modulo vs. loop (gcc 4.3.x bug) |
Date: |
Sun, 28 Mar 2010 00:24:43 +0100 |
/**
Category: bug: false optimization leads to critical bug
affects: avr-gcc 4.3.x
Problem: Modulo calculation is "optimized" to __udivmodqi4 calls from
simple loop (without asking for it)
-simple loop is smaller
-it is faster for small input numbers (which I know will be the case)
-bootloader section cannot have calls to the application section !
- if I wanted modulo, I would have written % , I did not waste my time
writing ten times as much character just for fun
-also generated divide+modulo code is inefficient, double call to
__udivmodqi4 with same parameters
--Details:
-environment: WinAVR-20080610,20081205,20090313,20100110 (avr-gcc 4.3.x )
(WinAVR-20060421, 20070525 works)
-build command:
avr-gcc -mmcu=atmega16 -save-temps -Os test.c
or WinAVR Makefile Template
Here is the test code:
*/
/** Note (to self): __udivmodqi4 is a paper-pencil division
other possible methods:
d = i/3 = (i*85+85)/256
m = i%3 = i-3*d
d = i/10 = (i*51+51)/512
m = i%10 = i-10*d
*/
#include <avr/io.h>
#include <avr/boot.h>
void test(void) BOOTLOADER_SECTION;
int main (void)
{
for (;;)
{
}
}
void test(void)
{
unsigned char m = PORTA;
unsigned char d=0;
while (m>=3){
d++;
m-=3;
}
PORTB=d;
PORTC=m;
}
/** ------------------ What I got --------------------- gcc 4.3.3
unsigned char m = PORTA;
3800: 2b b3 in r18, 0x1b ; 27
while (m>=3){
d++;
m-=3;
}
3802: 82 2f mov r24, r18
3804: 63 e0 ldi r22, 0x03 ; 3
3806: 0e 94 37 00 call 0x6e ; 0x6e <__udivmodqi4>
380a: 38 2f mov r19, r24
380c: 82 2f mov r24, r18
380e: 0e 94 37 00 call 0x6e ; 0x6e <__udivmodqi4>
PORTB=d;
3812: 38 bb out 0x18, r19 ; 24
PORTC=m;
3814: 95 bb out 0x15, r25 ; 21
0000006e <__udivmodqi4>:
6e: 99 1b sub r25, r25
70: 79 e0 ldi r23, 0x09 ; 9
72: 04 c0 rjmp .+8 ; 0x7c <__udivmodqi4_ep>
00000074 <__udivmodqi4_loop>:
74: 99 1f adc r25, r25
76: 96 17 cp r25, r22
78: 08 f0 brcs .+2 ; 0x7c <__udivmodqi4_ep>
7a: 96 1b sub r25, r22
0000007c <__udivmodqi4_ep>:
7c: 88 1f adc r24, r24
7e: 7a 95 dec r23
80: c9 f7 brne .-14 ; 0x74 <__udivmodqi4_loop>
82: 80 95 com r24
84: 08 95 ret
*/
/** ------------------ What I wanted --------------------- gcc 4.1.2
unsigned char m = PORTA;
3800: 8b b3 in r24, 0x1b ; 27
unsigned char d=0;
3802: 90 e0 ldi r25, 0x00 ; 0
while (m>=3){
3804: 02 c0 rjmp .+4 ; 0x380a <test+0xa>
d++;
3806: 9f 5f subi r25, 0xFF ; 255
m-=3;
3808: 83 50 subi r24, 0x03 ; 3
380a: 83 30 cpi r24, 0x03 ; 3
380c: e0 f7 brcc .-8 ; 0x3806 <test+0x6>
}
PORTB=d;
380e: 98 bb out 0x18, r25 ; 24
PORTC=m;
3810: 85 bb out 0x15, r24 ; 21
*/
/** ------------------ or --------------------- gcc 3.4.6
unsigned char m = PORTA;
3800: 8b b3 in r24, 0x1b ; 27
unsigned char d=0;
3802: 90 e0 ldi r25, 0x00 ; 0
while (m>=3){
d++;
m-=3;
3804: 83 30 cpi r24, 0x03 ; 3
3806: 18 f0 brcs .+6 ; 0x380e <test+0xe>
3808: 9f 5f subi r25, 0xFF ; 255
380a: 83 50 subi r24, 0x03 ; 3
380c: fb cf rjmp .-10 ; 0x3804 <test+0x4>
}
PORTB=d;
380e: 98 bb out 0x18, r25 ; 24
PORTC=m;
3810: 85 bb out 0x15, r24 ; 21
*/
/*
-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024 -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing
-fno-inline-small-functions -save-temps -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test.lst -ID:/Lib/ -std=gnu99 -MD -MP
-MF .dep/test.o.d test.c -o test.o
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024 -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing
-fno-inline-small-functions -save-temps -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test.o -ID:/Lib/ -std=gnu99 -MD -MP
-MF .dep/test.elf.d test.o --output test.elf -Wl,-Map=test.map,--cref
-lm -Wl,--section-start=.bootloader=0x3800
*/
/*
-------- begin --------
avr-gcc (GCC) 3.4.6
Copyright (C) 2006 Free Software Foundation, Inc.
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024 -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test_il.lst -ID:/Lib/ -std=gnu99 -MD
-MP -MF .dep/test_il.o.d test_il.c -o test_il.o
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=16000000UL
-DBOOTSIZE=1024 -Os -funsigned-char -funsigned-bitfields
-fpack-struct -fshort-enums -fno-strict-aliasing -Wall -Winline
-Wstrict-prototypes -Wa,-adhlns=test_il.o -ID:/Lib/ -std=gnu99 -MD -MP
-MF .dep/test_il.elf.d test_il.o --output test_il.elf
-Wl,-Map=test_il.map,--cref -lm
-Wl,--section-start=.bootloader=0x3800
*/
--
Szikra Istvan
- [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug),
Szikra Istvan <=
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Joerg Wunsch, 2010/03/27
- Message not available
- [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Szikra Istvan, 2010/03/27
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Joerg Wunsch, 2010/03/28
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Szikra Istvan, 2010/03/28
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Erik Christiansen, 2010/03/28
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Joerg Wunsch, 2010/03/29
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Erik Christiansen, 2010/03/29
- Re: [avr-gcc-list] modulo vs. loop (gcc 4.3.x bug), Joerg Wunsch, 2010/03/29