0

I get wired behavior on memory alignment of struct(LLVM 10), it doesn't match my learning of memory alignment.

For below c++ code:

struct CC {
  char   c1 = 'a';
  double d1 = 2.0;
  int    i1 = 12;
  bool   b1 = true;
  int    i2 = 13;
  bool   b2 = true;

} cc1;

int main() {
  CC cc2;
}

And it will generate IR like:

%struct.CC = type <{ i8, [7 x i8], double, i32, i8, [3 x i8], i32, i8, [3 x i8] }>

@cc1 = global { i8, double, i32, i8, i32, i8 } { i8 97, double 2.000000e+00, i32 12, i8 1, i32 13, i8 1 }, align 8

define linkonce_odr void @_ZN2CCC2Ev(%struct.CC*) unnamed_addr #1 align 2 {
  %2 = alloca %struct.CC*, align 8
  store %struct.CC* %0, %struct.CC** %2, align 8
  %3 = load %struct.CC*, %struct.CC** %2, align 8
  %4 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 0
  store i8 97, i8* %4, align 8
  %5 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 2
  store double 2.000000e+00, double* %5, align 8
  %6 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 3
  store i32 12, i32* %6, align 8
  %7 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 4
  store i8 1, i8* %7, align 4
  %8 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 6
  store i32 13, i32* %8, align 8
  %9 = getelementptr inbounds %struct.CC, %struct.CC* %3, i32 0, i32 7
  store i8 1, i8* %9, align 4
  ret void
}

My Questions:

  1. Must %struct.CC have to add extra data type([7xi8], [3xi8]) for alignment? Is there another way to align struct type?
  2. Why @cc1 doesn't use %struct.CC?
  3. Why @cc1 doesn't add extra data type for alignment?
  4. Why i1 aligns 8 not 4 while using store? What if aligns 4?
  5. Why i2 aligns 8 not 4 while using store?

Too many questions, very very grateful if anyone can answer some of them.

Lanistor
  • 149
  • 8

1 Answers1

1

The answer to almost all questions is the same: Platform C/C++ ABI. LLVM (or rather clang frontend) does the necessary thing to do the struct layout as prescribed by the ABI. In order to do so it could add necessary padding as struct members should have proper alignments.

Anton Korobeynikov
  • 9,074
  • 25
  • 28
  • Thanks for reply. I know the reason, what i don't know is the exact rule in LLVM IR, so that i can write correct IR code, such as question 1 and 2. – Lanistor Jul 31 '20 at 08:09
  • 1
    there is no "rule" in LLVM IR. The rule is platform ABI (C in this case). So, you'd need to generate LLVM IR that would have correct layout per C ABI for your target platform. Including necessary paddings and alignments. Since `@cc1` is an initializer that basically copies its fields it should adhere to C ABI, it's just "a bag of fields" – Anton Korobeynikov Aug 04 '20 at 09:14
  • I don't think i described my question clearly, so i ask a new question: https://stackoverflow.com/questions/63369905/when-should-add-padding-to-struct-in-llvm-ir-and-when-shouldnt. – Lanistor Aug 12 '20 at 04:46