ARM gcc 4.1 optimization bug.
Hi, I am using gcc4.1 for ARM to build Linux kernel. But there is a bug related to the gcc optimization. I assume this is correct mail list to report this bug. If not, please let me know. And I didn't find the same bug reported too. The kernel is 2.6.14. When I build ALSA subsystem. I use following commandline: arm-iwmmxt-linux-gnueabi-gcc -Wp,-MD,sound/core/.pcm_native.o.d -nostdinc -isystem /usr/local/arm-iwmmxt-linux-gnueabi/bin/../lib/gcc/arm-iwmmxt-linux-gnueabi/4.1.0/include -D__KERNEL__ -Iinclude -include include/linux/autoconf.h -mlittle-endian -gdwarf-2 -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -fno-omit-frame-pointer -fno-optimize-sibling-calls -gdwarf-2 -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=xscale -Wa,-mcpu=xscale -msoft-float -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -gdwarf-2 -DKBUILD_BASENAME=pcm_native -DKBUILD_MODNAME=snd_pcm -Os -c -o sound/core/pcm_native.o sound/core/pcm_native.c And the function is like following (using arm-iwmmxt-linux-gnueabi-objdump -d pcm_nativ.o): 211c : 211c:e1a0c00dmov ip, sp 2120:e92dd8f0stmdb sp!, {r4, r5, r6, r7, fp, ip, lr, pc} 2124:e24cb004sub fp, ip, #4 ; 0x4 2128:e24dd020sub sp, sp, #32 ; 0x20 212c:e5913000ldr r3, [r1] 2130:e51b502cldr r5, [fp, #-44] 2134:e24b603csub r6, fp, #60 ; 0x3c 2138:e1a0c000mov ip, r0 213c:e1a0e006mov lr, r6 2140:e1a04000mov r4, r0 2144:e0055003and r5, r5, r3 2148:e1a07001mov r7, r1 214c:e8bc000fldmia ip!, {r0, r1, r2, r3} 2150:e8ae000fstmia lr!, {r0, r1, r2, r3} 2154:e89c000fldmia ip, {r0, r1, r2, r3} 2158:e5845000str r5, [r4] 215c:e597c004ldr ip, [r7, #4] 2160:e355cmp r5, #0 ; 0x0 2164:e88e000fstmia lr, {r0, r1, r2, r3} 2168:e001300cand r3, r1, ip /* r1 from 2154: e89c000fldmia ip, {r0, r1, r2, r3} Using the wrong value. The r1 from this instruction should be used: 214c: ldmiaip!, {r0, r1, r2, r3} */ 216c:e1a4mov r0, r4 2170:e3a02008mov r2, #8 ; 0x8 2174:e1a01006mov r1, r6 2178:e5843004str r3, [r4, #4] 217c:1a05bne 2198 2180:e353cmp r3, #0 ; 0x0 2184:e3e03015mvn r3, #21 ; 0x15 2188:1a02bne 2198 218c:e1a3mov r0, r3 2190:e24bd01csub sp, fp, #28 ; 0x1c 2194:e89da8f0ldmia sp, {r4, r5, r6, r7, fp, sp, pc} 2198:ebfebl 0 219c:e2503000subsr3, r0, #0 ; 0x0 21a0:13a03001movne r3, #1 ; 0x1 21a4:eaf8b 218c The C code is like following: #define SNDRV_MASK_SIZE 2 struct mask_t { unsigned int bits[8]; }; typedef struct mask_t snd_mask_t; static inline int snd_mask_empty(const snd_mask_t *mask) { int i; for (i = 0; i < SNDRV_MASK_SIZE; i++) { if (mask->bits[i]) return 0; } return 1; } static inline void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v) { int i; for (i = 0; i < SNDRV_MASK_SIZE; i++) mask->bits[i] &= v->bits[i]; } static inline void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v) { *mask = *v; } int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v) { snd_mask_t old; snd_mask_copy(&old, mask); snd_mask_intersect(mask, v); if (snd_mask_empty(mask)) return -1; return !snd_mask_eq(mask, &old); return 1; } When I remove the -O option, the ALSA works OK. the .s file is like following: 0040 : 40:e1a0c00dmov ip, sp 44:e92dd800stmdb sp!, {fp, ip, lr, pc} 48:e24cb004sub fp, ip, #4 ; 0x4 4c:e24dd048sub sp, sp, #72 ; 0x48 50:e50b0048str r0, [fp, #-72] 54:e50b104cstr r1, [fp, #-76] 58:e51b3048
Re: ARM gcc 4.1 optimization bug.
Hi Daniel, I have already reported this bug. The bug number is #27363. I also tried the gcc snapshot 4.1.1-20060421. The bug is not fixed in this version too. Thanks & Regards yfw On 5/1/06, Daniel Jacobowitz <[EMAIL PROTECTED]> wrote: On Sun, Apr 30, 2006 at 11:03:05AM +0800, Fengwei Yin wrote: > Hi, > I am using gcc4.1 for ARM to build Linux kernel. But there is a bug > related to the gcc > optimization. I assume this is correct mail list to report this bug. > If not, please let me know. No, if you have a bug report, please use the bug reporting system. Please see: http://gcc.gnu.org/bugs.html -- Daniel Jacobowitz CodeSourcery
Problem about gcc 4.1 + binutil 2.16.92 + glibc 2.4 + ARM EABI
Hi, When enable the gcc 4.1 with EABI support for ARM, I met such situation about the alignment. Here is my test case: #include #include struct test { char c1; long long n; char c2; }; int my_temp(void) { int i; int j; char str[2]; long long l1; long long l2; char str2; printf("%s:\tj address: 0x%08x, str address:0x%08x\n", __func__, &j, str); printf("%s:\tl1 address:0x%08x, l2 address: 0x%08x\n", __func__, &l1, &l2); printf("%s:\tstr2 address: 0x%08x\n", __func__, &str2); return 0; } main() { struct test t; my_temp(); printf("%s:\ttest.c1 address: 0x%08x\n", __func__, &(t.c1)); printf("%s:\ttest.n address:0x%08x\n", __func__, &(t.n)); printf("%s:\ttest.c2 address: 0x%08x\n", __func__, &(t.c2)); } With the gcc 4.1 + EABI for ARM(build optioni: -mabi=aapcs-linux -O2), I get following output: [EMAIL PROTECTED] /test]#./test.gnu.eabi my_temp:j address: 0xbea85ac0, str address:0xbea85abe my_temp:l1 address: 0xbea85ab0, l2 address: 0xbea85aa8 my_temp:str2 address: 0xbea85aa7 main: test.c1 address:0xbea85ad8 main: test.n address: 0xbea85ae0 main: test.c2 address:0xbea85ae8 With the gcc 3.4.3 without EABI(build option: -O2), I get following output: [EMAIL PROTECTED] /test]#./test.gnu my_temp:j address: 0xbeb69bf8, str address:0xbeb69bf0 my_temp:l1 address: 0xbeb69be8, l2 address: 0xbeb69be0 my_temp:str2 address: 0xbeb69bdf main: test.c1 address:0xbeb69c10 main: test.n address: 0xbeb69c18 main: test.c2 address:0xbeb69c20 Please notice the address of the str and j. there IS NO memory hole between therm when using gcc 3.4.3 and there IS memory hole when using gcc 4.1. My question is: Why there is difference there. And what is the root cause of the difference (EABI or gcc update)? Is there any gcc option to make them align? Thanks & Regards Yin, Fengwei
Re: Problem about gcc 4.1 + binutil 2.16.92 + glibc 2.4 + ARM EABI
Hi Richard, Thanks for your information. I will ask for help on [EMAIL PROTECTED] But I still have question about gcc here: The Local variables layout will impact my development. Consider following C code: my_test() { int i; int j; char c[7]; int *tmp; tmp = (int *) c; *tmp = j; } I don't think the local variables will be in register. So the code "*tmp = j;" cause the align exception in some situation if use the 4.1 toolchain. If I am wrong, please correct me. Thanks a lot. Regards Yin, Fengwei On 5/31/06, Richard Earnshaw <[EMAIL PROTECTED]> wrote: On Wed, 2006-05-31 at 07:58, Fengwei Yin wrote: > int my_temp(void) > { > int i; > int j; > char str[2]; > > Please notice the address of the str and j. there IS NO memory hole > between therm > when using gcc 3.4.3 and there IS memory hole when using gcc 4.1. My question > is: Why there is difference there. And what is the root cause of the > difference (EABI > or gcc update)? Is there any gcc option to make them align? This has nothing to do with the EABI. Local variables are not laid out on the stack in any particular order (and in many cases will never go on the stack since they will live entirely in registers). Please direct any follow-ups to [EMAIL PROTECTED] This is off-topic for this list. R. -- Richard Earnshaw Email: [EMAIL PROTECTED] ARM Ltd Phone: +44 1223 400569 (Direct + VoiceMail) 110 Fulbourn RoadSwitchboard: +44 1223 400400 Cherry HintonFax: +44 1223 400410 Cambridge CB1 9NJWeb: http://www.arm.com/ UK -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.