From dfb8a9de874f233c9d3964569f3d5201fd717c16 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Tue, 30 Apr 2024 12:46:48 +0000 Subject: [PATCH 1/4] [Clang][AArch64] Fixed incorrect _BitInt alignment --- clang/include/clang/Basic/TargetInfo.h | 8 ++++ clang/lib/AST/ASTContext.cpp | 5 +- clang/lib/Basic/Targets/AArch64.cpp | 6 ++- clang/lib/Basic/Targets/AArch64.h | 3 ++ clang/test/CodeGen/aapcs64-align.cpp | 64 +++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 3ced2e7397a75..1b5efa488b6de 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -518,6 +518,14 @@ class TargetInfo : public TransferrableTargetInfo, /// getInt128Align() - Returns the alignment of Int128. unsigned getInt128Align() const { return Int128Align; } + /// 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));} + virtual unsigned getBitIntAlign(unsigned NumBits) const { + return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), + getLongLongAlign());} + /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and /// 'unsigned short _Accum' for this target, in bits. unsigned getShortAccumWidth() const { return ShortAccumWidth; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index cbf4932aff9a6..f440af50e08a4 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2263,9 +2263,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { } case Type::BitInt: { const auto *EIT = cast(T); - Align = std::clamp(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: diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index c8d243a8fb7ae..9a6c197ff77b5 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1473,6 +1473,10 @@ bool AArch64TargetInfo::validatePointerAuthKey( bool AArch64TargetInfo::hasInt128Type() const { return true; } +unsigned AArch64TargetInfo::getBitIntAlign(unsigned NumBits) const{ + return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), + getInt128Align());} + AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : AArch64TargetInfo(Triple, Opts) {} @@ -1674,4 +1678,4 @@ void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__RENDERSCRIPT__"); AArch64leTargetInfo::getTargetDefines(Opts, Builder); -} +} \ No newline at end of file diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 12fb50286f751..d8cdc814b2a9a 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -202,6 +202,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool hasBitIntType() const override { return true; } bool validateTarget(DiagnosticsEngine &Diags) const override; + + unsigned getBitIntAlign(unsigned NumBits) const override; + }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { diff --git a/clang/test/CodeGen/aapcs64-align.cpp b/clang/test/CodeGen/aapcs64-align.cpp index de231f2123b97..7a8151022852e 100644 --- a/clang/test/CodeGen/aapcs64-align.cpp +++ b/clang/test/CodeGen/aapcs64-align.cpp @@ -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" { @@ -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 + +} + From 908693b105980253eadb10b18f8b4c0d52f73415 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Tue, 30 Apr 2024 13:02:05 +0000 Subject: [PATCH 2/4] Fix formatting --- clang/include/clang/Basic/TargetInfo.h | 10 ++++++---- clang/lib/Basic/Targets/AArch64.cpp | 7 ++++--- clang/lib/Basic/Targets/AArch64.h | 1 - 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 1b5efa488b6de..488b166a95af7 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -518,13 +518,15 @@ class TargetInfo : public TransferrableTargetInfo, /// getInt128Align() - Returns the alignment of Int128. unsigned getInt128Align() const { return Int128Align; } - /// getBitIntAlign/Width - Return aligned size of '_BitInt' and + /// 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));} + return llvm::alignTo(NumBits, getBitIntAlign(NumBits)); + } virtual unsigned getBitIntAlign(unsigned NumBits) const { - return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), - getLongLongAlign());} + return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), + getLongLongAlign()); + } /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and /// 'unsigned short _Accum' for this target, in bits. diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 9a6c197ff77b5..cc0ae0e2856fd 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1473,9 +1473,10 @@ bool AArch64TargetInfo::validatePointerAuthKey( bool AArch64TargetInfo::hasInt128Type() const { return true; } -unsigned AArch64TargetInfo::getBitIntAlign(unsigned NumBits) const{ - return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), - getInt128Align());} +unsigned AArch64TargetInfo::getBitIntAlign(unsigned NumBits) const { + return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), + getInt128Align()); +} AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index d8cdc814b2a9a..be6435007a600 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -204,7 +204,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool validateTarget(DiagnosticsEngine &Diags) const override; unsigned getBitIntAlign(unsigned NumBits) const override; - }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { From e82b8a78269f28c513d46cef8f18842191aebcb7 Mon Sep 17 00:00:00 2001 From: Marian Lukac Date: Wed, 8 May 2024 14:47:06 +0000 Subject: [PATCH 3/4] add optional BitIntMaxAlign parameter to TargetInfo --- clang/include/clang/Basic/TargetInfo.h | 14 ++++++++++++-- clang/lib/Basic/Targets/AArch64.cpp | 6 +----- clang/lib/Basic/Targets/AArch64.h | 2 -- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 488b166a95af7..8a6511b9ced83 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -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 BitIntMaxAlign; + // Fixed point bit widths unsigned char ShortAccumWidth, ShortAccumAlign; unsigned char AccumWidth, AccumAlign; @@ -518,14 +522,20 @@ 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)); } - virtual unsigned getBitIntAlign(unsigned NumBits) const { + unsigned getBitIntAlign(unsigned NumBits) const { return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), - getLongLongAlign()); + getBitIntMaxAlign()); } /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index cc0ae0e2856fd..00c5180f70b58 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -154,6 +154,7 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, else LongWidth = LongAlign = PointerWidth = PointerAlign = 32; + BitIntMaxAlign = 128; MaxVectorAlign = 128; MaxAtomicInlineWidth = 128; MaxAtomicPromoteWidth = 128; @@ -1473,11 +1474,6 @@ bool AArch64TargetInfo::validatePointerAuthKey( bool AArch64TargetInfo::hasInt128Type() const { return true; } -unsigned AArch64TargetInfo::getBitIntAlign(unsigned NumBits) const { - return std::clamp(llvm::PowerOf2Ceil(NumBits), getCharWidth(), - getInt128Align()); -} - AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : AArch64TargetInfo(Triple, Opts) {} diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index be6435007a600..12fb50286f751 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -202,8 +202,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool hasBitIntType() const override { return true; } bool validateTarget(DiagnosticsEngine &Diags) const override; - - unsigned getBitIntAlign(unsigned NumBits) const override; }; class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo { From 22db03bbfba9a340dc6166db5c8fcd7e23b36fcc Mon Sep 17 00:00:00 2001 From: Lukacma Date: Wed, 8 May 2024 16:01:40 +0100 Subject: [PATCH 4/4] Update AArch64.cpp --- clang/lib/Basic/Targets/AArch64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 00c5180f70b58..c14f705cb430b 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -1675,4 +1675,4 @@ void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__RENDERSCRIPT__"); AArch64leTargetInfo::getTargetDefines(Opts, Builder); -} \ No newline at end of file +}