Author: Adam Smith Date: 2026-08-07T14:46:57-05:00 New Revision: c99056ed036c1ae7ff8d78d7fe4bc9a1f887c902
URL: https://github.com/llvm/llvm-project/commit/c99056ed036c1ae7ff8d78d7fe4bc9a1f887c902 DIFF: https://github.com/llvm/llvm-project/commit/c99056ed036c1ae7ff8d78d7fe4bc9a1f887c902.diff LOG: [CIR] Fix vector ABI alignment units and rounding (#214783) `cir::VectorType::getABIAlignment` returned `NextPowerOf2` of the type's size in bits, but the hook answers in bytes, and `NextPowerOf2` is strictly greater so it doubles a size that is already a power of two. A one-element vector of double reported 128 where its alignment is 8. Convert the size to bytes and round up with `PowerOf2Ceil`, which leaves an exact power of two alone. This matches how `llvm::DataLayout` aligns a vector that has no explicit layout entry. Assisted-by: Cursor / claude-opus-5 Added: clang/unittests/CIR/VectorTypeABIAlignTest.cpp Modified: clang/lib/CIR/Dialect/IR/CIRTypes.cpp clang/unittests/CIR/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index c2a3b3cb17b9e..af1bbdcd64fea 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -1279,7 +1279,9 @@ llvm::TypeSize cir::VectorType::getTypeSizeInBits( uint64_t cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout, ::mlir::DataLayoutEntryListRef params) const { - return llvm::NextPowerOf2(dataLayout.getTypeSizeInBits(*this)); + // This hook answers in bytes, not bits. + return llvm::PowerOf2Ceil( + llvm::divideCeil(dataLayout.getTypeSizeInBits(*this), 8u)); } mlir::LogicalResult cir::VectorType::verify( diff --git a/clang/unittests/CIR/CMakeLists.txt b/clang/unittests/CIR/CMakeLists.txt index fb1eea661b065..f31b8d210f4f7 100644 --- a/clang/unittests/CIR/CMakeLists.txt +++ b/clang/unittests/CIR/CMakeLists.txt @@ -12,6 +12,7 @@ add_distinct_clang_unittest(CIRUnitTests PointerLikeTest.cpp RecordTypeMetadataTest.cpp UnionTypeSizeTest.cpp + VectorTypeABIAlignTest.cpp LLVM_COMPONENTS Core diff --git a/clang/unittests/CIR/VectorTypeABIAlignTest.cpp b/clang/unittests/CIR/VectorTypeABIAlignTest.cpp new file mode 100644 index 0000000000000..cb36d2333494b --- /dev/null +++ b/clang/unittests/CIR/VectorTypeABIAlignTest.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Unit tests for VectorType::getABIAlignment. +// +//===----------------------------------------------------------------------===// + +#include "mlir/IR/BuiltinOps.h" +#include "mlir/IR/MLIRContext.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" +#include "gtest/gtest.h" + +using namespace mlir; +using namespace cir; + +namespace { + +class VectorTypeABIAlignTest : public ::testing::Test { +protected: + VectorTypeABIAlignTest() { context.loadDialect<cir::CIRDialect>(); } + + MLIRContext context; + + uint64_t abiAlign(mlir::Type elementType, uint64_t size) { + cir::VectorType ty = cir::VectorType::get(elementType, size); + OpBuilder builder(&context); + auto module = ModuleOp::create(builder.getUnknownLoc()); + mlir::DataLayout dl(module); + uint64_t align = dl.getTypeABIAlignment(ty); + module->erase(); + return align; + } + + mlir::Type f32() { return cir::SingleType::get(&context); } + mlir::Type f64() { return cir::DoubleType::get(&context); } +}; + +// The hook answers in bytes, so a vector holding one double aligns to 8 and +// not to its 64-bit size. +TEST_F(VectorTypeABIAlignTest, AlignmentIsInBytes) { + EXPECT_EQ(abiAlign(f64(), 1), 8u); + EXPECT_EQ(abiAlign(f32(), 1), 4u); +} + +// A size that is already a power of two keeps it rather than rounding to the +// next one up. +TEST_F(VectorTypeABIAlignTest, ExactPowerOfTwoSizeIsUnchanged) { + EXPECT_EQ(abiAlign(f32(), 4), 16u); + EXPECT_EQ(abiAlign(f32(), 8), 32u); + EXPECT_EQ(abiAlign(f32(), 16), 64u); +} + +// An element count that is not a power of two rounds the byte size up. +TEST_F(VectorTypeABIAlignTest, NonPowerOfTwoElementCountRoundsUp) { + EXPECT_EQ(abiAlign(f32(), 3), 16u); + EXPECT_EQ(abiAlign(f64(), 3), 32u); +} + +} // namespace _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
