Re: Crash when cross compiling for ARM with GCC-8-2-0 and -ftree-loop-distribute-patterns

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 18/10/2019 09:53, Josef Wolf wrote:
Thanks for your help, Richard!

On Thu, Oct 17, 2019 at 03:55:31PM +0100, Richard Earnshaw (lists) wrote:
On 17/10/2019 15:04, Josef Wolf wrote:
On Thu, Oct 17, 2019 at 02:37:11PM +0200, Matthias Pfaller wrote:
Why is the stack pointer so low at this point of execution? Using
0x20018000-0x20017d20 == 0x2e0 bytes of stack seems a little excessive
for just one call.

Ah!... Looks like you've spotted the problem! Actually, the SP is decremented
on every cycle of the loop:

   (gdb) disass
   Dump of assembler code for function memset:
      0x08001008 <+0>:    push {r4, lr}
      0x0800100a <+2>:    mov  r4, r0
      0x0800100c <+4>:    cbz  r2, 0x8001014 <memset+12>
   => 0x0800100e <+6>:    uxtb r1, r1
      0x08001010 <+8>:    bl   0x8001008 <memset>
      0x08001014 <+12>:   mov  r0, r4
      0x08001016 <+14>:   pop  {r4, pc}
   End of assembler dump.

This looks REALLY suspicous to me. Every cycle of the loop in memset() is
pushing something onto the stack?!?

Without the  -ftree-loop-distribute-patterns option, the memset() function
looks entirely different:

          cbz    r2, <memset+18>
          add    r2, r0
          subs   r2, #1
          uxtb   r1, r1
          subs   r3, r0, #1
   <+10>: strb.w r1, [r3, #1]!
          cmp    r3, r2
          bne.n  <memset+10>
   <+18>: bx     lr

The compiler has spotted that you've written something that acts like memset
and optimized it into a function call to memset.  So now you're recursing to
oblivion.  Try adding -fno-builtin-memset to your compile options.

This sounds reasonable, and I was actually thinking it would solve the
problem.

Unfortunately, -fno-built-memset doesn't have any effect. The same code is
generated.


Ah, yes. Looking at some libc sources it puts an explicit optimization attribute onto the memset (and similar mem... functions) to disable -ftree-loop-distribute-patterns for such functions. So something like

void *
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
memset (void *s, int c, size_t n)
{
  int i;
  for (i=0; i<n; i++)
    ((char *)s)[i] = c;

  return s;
}

Though, of course, it's wrapped up in a macro to make it look a bit prettier ;-)

This is just one of those gotchas that you have to be aware of when implementing the standard library.

R.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux