View Issue Details

IDProjectCategoryView StatusLast Update
0034998FPCDocumentationpublic2019-02-16 15:20
ReporterAdriaan van OsAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Platformi386OSMac OS XOS Version10.8.5
Product Version3.0.4Product Build 
Target Version3.2.0Fixed in Version3.3.1 
Summary0034998: Wrong alignment for i386
DescriptionThis one really surprises me:

{$align 8}

program MBTestAlignment;

type
  TestRecord =
    record
      b: boolean;
      d: double
    end;

begin
  writeln
    ( 'SizeOf( TestRecord) = ', SizeOf( TestRecord))
end.

This prints 16 on x86_64 but 12 (!) on i386.
TagsNo tags attached.
Fixed in Revision1561
FPCOldBugId0
FPCTarget
Attached Files

Relationships

related to 0034997 new MacPas mode doesn't accept some natural alignment directives 

Activities

Jonas Maebe

2019-02-03 12:43

manager   ~0113814

The natural alignment of double on macOS/i386 is 4: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4

Adriaan van Os

2019-02-03 12:53

developer   ~0113815

The test program species {$align 8}, not {$align normal}

Adriaan van Os

2019-02-03 13:06

developer   ~0113816

Besides, Section 1.2.60 of the FreePascal Programmer's Reference defines "natural alignment" as "the power of two that is equal to or larger than the element’s size."

So, we have different definitions of "natural alignment" here. I would agree to call the Apple-i386 alignment "default" but not "natural".

At least, the documentation should clarify this.

And for {$align 8} the result is clearly wrong.

Jonas Maebe

2019-02-03 13:17

manager   ~0113817

The documentation is wrong. First of all, the compiler always uses the ABI-specified alignment (which you call the default alignment) rather than the natural alignment (although in many cases these match, and at the time that documentation was written they probably always matched because in the very beginning, FPC didn't care at all about ABIs).

Additionally, {$packrecords x}/{$align x} only sets an upper boundary on the field alignment, never a lower boundary. Delphi's documentation is no help here (http://docwiki.embarcadero.com/RADStudio/Rio/en/Align_fields_(Delphi) ), since if you follow it literally then

{$align 8}
type
  trec = record
    a,b,c: byte;
  end;

would be 24 bytes.

There has never been any support for an FPC compiler switch that forces natural alignment, or that otherwise elevated the field alignment to something that is larger than what the ABI specifies for a type.

Jonas Maebe

2019-02-03 13:47

manager   ~0113821

Additionally, in case the ABI does not specify an alignment for a type because it does not exist in C (e.g. a set), then the alignment is currently implementation defined.

E.g. in all currently released versions, sets are aligned naturally (which means a 32 byte set is aligned up to 32 bytes), while in trunk it is limited to the size of the ALUs integer registers.

Adriaan van Os

2019-02-03 14:36

developer   ~0113823

In response to "There has never been any support for an FPC compiler switch that forces natural alignment, or that otherwise elevated the field alignment to something that is larger than what the ABI specifies for a type."

That is very unfortunate, so regard it as a feature request. Alignments "larger than what the ABI specifies for a type" are certainly needed for vector code.

I understand the historical reasons, but don't agree with them.

Adriaan van Os

2019-02-03 14:39

developer   ~0113824

GCC has, according to <https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html>

-malign-double
-mno-align-double
Control whether GCC aligns double, long double, and long long variables on a two-word boundary or a one-word boundary. Aligning double variables on a two-word boundary produces code that runs somewhat faster on a Pentium at the expense of more memory.

On x86-64, -malign-double is enabled by default.

Warning: if you use the -malign-double switch, structures containing the above types are aligned differently than the published application binary interface specifications for the x86-32 and are not binary compatible with structures in code compiled without that switch.

Adriaan van Os

2019-02-03 14:40

developer   ~0113825

GCC also has, according to <https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mno-align-double>

-malign-data=type
Control how GCC aligns variables. Supported values for type are ‘compat’ uses increased alignment value compatible uses GCC 4.8 and earlier, ‘abi’ uses alignment value as specified by the psABI, and ‘cacheline’ uses increased alignment value to match the cache line size. ‘compat’ is the default.

Jonas Maebe

2019-02-03 16:25

manager   ~0113829

> Alignments "larger than what the ABI specifies for a type" are certainly needed for vector code.

We should add vector types for that (or a vector modifier for arrays), rather than requiring people to manually hack this by forcing alignments. The vector alignments in the ABI are already appropriate in that case as well.

Adriaan van Os

2019-02-03 17:25

developer   ~0113830

Specifying an alignment through an alignment directive is not a "hack" but something that the programmer rightly specifies and expects to be obeyed. Vector types or vector modifiers are insufficient, as the alignment may be required by assembly or external code.

Jonas Maebe

2019-02-03 17:32

manager   ~0113832

It is a hack if you have to manually specify an alignment because you want to use vector instructions. Vectors may have different alignment requirements on different platforms, so this should be handled implicitly rather than explicitly.

The ability to manually specify alignments is a separate feature.

Adriaan van Os

2019-02-03 17:45

developer   ~0113834

Last edited: 2019-02-03 17:46

View 2 revisions

So, anything that is platform dependent is a hack ?

Sorry, I find this discussion more than ridiculous. I specify $align 8 and I get $align 4. No reasoning behind that is anything else but absurd.

Jonas Maebe

2019-02-03 18:00

manager   ~0113836

> So, anything that is platform dependent is a hack ?

Sometimes it's necessary, but if it can be avoided in a clean way, all the better.

> I specify $align 8 and I get $align 4.

It's mainly a badly named directive, but for compatibility reasons not much can be done about it. Its origin lies in providing backward compatibility with other (usually older) compilers/platforms that had a lower maximum alignment, hence the behaviour.

Michael Van Canneyt

2019-02-16 15:20

administrator   ~0114181

Adapted the documentation to state that the platform's ABI is used, and removed the references to natural boundaries.

Issue History

Date Modified Username Field Change
2019-02-03 12:39 Adriaan van Os New Issue
2019-02-03 12:43 Jonas Maebe Note Added: 0113814
2019-02-03 12:43 Jonas Maebe Status new => resolved
2019-02-03 12:43 Jonas Maebe Resolution open => no change required
2019-02-03 12:43 Jonas Maebe Assigned To => Jonas Maebe
2019-02-03 12:53 Adriaan van Os Note Added: 0113815
2019-02-03 12:53 Adriaan van Os Status resolved => feedback
2019-02-03 12:53 Adriaan van Os Resolution no change required => reopened
2019-02-03 13:06 Adriaan van Os Note Added: 0113816
2019-02-03 13:06 Adriaan van Os Status feedback => assigned
2019-02-03 13:17 Jonas Maebe Note Added: 0113817
2019-02-03 13:43 Jonas Maebe Relationship added related to 0034997
2019-02-03 13:44 Jonas Maebe Assigned To Jonas Maebe => Michael Van Canneyt
2019-02-03 13:44 Jonas Maebe Category Compiler => Documentation
2019-02-03 13:47 Jonas Maebe Note Added: 0113821
2019-02-03 14:36 Adriaan van Os Note Added: 0113823
2019-02-03 14:39 Adriaan van Os Note Added: 0113824
2019-02-03 14:40 Adriaan van Os Note Added: 0113825
2019-02-03 16:25 Jonas Maebe Note Added: 0113829
2019-02-03 17:25 Adriaan van Os Note Added: 0113830
2019-02-03 17:32 Jonas Maebe Note Added: 0113832
2019-02-03 17:45 Adriaan van Os Note Added: 0113834
2019-02-03 17:46 Adriaan van Os Note Edited: 0113834 View Revisions
2019-02-03 18:00 Jonas Maebe Note Added: 0113836
2019-02-16 15:20 Michael Van Canneyt Fixed in Revision => 1561
2019-02-16 15:20 Michael Van Canneyt Note Added: 0114181
2019-02-16 15:20 Michael Van Canneyt Status assigned => resolved
2019-02-16 15:20 Michael Van Canneyt Fixed in Version => 3.3.1
2019-02-16 15:20 Michael Van Canneyt Resolution reopened => fixed
2019-02-16 15:20 Michael Van Canneyt Target Version => 3.2.0