Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang][AArch64] Fixed incorrect _BitInt alignment #90602

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ struct TransferrableTargetInfo {
unsigned char LongLongWidth, LongLongAlign;
unsigned char Int128Align;

// This is an optional parameter for targets that
// don't use 'LongLongAlign' for '_BitInt' max alignment
std::optional<unsigned> BitIntMaxAlign;

// Fixed point bit widths
unsigned char ShortAccumWidth, ShortAccumAlign;
unsigned char AccumWidth, AccumAlign;
Expand Down Expand Up @@ -518,6 +522,22 @@ class TargetInfo : public TransferrableTargetInfo,
/// getInt128Align() - Returns the alignment of Int128.
unsigned getInt128Align() const { return Int128Align; }

/// getBitIntMaxAlign() - Returns the maximum possible alignment of
/// '_BitInt' and 'unsigned _BitInt'.
unsigned getBitIntMaxAlign() const {
return BitIntMaxAlign.value_or(LongLongAlign);
}

/// getBitIntAlign/Width - Return aligned size of '_BitInt' and
/// 'unsigned _BitInt' for this target, in bits.
unsigned getBitIntWidth(unsigned NumBits) const {
return llvm::alignTo(NumBits, getBitIntAlign(NumBits));
}
unsigned getBitIntAlign(unsigned NumBits) const {
return std::clamp<unsigned>(llvm::PowerOf2Ceil(NumBits), getCharWidth(),
getBitIntMaxAlign());
}

/// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
/// 'unsigned short _Accum' for this target, in bits.
unsigned getShortAccumWidth() const { return ShortAccumWidth; }
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2258,9 +2258,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::BitInt: {
const auto *EIT = cast<BitIntType>(T);
Align = std::clamp<unsigned>(llvm::PowerOf2Ceil(EIT->getNumBits()),
getCharWidth(), Target->getLongLongAlign());
Width = llvm::alignTo(EIT->getNumBits(), Align);
Align = Target->getBitIntAlign(EIT->getNumBits());
Width = Target->getBitIntWidth(EIT->getNumBits());
break;
}
case Type::Record:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
else
LongWidth = LongAlign = PointerWidth = PointerAlign = 32;

BitIntMaxAlign = 128;
MaxVectorAlign = 128;
MaxAtomicInlineWidth = 128;
MaxAtomicPromoteWidth = 128;
Expand Down
64 changes: 63 additions & 1 deletion clang/test/CodeGen/aapcs64-align.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// REQUIRES: arm-registered-target
// RUN: %clang_cc1 -triple aarch64-none-elf \
// RUN: -O2 \
// RUN: -emit-llvm -o - %s | FileCheck %s
// RUN: -emit-llvm -fexperimental-max-bitint-width=1024 -o - %s | FileCheck %s

extern "C" {

Expand Down Expand Up @@ -100,4 +100,66 @@ void f5m(int, int, int, int, int, P16);
// CHECK: declare void @f5(i32 noundef, [2 x i64])
// CHECK: declare void @f5m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [2 x i64])

//BitInt alignment
struct BITINT129 {
char ch;
unsigned _BitInt(129) v;
};

int test_bitint129(){
return __builtin_offsetof(struct BITINT129, v);
}
// CHECK: ret i32 16

struct BITINT127 {
char ch;
_BitInt(127) v;
};

int test_bitint127(){
return __builtin_offsetof(struct BITINT127, v);
}
// CHECK: ret i32 16

struct BITINT63 {
char ch;
_BitInt(63) v;
};

int test_bitint63(){
return __builtin_offsetof(struct BITINT63, v);
}
// CHECK: ret i32 8

struct BITINT32 {
char ch;
unsigned _BitInt(32) v;
};

int test_bitint32(){
return __builtin_offsetof(struct BITINT32, v);
}
// CHECK: ret i32 4

struct BITINT9 {
char ch;
unsigned _BitInt(9) v;
};

int test_bitint9(){
return __builtin_offsetof(struct BITINT9, v);
}
// CHECK: ret i32 2

struct BITINT8 {
char ch;
unsigned _BitInt(8) v;
};

int test_bitint8(){
return __builtin_offsetof(struct BITINT8, v);
}
// CHECK: ret i32 1

}

Loading