Open Quuxplusone opened 8 years ago
Attached ClangCrashRepro.tgz
(856 bytes, application/x-compressed-tar): Crash repro
This is not stack misalignment, this is a disagreement between clang and GCC
about the alignment of the static data member in your example.
Reduced:
struct S { float myarray[16]; } s;
float useit() { return s.myarray[0]; }
If you emit LLVM IR you can see the low alignment:
$ clang -S -emit-llvm t.cpp -O3 -o - | grep '@s = '
@s = global %struct.S zeroinitializer, align 4
If you remove the wrapper struct around myarray, the alignment goes up to 16.
So, this boils down to two interpretations of the Sys V psABI doc, which has a
special case for global arrays larger than 16 bytes.
ABI doc quote:
http://www.x86-64.org/documentation/abi.pdf
Aggregates and Unions
An array uses the same alignment as its elements, except that a local or global
array variable of length at least 16 bytes or a C99 variable-length array
variable always has alignment of at least 16 bytes.
So, we need clarification about whether this counts as a global array or not.
(In reply to comment #2)
>
> So, we need clarification about whether this counts as a global array or not.
struct S { float myarray[16]; } s;
extern void useit(float []);
void
bar (void)
{
return useit (s.myarray);
}
useit should be passed an array aligned to 16 bytes,
(In reply to comment #3)
> useit should be passed an array aligned to 16 bytes,
Why? Consider this case:
struct S {
int x;
float myarray[16];
} s;
extern void useit(float []);
void bar (void) { return useit (s.myarray); }
Surely we will not change the layout of 'S' to ensure that the second field is
16 byte aligned.
It sounds like you are saying that the alignment of any global should be
increased to 16 if it has a subobject which is an array of floating point
values larger than 16 bytes.
(In reply to comment #4)
> (In reply to comment #3)
> > useit should be passed an array aligned to 16 bytes,
>
> Why? Consider this case:
>
> struct S {
> int x;
> float myarray[16];
> } s;
> extern void useit(float []);
> void bar (void) { return useit (s.myarray); }
>
> Surely we will not change the layout of 'S' to ensure that the second field
> is 16 byte aligned.
Will you do it for
struct S {
int x;
float myarray[16];
} s;
extern void useit(float [16]);
void bar (void) { return useit (s.myarray); }
> It sounds like you are saying that the alignment of any global should be
> increased to 16 if it has a subobject which is an array of floating point
> values larger than 16 bytes.
Yes.
ClangCrashRepro.tgz
(856 bytes, application/x-compressed-tar)