LLVM IR 对结构内存对齐的有线行为?

Posted

技术标签:

【中文标题】LLVM IR 对结构内存对齐的有线行为?【英文标题】:LLVM IR wired behavior on memory alignment of struct? 【发布时间】:2020-07-30 04:35:16 【问题描述】:

我在 struct(LLVM 10) 的内存对齐方面得到了有线行为,它与我对内存对齐的学习不匹配。

对于以下c++代码:

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;

它会生成像这样的 IR:

%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

我的问题:

    必须%struct.CC 必须添加额外的数据类型([7xi8][3xi8])才能对齐?还有其他对齐结构类型的方法吗? 为什么@cc1 不使用%struct.CC? 为什么@cc1 不为对齐添加额外的数据类型? 为什么在使用storei1 对齐8 而不是4?如果对齐 4 怎么办? 为什么在使用storei2 对齐8 而不是4?

问题太多了,如果有人能回答其中的一些,非常感谢。

【问题讨论】:

如果您需要字节对齐的成员,请使用适当的#pragma 或编译器指令。 【参考方案1】:

几乎所有问题的答案都是相同的:Platform C/C++ ABI。 LLVM(或者更确切地说是clang前端)按照ABI的规定做必要的事情来做结构布局。为此,它可以添加必要的填充,因为结构成员应该具有正确的对齐方式。

【讨论】:

感谢您的回复。我知道原因,我不知道LLVM IR中的确切规则,以便我可以编写正确的IR代码,例如问题1和2。 LLVM IR 中没有“规则”。规则是平台 ABI(在本例中为 C)。因此,您需要为您的目标平台生成每个 C ABI 具有正确布局的 LLVM IR。包括必要的填充和对齐。由于@cc1 是一个初始化器,它基本上复制了它应该遵循 C ABI 的字段,它只是“一袋字段” 我认为我没有清楚地描述我的问题,所以我提出了一个新问题:***.com/questions/63369905/…。

以上是关于LLVM IR 对结构内存对齐的有线行为?的主要内容,如果未能解决你的问题,请参考以下文章

内存字节对齐

内存字节对齐

C语言结构体内存对齐的问题

C语言结构体内存对齐的问题

解析C语言结构体对齐(内存对齐问题)

内存字节对齐