Thread overview
[Issue 3521] New: Optimized code access popped register
Nov 17, 2009
lifc0@yahoo.com.cn
Nov 23, 2009
Don
Nov 27, 2009
Don
Nov 30, 2009
Walter Bright
Dec 01, 2009
Walter Bright
Dec 06, 2009
Walter Bright
November 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3521

           Summary: Optimized code access popped register
           Product: D
           Version: 1.051
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: lifc0@yahoo.com.cn


--- Comment #0 from lifc0@yahoo.com.cn <lifc0@yahoo.com.cn> 2009-11-16 22:53:09 PST ---
DMD compiler(seems from 1.029) produces bad optimized opcode which access a
popped register.
$cat test.d
class foo {
        uint a, b;
}

void main () {
        foo f = new foo;
        uint c;
        with (f) {
                c = 0;
                b = 0;
                a = 0;
                if (a == b && (a + (c = 66)) <= 66)
                        assert(c == 66);
        }
}

$dmd -O test.d
$./test
Error: AssertError Failure test.d(13)
$objdump -d test.o
  ...
  ...
  25:   53                      push   %ebx
  26:   bb 42 00 00 00          mov    $0x42,%ebx
  2b:   89 d9                   mov    %ebx,%ecx
  2d:   5b                      pop    %ebx        <----------- here
  2e:   8d 14 0b                lea    (%ebx,%ecx,1),%edx
  31:   3b d6                   cmp    %esi,%edx
  33:   77 0f                   ja     44 <_Dmain+0x44>
  35:   83 fb 42                cmp    $0x42,%ebx  <---------- and here
  38:   74 0a                   je     44 <_Dmain+0x44>
  ...
  ...

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


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #1 from Don <clugdbug@yahoo.com.au> 2009-11-23 01:57:30 PST ---
Reduced test case shows that this is very low level. It's very specific, changing the expression order slightly will make the problem go away. The assignment to c gets optimised away, so that it remains as 0.
-------------------------
void bug3521(int *a)
{
    int c = 0;
    *a = 0;
    if (*a == 0 && (*a + (c = 2)) == 2)
        assert(c == 2);
}

void main ()
{
   int x;
   bug3521(&x);
}

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



--- Comment #2 from Don <clugdbug@yahoo.com.au> 2009-11-27 00:15:10 PST ---
I investigated this a bit, so far without success. I'm writing notes here for
when I come back to it.
It's something to do with the register allocation. The compiler is somehow
forgetting that it already assigned a register for c when doing the assignment.
I removed the assert to make disassembly even easier: this hits a breakpoint
only when compiled with -O. It only happens if c is zero. You can change the !=
into any kind of comparison, and the c=200 into c+=200, without affecting the
bug. However, changing it into ((c = 200)!=*a) avoids the bug.

void crash(int x)
{
  if (x==200) return;
   asm { int 3; }
}

void bug3521(int *a){
    int c = 0;
    *a = 0;
    if ( *a || (*a != (c = 200)) )
       crash(c);
}

void main (){
   int x;
   bug3521(&x);
}

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


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2009-11-30 14:16:29 PST ---
I've found the cause of the problem; it's when a registered variable is on both sides of an operator and the right side tries to modify the variable. The fix isn't easy, I'll work on it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 01, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3521



--- Comment #4 from Walter Bright <bugzilla@digitalmars.com> 2009-11-30 17:39:56 PST ---
Fixed changeset 272.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 06, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3521


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #5 from Walter Bright <bugzilla@digitalmars.com> 2009-12-06 00:48:12 PST ---
Fixed dmd 1.053 and 2.037

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------