public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug rtl-optimization/59099] New: Erroneous register allocation on 32-bit x86 using regparm
@ 2013-11-13  2:20 ian at airs dot com
  2013-11-13 14:48 ` [Bug rtl-optimization/59099] " hjl.tools at gmail dot com
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: ian at airs dot com @ 2013-11-13  2:20 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 59099
           Summary: Erroneous register allocation on 32-bit x86 using
                    regparm
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ian at airs dot com
                CC: vmakarov at redhat dot com

The appended test case should run without error and return 0.  When I compile
it with  -O2 -fPIC -m32 for 32-bit x86, it crashes at runtime with a
segmentation violation.

The generated code is incorrect.  The loop is entered like this:

    movl    12(%esp), %eax
    leal    4(%esi), %ecx
    movl    %edi, 64(%esp)
    xorl    %esi, %esi
    subl    $1, %eax
    movl    %eax, 20(%esp)
    jmp    .L7


Note that %eax holds a value stored in 20(%esp), which as we will see is used
to terminate the loop.  At .L7 we see this:

.L7:
    movl    4(%esp), %edi
    testl    %edi, %edi
    jne    .L5
    cmpl    %edx, 20(%esp)
    jne    .L5

Note that nothing changes %eax.  Note the comparison with 20(%esp).

At .L5 we see this:

.L5:
    movl    64(%esp), %edi
    movl    (%eax), %eax

Note that we are loading a value from %eax.  But at this point it still holds
the value it was given before the loop, which is a counter, not a pointer.

I have not tried to track down the problem, but superficially it appears that
the register allocator has decided to rematerialize the pointer p from the
register parameter, without realizing that the register has changed since the
start of the function.

This is reduced from code in the libgo library.  The libgo code does not use
regparm, but the function in question is a static function and the optimizers
assign it regparm ((1)).

void (*pfn)(void);

struct s
{
  void** q;
  int h;
  int t;
  int s;
};


void* f (struct s *, struct s *) __attribute__ ((noinline, regparm(1)));

void*
__attribute__ ((regparm(1)))
f (struct s *p, struct s *p2)
{
  void *gp, *gp1;
  int t, h, s, t2, h2, c, i;

  if (p2->h == p2->t)
    return 0;

  (*pfn) ();

  h = p->h;
  t = p->t;
  s = p->s;

  h2 = p2->h;
  t2 = p2->t;

  gp = p2->q[h2++];

  c = (t2 - h2) / 2;
  for (i = 0; i != c; i++)
    {
      if (t == h || (h == 0 && t == s - 1))
    break;
      gp1 = p2->q[h2++];
      p->q[t++] = gp1;
      if (t == s)
    t = 0;
    }

  p2->h = h2;
  return gp;
}

static void fn () { }

int
main()
{
  struct s s1, s2;
  void *q[10];

  pfn = fn;

  s1.q = q;
  s1.h = 0;
  s1.t = 2;
  s1.s = 4;

  s2.q = q;
  s2.h = 0;
  s2.t = 4;
  s2.s = 2;

  f (&s1, &s2);

  return 0;
}


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-11-20  0:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-13  2:20 [Bug rtl-optimization/59099] New: Erroneous register allocation on 32-bit x86 using regparm ian at airs dot com
2013-11-13 14:48 ` [Bug rtl-optimization/59099] " hjl.tools at gmail dot com
2013-11-13 15:50 ` [Bug rtl-optimization/59099] [4.9 Regression] " jamborm at gcc dot gnu.org
2013-11-14 18:24 ` jamborm at gcc dot gnu.org
2013-11-15 17:04 ` jamborm at gcc dot gnu.org
2013-11-19 15:09 ` rguenth at gcc dot gnu.org
2013-11-19 23:11 ` jamborm at gcc dot gnu.org
2013-11-20  0:06 ` ian at airs dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).