How to change CLang struct alignment behaviour?

My target implementation has 2 byte (16 bit ints)
For my target implementation I would want that Clang would always use at least 2 byte aligned padding for Structs, which would match the size of an int.

The current situation is that for this struct:

struct AA
{
char n;
char m;
char j;
};

I get it aligned by 1:

%a = alloca %struct.AA, align 1

I would want it to implicitly use 4 bytes instead of 3, (or it be aligned by 2 bytes instead of 1).

If I replace the above struct by this:

struct AA
{
int n;
char m;
};

or this:

struct AA
{
char n;
char m;
char j;
char k
};

I correctly get it aligned by 2:

%a = alloca %struct.AA, align 2

or:

%a = alloca i32, align 2
%tmpcast = bitcast i32* %a to %struct.AA*

In summary, I noticed that Clang will compute struct alignments as an int (2 bytes) if it has one, or if the struct size is already a multiple of 2, but not in other cases.

How do I change that behaviour to get structs always (at least) 2 byte aligned ?

John Lluch

Depending on your target, alignment may be increased by final code generation (IR → native). Did you check final code?

As radical measure you can hack your clang.

Namely, artificially add “Aligned” attr to your structure declaration (which is CXXRecordDecl).
See “handleAlignedAttr” static method. And then “Sema::AddAlignedAttr”. Latter should be called with some fake params, for it’s not user defined.

Or may be you could alter DataLayout for your target somehow.

P.S.: If you’re under C++11 or higher you always can use “alignas” in cpp code.
P.S.2: But the goal is weird. If I got right, you rely on target alignment and then fullfill gaps between structures with some data?

Stepan Dyatkovskiy

This has been tracked down to a bug in LLVM FindOptimalMemOpLowering function that affects all targets not supporting misaligned memory accesses (such as MSP430 and mips16)

The entire discussion starts here:

http://lists.llvm.org/pipermail/llvm-dev/2019-May/132349.html

John Lluch