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

Reply via email to