Jump to page: 1 2
Thread overview
[Issue 6189] New: register content destroyed in function prolog
Jun 21, 2011
dawg@dawgfoto.de
Jun 21, 2011
dawg@dawgfoto.de
Aug 29, 2011
dawg@dawgfoto.de
Aug 29, 2011
dawg@dawgfoto.de
Aug 29, 2011
dawg@dawgfoto.de
Nov 22, 2011
dawg@dawgfoto.de
Jan 13, 2012
dawg@dawgfoto.de
Jan 13, 2012
dawg@dawgfoto.de
[Issue 6189] [64bit] optimizer: vector register content destroyed in function prolog
May 21, 2012
Don
[Issue 6189] [64bit] optimizer: register content destroyed in function prolog
May 21, 2012
Don
May 21, 2012
Don
May 22, 2012
Leandro Lucarella
May 22, 2012
Leandro Lucarella
May 22, 2012
dawg@dawgfoto.de
May 23, 2012
Walter Bright
June 21, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189

           Summary: register content destroyed in function prolog
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: All
            Status: NEW
          Keywords: wrong-code
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: dawg@dawgfoto.de


--- Comment #0 from dawg@dawgfoto.de 2011-06-21 05:52:01 PDT ---
struct FPoint {
  float x, y;
}

void constructBezier(FPoint p0, FPoint p1, FPoint p2, ref FPoint[3] quad) {
  quad[0] = p0;
  quad[1] = FPoint(p1.x, p1.y);
  quad[$-1] = p2;
}

void main() {
  auto p0 = FPoint(0, 0);
  auto p1 = FPoint(1, 1);
  auto p2 = FPoint(2, 2);

  // avoid inline of call
  FPoint[3] quad;
  auto f = &constructBezier;
  f(p0, p1, p2, quad);

  assert(quad == [p0, p1, p2]);
}

---

This code will fail if compiled with optimization.
The issue is that quad variable is assigned to a register during the function.
In the function prolog quad is move from it's parameter register to the target
register while another parameter still resides in that register.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 21, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #1 from dawg@dawgfoto.de 2011-06-21 11:08:30 PDT ---
*** Issue 6042 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 29, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #2 from dawg@dawgfoto.de 2011-08-29 09:56:49 PDT ---
I've further dissected this bug.

Chain of infection.
- p1 (passed in RDX) is marked as being not register candidate
  because it is used in an OPrelconst (probably p1.x/p1.y)
- => Symbol for p1 doesn't get a live range
- => blcodgen doesn't mark regcon.used for RDX because parameter isn't marked
     alive in entry block

  if (s->Sclass & SCfastpar &&
      regcon.params & mask[s->Spreg] &&
      vec_testbit(dfoidx,s->Srange))
  {
      regcon.used |= mask[s->Spreg];
  }

- => cgreg_assign for quad figures DX is a neat register to assign quad to
     (passed in RDI)
- => nobody is responsible for saving fastpars and the function prolog creates
     a mov RDX, RDI before RDX is saved

There are two things involved which work suboptimal for the ABI64 conventions.

I. The current way of marking a fastpar register as being used effectively
prevents cgreg_assign to leave them in this register.
II. With the 32 LinkD ABI there was only one register parameter. So moving it
in the function prolog couldn't conflict with other parameters.

Both of them can be improved but still they won't guarantee a proper fix for this bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 29, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #3 from dawg@dawgfoto.de 2011-08-29 10:02:49 PDT ---
That is you can not have working prolog code if parameter register locations and function register locations are crossing each other without temporary storage, e.g. swap(RDI, RSI).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 29, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #4 from dawg@dawgfoto.de 2011-08-29 10:31:41 PDT ---
Rough sketch of improvements.

I.  cgreg_assign/cgreg_benefit (cgreg.c)
When doing register benefit calculation, add block weights for the fastpar
register if the symbol is still contained in it. Decrease benefit by -1 for
other registers.

II. prolog (cod3.c)
Strictly sort parameter movings in the following order.
Register to stack, Register to register, Stack to register.
Keep track of used registers and add an assertion that moving to a register
is not conflicting.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #5 from dawg@dawgfoto.de 2011-11-22 12:53:46 PST ---
This test case doesn't reproduce the bug since xmmregs
are used for floating point.
Disabling fpxmmregs still reproduces the bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 13, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #6 from dawg@dawgfoto.de 2012-01-13 04:43:54 PST ---
struct Point(T)
{
    T x, y;
}
alias Point!int IPoint;
alias Point!float FPoint;

void calcCoeffs(uint half, IPoint pos, ref FPoint[2] pts, uint=0)
{
    pos.x &= ~(half - 1);
    pos.y &= ~(half - 1);
    immutable float xo = pos.x;
    immutable float yo = pos.y;

    pts[0].x -= xo;
    pts[0].y -= yo;
    pts[1].x -= xo;
    pts[1].y -= yo;
}

void main()
{
    auto pos = IPoint(2, 2);
    FPoint[2] pts;
    pts[0] = pts[1] = FPoint(3, 3);
    auto f = &calcCoeffs;
    f(2, pos, pts);

    assert(pts[0].x == 1);
    assert(pts[0].y == 1);
    assert(pts[1].x == 1);
    assert(pts[1].y == 1);
}

----

This one happens with xmmregs too.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 13, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #7 from dawg@dawgfoto.de 2012-01-13 04:45:03 PST ---
https://github.com/D-Programming-Language/dmd/pull/521

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6189


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au
            Version|D2                          |D1 & D2
            Summary|register content destroyed  |[64bit] optimizer: vector
                   |in function prolog          |register content destroyed
                   |                            |in function prolog
           Severity|major                       |critical


--- Comment #8 from Don <clugdbug@yahoo.com.au> 2012-05-21 04:33:14 PDT ---
Modified test case applies to D1 as well. I hoped this was a duplicate of bug 8095 or 8060, but it isn't.

struct Point(T)
{
    T x, y;
}
alias Point!(int) IPoint;
alias Point!(float) FPoint;

void calcCoeffs(uint half, IPoint pos, FPoint[2] *pts, uint q)
{
    pos.x &= ~(half - 1);
    pos.y &= ~(half - 1);
    float xo = pos.x;
    float yo = pos.y;

    (*pts)[0].x -= xo;
    (*pts)[0].y -= yo;
    (*pts)[1].x -= xo;
    (*pts)[1].y -= yo;
}

void main()
{
    auto pos = IPoint(2, 2);
    FPoint[2] pts;
    pts[0] = pts[1] = FPoint(3, 3);
    auto f = &calcCoeffs;
    f(2, pos, &pts, 0);

    assert(pts[0].x == 1);
    assert(pts[0].y == 1);
    assert(pts[1].x == 1);
    assert(pts[1].y == 1);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 21, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6189



--- Comment #9 from Don <clugdbug@yahoo.com.au> 2012-05-21 06:14:16 PDT ---
Reduced test case (compile with -m64 -O):

void bug6189(int half, int[2] pos, float[3] *pts, int unused)
{
    pos[0] += half;

    (*pts)[0] = pos[0];
    (*pts)[1] = pos[1];
    (*pts)[2] = half;
}

void main()
{
    int[2] pos = [2,2];
    float[3] pts = [0.0, 0.0, 0.0];
    bug6189(0, pos, &pts, 0);
    assert(pts[0] == 2);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2