bogus reference to unused symbols

Bug #771832 reported by Andrew Stubbs
18
This bug affects 3 people
Affects Status Importance Assigned to Milestone
Linaro GCC
Won't Fix
Low
Michael Collison
gcc
Confirmed
Medium

Bug Description

This code is derived from the kernel. The problem is a link error for a missing symbol, __aeabi_uldivmod, that isn't actually used. Clearly, this is not right!

static void
f (unsigned int a)
{
  unsigned long long __res;
  if (~0ULL % (a / (a & -a)) == 0)
    {
      asm ("": "+&r" (__res));
    }
}

int
g (unsigned int a)
{
  f (a);
}

This gives:

        .global __aeabi_uidiv
        .global __aeabi_uldivmod
        .text
        .align 2
        .global g
        .thumb
        .thumb_func
        .type g, %function
g:
        .fnstart
.LFB1:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        push {lr}
        .save {lr}
        ldr pc, [sp], #4
        .fnend

So, both __aeabi_uidiv and __aeabi_uldivmod are declared global, but neither is
actually used as the code is optimized away.

Revision history for this message
In , Michael Hope (michaelh1) wrote :

Created attachment 24107
Preprocessed source

When compiled, the attached code refers to the 64 bit unsigned divmod helper function '__aeabi_uldivmod' even though the function is never called. This causes a link error when cross-compiling an ARM Linux 2.6.38 kernel.

To reproduce:
 * Make a arm-linux-gnueabi cross compiler configured with --with-mode=thumb --with-arch=armv7-a --with-tune=cortex-a9 --with-float=softfp --with-fpu=neon
 * Compile the attached code with 'arm-linux-gnueabi-gcc -O2 -S wm8974.i'
 * See a '.global __aeabi_uldivmod' in the header of wm8974_set_dai_pll

Marking pll_factors() as noinline or putting asm("" : "+r"(source)); before the call to do_div() works around the problem.

Revision history for this message
In , Andrew Stubbs (ams-codesourcery) wrote :

I don't see any call to __aeabi_uldivmod???

I *do* see __aeabi_uidivmod, and that does seem to be called properly.

I get:

        .global __aeabi_uidiv
        .global __aeabi_uidivmod
        .align 2
        .thumb
        .thumb_func
        .type pll_factors, %function
pll_factors:
        .fnstart
[.....]
.L54:
        ldrb r3, [r6, #0] @ zero_extendqisi2
        mov r0, r7
        mov r1, r4
        bfi r3, r5, #1, #4
        strb r3, [r6, #0]
        bl __aeabi_uidivmod
        movw r5, #52429
        movt r5, 52428
        mov r0, #167772160
        umull r0, r1, r1, r0
[.....]

I can't find a bug here?

Revision history for this message
In , Michael Hope (michaelh1) wrote :

Sorry, the original attachment included the __attribute__((noinline)) workaround on pll_factors(). Attached is the original that shows the fault.

Revision history for this message
In , Michael Hope (michaelh1) wrote :

Created attachment 24111
Preprocessed source

Revision history for this message
In , Andrew Stubbs (ams-codesourcery) wrote :

Somewhat reduced testcase:

static void
f (unsigned int a)
{
  unsigned long long __res;
  if (~0ULL % (a / (a & -a)) == 0)
    {
      asm ("": "+&r" (__res));
    }
}

int
g (unsigned int a)
{
  f (a);
}

This gives:

        .global __aeabi_uidiv
        .global __aeabi_uldivmod
        .text
        .align 2
        .global g
        .thumb
        .thumb_func
        .type g, %function
g:
        .fnstart
.LFB1:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        push {lr}
        .save {lr}
        ldr pc, [sp], #4
        .fnend

So, both __aeabi_uidiv and __aeabi_uldivmod are declared global, but neither is actually used as the code is optimized away.

Changed in gcc:
importance: Unknown → Medium
status: Unknown → New
Michael Hope (michaelh1)
Changed in gcc-linaro:
status: New → Triaged
importance: Undecided → Low
Revision history for this message
In , Ramana-gcc (ramana-gcc) wrote :

IIUC the problem is because we externalize the label before the functions have been deleted.

Based on a quick look at the sources, I *think* this comes from the fact that the default definition of ASM_OUTPUT_EXTERNAL_LIBCALL ends up generating a .globl symname and somehow don't think this is a port specific problem ( which I *think* comes from config/elfos.h )

cheers
Ramana

Changed in gcc:
status: New → Confirmed
Revision history for this message
In , Pinskia (pinskia) wrote :

~0ULL % (a / (a & -a)) == 0
Is not optimized to false on the tree level.

Basically we should figure that out and we would then remove the reference to the uldivmod libcall.

Changed in gcc-linaro:
assignee: nobody → Michael Collison (michael-collison)
Revision history for this message
Michael Collison (michael-collison) wrote :

Will not fix for older releases. Does not occur with new releases asassembler/linker realize the symbol is not used.

Changed in gcc-linaro:
status: Triaged → Won't Fix
Revision history for this message
In , Pinskia (pinskia) wrote :

Note the reduced testcase in comment #4 has been fixed since GCC 5 but I think the original issue is still there ...

Revision history for this message
In , Pinskia (pinskia) wrote :

See also thread starting at https://inbox.<email address hidden>/ .

Revision history for this message
In , Jemarch-f (jemarch-f) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

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