Broken branch code for simple condition (conditional code always executed!)

Bug #1209171 reported by Rafał Miłecki
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Invalid
Undecided
Unassigned

Bug Description

I've created minimal test-case based on my original code, it looks like that:
writel(0x2, &offsets[0]);
if (rev == 0x4) {
 writel(0x8, &offsets[16]);
}

When using Linaro gcc with -Os I get a bugged object. The second "writel" is always executed, not just for (rev == 0x4) and it's first argument is calculated in some weird way.

I incorrectly reported this problem to gcc team yesterday:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58092
but it has appeared to be Linaro-specific bug, it doesn't happen with original gcc.

I noticed this when using OpenWrt, so to make sure it's also present in original Linaro gcc I compiled it on my own (gcc-linaro-4.6-2012.12.tar.bz2) with binutils-2.22.tar.bz2. Disassembled version of test.o looks like this:
   0: 24020002 li v0,2
   4: 24030004 li v1,4
   8: aca20000 sw v0,0(a1)
   c: 10830002 beq a0,v1,18 <test+0x18>
  10: 24020008 li v0,8
  14: 8ca20040 lw v0,64(a1)
  18: aca20040 sw v0,64(a1)
  1c: 03e00008 jr ra
  20: 00000000 nop
As you can see, instruction at offset 0x18 is always executed. This is wrong.

I also compiled original gcc (gcc-4.6.4.tar.bz2) with the same binutils (binutils-2.22.tar.bz2) and disassembled test.o looks like that:
00000000 <test>:
   0: 24020002 li v0,2
   4: aca20000 sw v0,0(a1)
   8: 24020004 li v0,4
   c: 14820002 bne a0,v0,18 <test+0x18>
  10: 24020008 li v0,8
  14: aca20040 sw v0,64(a1)
  18: 03e00008 jr ra
  1c: 00000000 nop
This is exactly what I expected. After first writel (instruction at offset 0x4) a0 is compared with v0 (which contains 0x4). In case they are not equal (a0 != 4) code jumps to 0x18, which is a simple function return.

Revision history for this message
Rafał Miłecki (zajec5) wrote :
Revision history for this message
Rafał Miłecki (zajec5) wrote :

I'm attaching test.o compiled with mipsel-linaro-linux-gnu-gcc. This gcc comes from gcc-linaro-4.6-2012.12.tar.bz2.

Revision history for this message
Rafał Miłecki (zajec5) wrote :

I compile test.o using following command:

XXX-gcc \
-I arch/mips/include \
-I arch/mips/include/generated \
-I arch/mips/include/asm/mach-bcm47xx \
-I arch/mips/include/asm/mach-generic \
-I include \
-include include/linux/kconfig.h \
-D__KERNEL__ -DMODULE \
-Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror-implicit-function-declaration -Wno-format-security -Wframe-larger-than=1024 -Wno-unused-but-set-variable -Wdeclaration-after-statement -Wno-pointer-sign \
-fno-strict-aliasing -fno-common -fno-delete-null-pointer-checks -fno-caller-saves -fno-stack-protector -fno-pic -pipe -fomit-frame-pointer -femit-struct-debug-baseonly -fno-strict-overflow -fconserve-stack \
-mno-check-zero-division -mno-abicalls -mno-branch-likely -msoft-float -mno-long-calls -ffreestanding -mabi=32 -march=mips32 -Wa,-mips32 -Wa,--trap \
-D CC_HAVE_ASM_GOTO \
-Os \
-c -o test.o test.c

Revision history for this message
Rafał Miłecki (zajec5) wrote :

I decided to test the latest version and it seems to be fixed! There is some summary:
gcc-linaro-4.6-2012.10.tar.bz2 BAD
gcc-linaro-4.6-2012.12.tar.bz2 BAD
gcc-linaro-4.6-2013.05.tar.bz2 GOOD
gcc-linaro-4.7-2012.11.tar.bz2 GOOD
gcc-linaro-4.8-2013.07-1.tar.xz GOOD

So I think we can only blame OpenWrt for not updating their Lnaro gcc :|

Revision history for this message
Rafał Miłecki (zajec5) wrote :

After noticing gcc-linaro-4.6-2012.12 is bugged and gcc-linaro-4.6-2013.05 if this-bug-free, I decided to test gcc.

I has appeared that gcc 4.6.3 has this bug while 4.6.4 doesn't. So we just suffered from gcc bug.

Revision history for this message
Rafał Miłecki (zajec5) wrote :

I really don't understand this Launchpad interface... can someone close it for me? :)

Milo Casagrande (milo)
Changed in gcc-linaro:
status: New → Invalid
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.