This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/37176] New: [arm] Optimizer omits loop condition leading to failing code


My recent 2.6.21.6-rt21 kernel build for ARM dumps a NULL pointer dereference
exception due to a missing loop termination condition that was omitted by the
gcc 4.3.1 optimizer.

This happens in net/ipv4/inet_hashtables.c, in function
inet_lookup_listener_slow which is inlined by the optimizer (-Os, -O2, -O3)
into function inet_lookup_listener:

===== C-Code:
  sk_for_each(sk, node, head) {
       const struct inet_sock *inet = inet_sk(sk);

       if (inet->num == hnum && !ipv6_only_sock(sk)) {
       ...
       }
   }

===== Generated assembler code with my comments:
.L57:
        mov     r4, r0
        ldr     r1, [r4], #-8          @ node = node->next; THIS FAILS !!!
#APP
@ 108 "include/asm/processor.h" 1
        pld     [r1, #0]               @ preload node
@ 0 "" 2
        ldrh    r3, [r4, ip]           @ load 'inet->num' ...
        mov     r0, r1
        cmp     r3, r5                 @ ... and compare this with 'hnum'
        bne     .L57                   @ if 'inet->num != hnum' continue loop
        b       .L58                   @ do the work inside the loop

===== why this code fails:
If you look at sk_for_each macro it is replaced with something like:
for (node=head; node && ...; node=node->next)
Unfortunately the condition for node being non zero is not evaluated every
loop. It seems to me that this important condition is replaces with the inner
if-condition inet->num == hnum whereas node!=0 is evaluated later on.

===== possible workarounds:
Do not use -Os, -O2, -O3. -O1 and -O0 works.

E.g. this is the code for the -O1 case:
.L47:
        mov     r3, r0
        mov     r4, ip
.L50:
        cmp     r2, #0          @ CHECKS node != 0       !!!!!!!
        beq     .L49            @ terminates loop
        mov     r0, r3
        mov     ip, r4
        b       .L51            @ next loop
.L43:
        mvn     r0, #0
        mov     ip, #0
        mov     r3, #516
        add     lr, r3, #2
.L51:
        mov     r4, r2
        ldr     r2, [r4], #-8
#APP
@ 108 "include/asm/processor.h" 1
        pld     [r2, #0]
@ 0 "" 2
        mov     r1, r4
        ldrh    r3, [r4, lr]
        cmp     r3, r5
        bne     .L47
        b       .L54
.L49:

===== Compiler version: 4.3.1 (release version)

===== System type: ARM Linux, XScale-PXA255 (ARMv5-TE)

===== Compiler configure command line:
  $ ../gcc-4.3.1/configure --prefix=/tmp/tc3/sysroot/cross --target=arm-linux
--host=i686-pc-linux-gnu --disable-multilib --with-sysroot=/tmp/tc3/sysroot
--disable-nls --enable-shared --enable-languages=c,c++ --enable-__cxa_atexit
--enable-c99 --enable-threads=posix --with-float=soft

===== Commandline: (generated by kernel makefile hierarchy)
arm-linux-gcc -Wp,-MD,net/ipv4/.inet_hashtables.o.d  -nostdinc -isystem
tmp/tc3/sysroot/cross/lib/gcc/arm-linux/4.3.1/include -D__KERNEL__ -Iinclude 
in
clude include/linux/autoconf.h -mlittle-endian -Wall -Wundef
-Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Os -marm
fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu
-mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=xscale
-Wa,-mcpu=xscale  -msoft-float -Uarm -fno-omit-frame-pointer
-fno-optimize-sibling-calls -fno-stack-protector -Wdeclaration-after-statement
-Wno-pointer-sign   -DFW_VERSION=\"1.1.1-cec0\" -D"KBUILD_STR(s)=\#s"
-D"KBUILD_BASENAME=KBUILD_STR(inet_hashtables)"  -D"KBUILD_MODNAME=KBUILD_STR
(inet_hashtables)" -c -o net/ipv4/inet_hashtables.o net/ipv4/inet_hashtables.c

===== Compiler outputs/warnings: none

===== Attachments: .c, .i and .s files


-- 
           Summary: [arm] Optimizer omits loop condition leading to failing
                    code
           Product: gcc
           Version: 4.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: berndorfer at festo dot at
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: arm-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37176


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]