www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 231] New: long is 4-byte aligned in unittest with 4 character module name

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=231

           Summary: long is 4-byte aligned in unittest with 4 character
                    module name
           Product: D
           Version: 0.161
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: sean f4.ca


This one is really weird.  It turns out that the value must be used in a
unittest, etc, as per the test case, and the error actually goes away if I
change the module name to be larger than 4 characters.  This is a new bug, as
the test this is derived from used to pass without error:

C:\code\src\d\bugs>type 161x.d
template testStoreIf( T )
{
    void testStoreIf( T val = T.init + 1 )
    {
        T base;
        assert( atomicValueIsProperlyAligned!(T)( cast(size_t) &base ) );
    }
}
import std.c.stdio;

template atomicValueIsProperlyAligned( T )
{
    bool atomicValueIsProperlyAligned( size_t addr )
    {
        printf( "%p %% %u = %u\n", addr, T.sizeof, addr % T.sizeof );
        return addr % T.sizeof == 0;
    }
}


unittest
{
    testStoreIf!(long)();
}


void main()
{

}
C:\code\src\d\bugs>dmd -unittest 161x.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe 161x,,,user32+kernel32/noi;

C:\code\src\d\bugs>161x
0012FEEC % 8 = 4
161x(6): Assertion failure

C:\code\src\d\bugs>copy 161x.d 161_1.d
        1 file(s) copied.

C:\code\src\d\bugs>dmd -unittest 161_1.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe 161_1,,,user32+kernel32/noi;

C:\code\src\d\bugs>161_1
0012FEE8 % 8 = 0

C:\code\src\d\bugs>


-- 
Jun 29 2006
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=231





------- Comment #1 from sean f4.ca  2006-06-29 13:26 -------
I just realized the real problem here is that I'm expecting longs to be 8-byte
aligned on a system with no native 8-byte type.  Perhaps it's just dumb luck
that I've never encountered a long whose address was not 8-byte aligned?  With
that in mind, how does DMD align longs?  And is this portable across compilers?


-- 
Jun 29 2006
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=231





------- Comment #2 from sean f4.ca  2006-06-29 13:38 -------
One last update.  I just noticed that the static data segment is actually
different sizes for the two modules tested above.  The data segment for 161x is
68 bytes and is 72 bytes for 161_1.  It also seems weird that the size of a
module name should affect the stack location of a variable used in a unit test.
 In any case, here are the two data segments.  Notice the additional padding
before __ModuleInfo_5161_1 in the latter case:

168x:

_DATA   segment
        db      025h,070h,020h,025h,025h,020h,025h,075h
        db      020h,03dh,020h,025h,075h,00ah,000h,031h
        db      036h,031h,078h,000h
__ModuleInfo_4161x:
        db      000h,000h,000h,000h
        db      000h,000h,000h,000h,004h,000h,000h,000h
        dd      offset FLAT:_DATA[0Fh]
        db      000h,000h,000h,000h
        dd      offset FLAT:__ModuleInfo_4161x[030h]
        db      000h,000h,000h,000h
        db      000h,000h,000h,000h,000h,000h,000h,000h
        db      000h,000h,000h,000h,000h,000h,000h,000h
        dd      offset FLAT:__modtest_4161x
_DATA   ends

161_1:

_DATA   segment
        db      025h,070h,020h,025h,025h,020h,025h,075h
        db      020h,03dh,020h,025h,075h,00ah,000h,031h
        db      036h,031h,05fh,031h,000h,000h,000h,000h
__ModuleInfo_5161_1:
        db      000h,000h,000h,000h,000h,000h,000h,000h
        db      005h,000h,000h,000h
        dd      offset FLAT:_DATA[0Fh]
        db      000h,000h,000h,000h
        dd      offset FLAT:__ModuleInfo_5161_1[030h]
        db      000h,000h,000h,000h,000h,000h,000h,000h
        db      000h,000h,000h,000h,000h,000h,000h,000h
        db      000h,000h,000h,000h
        dd      offset FLAT:__modtest_5161_1
_DATA   ends


-- 
Jun 29 2006
parent reply BCS <BCS pathlink.com> writes:
The length of the error messages might be making a difference.

"161x(6): Assertion failure"
"161_1(6): Assertion failure"

What was the last version that you tried it with? If it was pre 0.160 
then the change to assert semantics might be causing this.
Jun 29 2006
parent Sean Kelly <sean f4.ca> writes:
BCS wrote:
 The length of the error messages might be making a difference.
 
 "161x(6): Assertion failure"
 "161_1(6): Assertion failure"
 
 What was the last version that you tried it with? If it was pre 0.160 
 then the change to assert semantics might be causing this.

Good idea--it was pre-160. I haven't unit tested this code for a while.
Jun 29 2006
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=231





------- Comment #3 from someidiot earthlink.net  2006-06-29 14:21 -------
Seems like only FP-double has a problem being 32-bit aligned on the x86?


"On Pentium and PentiumPro, double and long double values should be aligned to
an 8 byte boundary (see -malign-double) or suffer significant run time
performance penalties. On Pentium III, the Streaming SIMD Extension (SSE) data
type __m128 suffers similar penalties if it is not 16 byte aligned."


"On the Pentium and subsequent x86 processors, there is a substantial
performance penalty if double-precision variables are not stored 8-byte
aligned; a factor of two or more is not unusual. Unfortunately, the stack (the
place that local variables and subroutine arguments live) is not guaranteed by
the Intel ABI to be 8-byte aligned."


This would suggest 'double' should be correctly aligned on the stack (for
better performance). In particular, a double[] should be correctly aligned (on
the heap also) ?


-- 
Jun 29 2006
parent Sean Kelly <sean f4.ca> writes:
 ------- Comment #3 from someidiot earthlink.net  2006-06-29 14:21 -------
 Seems like only FP-double has a problem being 32-bit aligned on the x86?

For what it's worth, I altered the code to use a double instead of a long and the alignment issue existed there as well.
Jun 29 2006
prev sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=231


bugzilla digitalmars.com changed:

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




------- Comment #4 from bugzilla digitalmars.com  2006-07-08 16:39 -------
Not a bug, since longs only need to be aligned on 4 byte boundaries on a 32 bit
machine.


-- 
Jul 08 2006
next sibling parent Sean Kelly <sean f4.ca> writes:
d-bugmail puremagic.com wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=231
 
 
 bugzilla digitalmars.com changed:
 
            What    |Removed                     |Added
 ----------------------------------------------------------------------------
              Status|NEW                         |RESOLVED
          Resolution|                            |INVALID
 
 
 
 
 ------- Comment #4 from bugzilla digitalmars.com  2006-07-08 16:39 -------
 Not a bug, since longs only need to be aligned on 4 byte boundaries on a 32 bit
 machine.

Thanks. Out of curiosity, does this apply to double as well? I noticed the same issue there. Sean
Jul 08 2006
prev sibling parent reply kris <foo bar.com> writes:
d-bugmail puremagic.com wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=231
 
 
 bugzilla digitalmars.com changed:
 
            What    |Removed                     |Added
 ----------------------------------------------------------------------------
              Status|NEW                         |RESOLVED
          Resolution|                            |INVALID
 
 
 
 
 ------- Comment #4 from bugzilla digitalmars.com  2006-07-08 16:39 -------
 Not a bug, since longs only need to be aligned on 4 byte boundaries on a 32 bit
 machine.
 
 

It's apparently well known that doubles need to be 64-bit aligned on x86 devices. Otherwise, the performance is known to drop by a factor of two or more. I suspect you'd agree that's quite significant? Does D align double on 32bit or 64bit? How about double[] ?
Jul 09 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"kris" <foo bar.com> wrote in message 
news:e8qhlp$2rtk$1 digitaldaemon.com...

 Does D align double on 32bit or 64bit? How about double[] ?

double.alignof is 8 on my 32-bit machine. And if array alignment works like I believe it does, double[] should also be 64-bit aligned.
Jul 09 2006
parent reply kris <foo bar.com> writes:
Jarrett Billingsley wrote:
 "kris" <foo bar.com> wrote in message 
 news:e8qhlp$2rtk$1 digitaldaemon.com...
 
 
Does D align double on 32bit or 64bit? How about double[] ?

double.alignof is 8 on my 32-bit machine. And if array alignment works like I believe it does, double[] should also be 64-bit aligned.

That's good. In reality, does it actually perform double-alignment on 64-bit boundaries?
Jul 09 2006
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"kris" <foo bar.com> wrote in message 
news:e8rul1$1tkj$1 digitaldaemon.com...

 That's good. In reality, does it actually perform double-alignment on 
 64-bit boundaries?

Hmm. Well, simple tests seem to show that memory allocations end up on 128-bit boundaries (hex addresses always end in 0), regardless of the type being allocated. And so do stack (local) variables; I tried putting all kinds of alignments of types in a function, and doubles always end up on 64-bit boundaries.
Jul 09 2006