Consider the following C++ example
struct B {
int *b1;
};
struct A : public B {
int a2;
};
int f( A *p) {
return p->a2;
}
The alignment of struct A must be equal to 8 bytes (for most 64-bits platforms). There is a follow llvm-IR for clang-17:
%struct.A = type <{ %struct.B, i32, [4 x i8] }>
%struct.B = type { ptr }
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) uwtable
define dso_local noundef i32 @_Z1fP1A(ptr nocapture noundef readonly %0) local_unnamed_addr #0 {
%2 = getelementptr inbounds %struct.A, ptr %0, i64 0, i32 1
%3 = load i32, ptr %2, align 8, !tbaa !5
ret i32 %3
}
The load instruction has the alignment equals to 8 bytes. But the llvm::StructType A is declared with isPacked() == true. After all
llvm::Module &M;
M.getDataLayout().getStructLayout( T)->getAlignment().value()
gives on later llvm passes only 1 byte. The packed property was set by the following code
void CGRecordLowering::determinePacked(bool NVBaseType) {
...;
// If the non-virtual sub-object is not a multiple of the non-virtual
// sub-object's alignment, it must be packed. We cannot have a packed
// non-virtual sub-object and an unpacked complete object or vise versa.
if (NVSize % NVAlignment)
Packed = true;
...;
when NVSize == 12 and NVAlignment == 8
(llvm-project/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp).
Is there any way to get the real alignment for StructType on the later llvm passes?
UPD. Packed-lowering was added by
commit bb51300970b7623f552560c99f9704b1b1884830
Author: David Majnemer <david.majnemer@gmail.com>
Date: Sun Sep 28 06:39:30 2014 +0000
CodeGen: Don't crash when initializing pointer-to-member fields in bases
Clang uses two types to talk about a C++ class, the
NonVirtualBaseLLVMType and the LLVMType. Previously, we would allow one
of these to be packed and the other not.
This is problematic. If both don't agree on a common subset of fields,
then routines like getLLVMFieldNo will point to the wrong field. Solve
this by copying the 'packed'-ness of the complete type to the
non-virtual subobject. For this to work, we need to take into account
the non-virtual subobject's size and alignment when we are computing the
layout of the complete object.
This fixes PR21089.
llvm-svn: 218577