A struct {i8,i64} has size == 12, clang says size 16

I'm creating a struct of `{i8,i64}` and `DataLayout::getTypeAllocSize`
is returning `12`. `getStructLayout` also gives an `4` offset for the
second element.

The native ABI, and clang, for the same type are producing a size of 16,
with an alignment of 8, for the second element.

This is for the system triple "x86_64-linux-gnu"

What could be causing this difference in alignment and how can I fix it?

I'm verifying the native ABI with:

// clang \-emit\-llvm ll\_struct\_arg\.c \-S \-o /dev/tty
\#include <stddef\.h>

typedef struct vpt\_data \{
    \_Bool c;
    long int b;
\} vpt\_data;

int main\(\) \{
    vpt\_data v;
    vpt\_test\(v\);
    auto a = sizeof\(v\);
    auto off = offsetof\(vpt\_data,b\);
\}

16 is stored to `a` and 8 to `off`.

This is because of alignment requirements. The alignment for the 'i64' is 8, so assuming the compiler is required to insert 7 bytes of padding between the first member and the second to ensure that the second 'i64' member is validly aligned.

You can use '__attribute__((packed))' to cause the compiler to remove the padding, and the size will become '9'.

  MartinO

It sounds like your DataLayout may not match clang's for x86_64-linux. What
does it say about the alignment of i64?

The getABITypeAlignment
<http://llvm.org/doxygen/classllvm_1_1DataLayout.html#a43556646ad677cfdcfde2b031fa59173&gt;
function is returning only 4 for an i64, which would explain the
discrepency.

I double-checked my triple again and ensured it's the same one as clang.
That's apparently not enough. What else do I need to adjust to get the
platform default ABI?

I think I see a potential issue. My ExecutionEngine setup may not be
using the same target as my object code emitting, and in this test case
I'm running in the ExecutionEngine. I'll go over this code to ensure
I'm creating the same triple and see if that helps -- I'm assuming it
will, since I can't imagine the exact same triple with clang would
produce a different layout.

What exactly is your alignment settings in your LLVM struct?

Something like this would tell you the alignment of “something”.
const llvm::DataLayout dl(theModule);
size_t size = dl.getPrefTypeAlignment(something);

IIn “my” compiler, I don’t do anything special to align structs, so it’s plausibly your specific data-layout that says that i64 only needs aligning to 32-bits (and clang adjusts it because “it can”, by adding extra padding elements) - or you’re using different targets (or settings for the targets)

I think I've figured it out now. The setup of my triple/datalayout for
the module was apparently not correct. It likely worked mainly to this
point since the default dataLayout is close to the host ABI, but not quite.

I have the following setup, which appears to work:

module = new llvm::Module\( &quot;test&quot;, \*llvm\_context \);
module\-&gt;setTargetTriple\( platform::target\-&gt;triple \);

//x86_64-pc-linux-gnu

std::string err\_str;
auto triple\_str = llvm::Triple::normalize\(platform::target\-&gt;triple\);
llvm::Target const \*  target = llvm::TargetRegistry::lookupTarget\(

triple_str, err_str );
STATE_CHECK( target, err_str ); //assert target != nullptr
auto targetMachine = target->createTargetMachine(triple_str,
"generic", "", llvm::TargetOptions{},
llvm::Optional<llvm::Reloc::Model>());

module\-&gt;setDataLayout\( targetMachine\-&gt;createDataLayout\(\) \);

I'll be testing on Mac later today, but I suspect it has the same data
layout.