diff options
author | Reid Kleckner <rnk@google.com> | 2023-06-12 13:50:50 -0700 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2023-06-13 12:54:23 -0700 |
commit | 651e5ae62d29fdb07eb85f75ab7e686b98479f3a (patch) | |
tree | b0943ea0e9cd07a92bc327b54a620e794d0c5179 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | a5cd198181f937417c988e82f50461adb29aef76 (diff) | |
download | llvm-651e5ae62d29fdb07eb85f75ab7e686b98479f3a.zip llvm-651e5ae62d29fdb07eb85f75ab7e686b98479f3a.tar.gz llvm-651e5ae62d29fdb07eb85f75ab7e686b98479f3a.tar.bz2 |
[MS] Fix passing aligned records by value in some cases
It's not exactly clear what the meaning of TypeInfo::AlignRequirement
is, so go directly to the ASTRecordLayout for records and check the
required alignment there. Compare that number with the stack alignment
value of 4.
This fixes cases when the alignment attribute does not appear directly
on the record [1], or when the attribute on the record is underaligned
[2].
[1]: `struct Foo { int __declspec(align(16)) x; };`
[2]: `struct __declspec(align(1)) Bar { int x; };`
Fixes https://llvm.org/pr63257
Differential Revision: https://reviews.llvm.org/D152752
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 3b9cce4..7a23687 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -1893,9 +1893,21 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : nullptr; // Pass over-aligned aggregates on Windows indirectly. This behavior was - // added in MSVC 2015. - if (IsWin32StructABI && TI.isAlignRequired() && TI.Align > 32) - return getIndirectResult(Ty, /*ByVal=*/false, State); + // added in MSVC 2015. Use the required alignment from the record layout, + // since that may be less than the regular type alignment, and types with + // required alignment of less than 4 bytes are not passed indirectly. + if (IsWin32StructABI) { + unsigned AlignInBits = 0; + if (RT) { + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(RT->getDecl()); + AlignInBits = getContext().toBits(Layout.getRequiredAlignment()); + } else if (TI.isAlignRequired()) { + AlignInBits = TI.Align; + } + if (AlignInBits > 32) + return getIndirectResult(Ty, /*ByVal=*/false, State); + } // Expand small (<= 128-bit) record types when we know that the stack layout // of those arguments will match the struct. This is important because the |