This occurs with a cross compilation from i386-linux to powerpc-elf. The input parameter in r3 gets overwritten by the return value from a function call. This only occurs when optimization is enabled (-O1 or higher). This has something to do with unions and bit fields. A simple test case follows.
foo.c: extern int bar1(void); extern void bar2(int); void foo(char x) { union { int val; struct { unsigned a: 8; } f; } u; u.val = bar1(); u.f.a = x; bar2(u.val); } Here is the assembly: foo: stwu 1,-16(1) mflr 0 stw 0,20(1) bl bar1 rlwimi 3,3,24,0,7 bl bar2 lwz 0,20(1) mtlr 0 addi 1,1,16 blr The input paramter to foo() is passed in r3. r3 is not saved before calling bar1(), and bar1() returns its value in r3, thereby overwriting the input value of r3. But the input value of r3 is required in the next instruction 'rlwimi 3,3,24,0,7'. This works with gcc 3.3.1. It also works with gcc 4.1.2 targetted for mipsisa32-elf. It fails with gcc 4.1.2 targetted for powerpc-elf. My target is an embedded system with no OS. Here is how I build this: $ /usr/local/trpz/trpz4.1/bin/powerpc-elf-gcc -v -save-temps -Wall -c -O -o foo.o foo.c Using built-in specs. Target: powerpc-elf Configured with: ../gcc-4.1.2/configure --prefix=/usr/local/trpz/trpz4.1 --target=powerpc-elf --enable-64-bit-bfd --disable-libssp Thread model: single gcc version 4.1.2 /home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../libexec/gcc/powerpc-elf/4.1.2/cc1 -E -quiet -v -iprefix /home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../lib/gcc/powerpc-elf/4.1.2/ foo.c -Wall -O -fpch-preprocess -o foo.i ignoring nonexistent directory "/home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../lib/gcc/powerpc-elf/4.1.2/../../../../powerpc-elf/sys-include" ignoring nonexistent directory "/home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../lib/gcc/powerpc-elf/4.1.2/../../../../powerpc-elf/include" ignoring duplicate directory "/usr/local/trpz/trpz4.1/lib/gcc/powerpc-elf/4.1.2/include" ignoring nonexistent directory "/usr/local/trpz/trpz4.1/lib/gcc/powerpc-elf/4.1.2/../../../../powerpc-elf/sys-include" ignoring nonexistent directory "/usr/local/trpz/trpz4.1/lib/gcc/powerpc-elf/4.1.2/../../../../powerpc-elf/include" #include "..." search starts here: #include <...> search starts here: /home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../lib/gcc/powerpc-elf/4.1.2/include End of search list. /home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../libexec/gcc/powerpc-elf/4.1.2/cc1 -fpreprocessed foo.i -quiet -dumpbase foo.c -auxbase-strip foo.o -O -Wall -version -o foo.s GNU C version 4.1.2 (powerpc-elf) compiled by GNU C version 3.2 20020903 (Red Hat Linux 8.0 3.2-7). GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=129090 Compiler executable checksum: bd93f7309b7da302bc5e08433888e36b /home/gary/trpz/tools/i386-redhat-linux/trpz4.1/bin/../lib/gcc/powerpc-elf/4.1.2/../../../../powerpc-elf/bin/as -mppc -many -V -Qy -o foo.o foo.s GNU assembler version 2.17 (powerpc-elf) using BFD version 2.17 My host system is: $ uname -por 2.6.20-1.2948.fc6 i686 GNU/Linux -- Summary: Input parameter trashed with optimization -O when using a union and bit field Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gmorain at gmail dot com GCC host triplet: i386-linux-gnu GCC target triplet: powerpc-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31830