Drop alignment padding fields in type definitions in LLVM IR

Given the following code:

struct Point<'a> {
    x: i32,
    caption: &'a str,
    y: i32,
}

static mut global_var: Point = Point {
    x: 123,
    y: 344,
    caption: "123",
};

The generated LLVM IR code contains empty arrays, which are believed to be alignment paddings, according to discussions on Reddit: https://www.reddit.com/r/rust/comments/et2i62/why_the_global_variables_in_llvm_ir_is_generated/

%Point = type
{
    [0 x i64],
    { [0 x i8]*, i64 },
    [0 x i32],
    i32,
    [0 x i32],
    i32,
    [0 x i32]
}

Can I avoid those paddings to make some analyses on LLVM IR easier? To my understand, if an LLVM pass can do this job, it should be able to first identify those paddings, and then correctly rewrite the GEP instructions in the LLVM code.

It depends on your analysis, but in general no: it's not possible in every case to identify which instructions would need to be modified to mirror the change in layout.

It would be easier to make the analysis cope with padding, or to make the analysis run on a higher-level intermediate representation (eg. MIR) instead of LLVM IR.

Can I do something like adding a compiler option or parameter to avoid them?

#[repr(packed)] should remove most (all?) padding. But of course, not everything can be #[repr(packed)], so at best this will only delay the need to make your analysis handle cope with padding or run on a higher-level IR.

1 Like