Bug 231 – long is 4-byte aligned in unittest with 4 character module name
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2006-06-29T13:17:00Z
Last change time
2014-02-15T13:20:12Z
Keywords
wrong-code
Assigned to
bugzilla
Creator
sean
Comments
Comment #0 by sean — 2006-06-29T13:17:53Z
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>
Comment #1 by sean — 2006-06-29T13:26:56Z
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?
Comment #2 by sean — 2006-06-29T13:38:28Z
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
Comment #3 by someidiot — 2006-06-29T14:21:54Z
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) ?
Comment #4 by bugzilla — 2006-07-08T16:39:01Z
Not a bug, since longs only need to be aligned on 4 byte boundaries on a 32 bit machine.