Bug creation and email sending has been disabled, file new bugs at gcc.gnu.org/bugzilla
Bug 33 - Illegal instruction reordering with O2
Summary: Illegal instruction reordering with O2
Status: RESOLVED WORKSFORME
Alias: None
Product: GDC
Classification: Unclassified
Component: gdc (show other bugs)
Version: development
Hardware: x86_64 Linux
: --- major
Assignee: Iain Buclaw
URL:
Depends on:
Blocks:
 
Reported: 2012-12-31 10:47 CET by Johannes Pfau
Modified: 2013-03-15 21:27 CET (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Pfau 2012-12-31 10:47:17 CET
I'm not totally sure if my conclusion is right, but this is a strange bug:

Testcase: (fails with -O2, ok without)
----------
import std.typecons;

void main()
{
    class A { int x = 1; }
    auto a1 = scoped!A();
    assert(a1.x == 1);
}
----------

Testcase2: (OK with -O2)
----------
import std.typecons, std.stdio;

void main()
{
    class A { int x = 1; }
    auto a1 = scoped!A();
    writeln();
    assert(a1.x == 1);
}
----------

Disassembler for failing test:
----------
   0x0000000000cd9960 <+0>:	push   %rbp
   0x0000000000cd9961 <+1>:	push   %rbx
   0x0000000000cd9962 <+2>:	sub    $0x98,%rsp
   0x0000000000cd9969 <+9>:	mov    %rsp,%rdi
   0x0000000000cd996c <+12>:	lea    0x30(%rsp),%rbx
   0x0000000000cd9971 <+17>:	callq  0xce89b0 <_D3std8typecons45__T6scopedTC3std8typecons12__unittest41FZv1AZ6scopedFZS3std8typecons45__T6scopedTC3std8typecons12__unittest41FZv1AZ6scoped45__T6ScopedTC3std8typecons12__unittest41FZv1AZ6Scoped>
   0x0000000000cd9976 <+22>:	mov    (%rsp),%rax
=> 0x0000000000cd997a <+26>:	cmpl   $0x1,0x10(%rbx)
----------

Disassembler for working test:
----------
   0x0000000000cd9970 <+0>:	push   %r12
   0x0000000000cd9972 <+2>:	push   %rbp
   0x0000000000cd9973 <+3>:	push   %rbx
   0x0000000000cd9974 <+4>:	sub    $0x90,%rsp
   0x0000000000cd997b <+11>:	mov    %rsp,%rdi
   0x0000000000cd997e <+14>:	lea    0x30(%rsp),%rbp
   0x0000000000cd9983 <+19>:	callq  0xce89d0 <_D3std8typecons45__T6scopedTC3std8typecons12__unittest41FZv1AZ6scopedFZS3std8typecons45__T6scopedTC3std8typecons12__unittest41FZv1AZ6scoped45__T6ScopedTC3std8typecons12__unittest41FZv1AZ6Scoped>
   0x0000000000cd9988 <+24>:	mov    (%rsp),%rax
   0x0000000000cd998c <+28>:	mov    %rax,0x30(%rsp)
   0x0000000000cd9991 <+33>:	mov    0x8(%rsp),%rax
   0x0000000000cd9996 <+38>:	mov    %rax,0x38(%rsp)
   0x0000000000cd999b <+43>:	mov    0x10(%rsp),%rax
   0x0000000000cd99a0 <+48>:	mov    %rax,0x40(%rsp)
   0x0000000000cd99a5 <+53>:	mov    0x18(%rsp),%rax
   0x0000000000cd99aa <+58>:	mov    %rax,0x48(%rsp)
   0x0000000000cd99af <+63>:	mov    0x20(%rsp),%rax
   0x0000000000cd99b4 <+68>:	mov    %rax,0x50(%rsp)
   0x0000000000cd99b9 <+73>:	callq  0xa15ba0 <_D3std5stdio12__T7writelnZ7writelnFZv>
   0x0000000000cd99be <+78>:	lea    0x30(%rsp),%rbp
=> 0x0000000000cd99c3 <+83>:	cmpl   $0x1,0x10(%rbp)
----------

The <...Scoped> functions are identical.

Now my x86 asm understanding is pretty bad, but what looks odd to me is that in the working example "lea    0x30(%rsp),%rbp" is called after calling the <...Scoped> helper function but in the not working example "lea    0x30(%rsp),%rbx" is called before calling the function. And rbx is supposed to contain the pointer to the payload, which can only be obtained by calling <...Scoped>. It seems the compiler moved the lea instruction for some reason.

Tested with:
GDC rev 102ab270
gcc-4.8-20121021
Comment 1 Iain Buclaw 2013-03-15 21:27:52 CET
CNR on current head.