[clang] 472aa4e - [CIR] Fix union RecordType::getTypeSizeInBits to return bits (#191516)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 14 10:26:23 PDT 2026
Author: adams381
Date: 2026-04-14T12:26:18-05:00
New Revision: 472aa4e326be7f1ea7b182f2e55193474f22e6de
URL: https://github.com/llvm/llvm-project/commit/472aa4e326be7f1ea7b182f2e55193474f22e6de
DIFF: https://github.com/llvm/llvm-project/commit/472aa4e326be7f1ea7b182f2e55193474f22e6de.diff
LOG: [CIR] Fix union RecordType::getTypeSizeInBits to return bits (#191516)
RecordType::getTypeSizeInBits for unions was calling
dataLayout.getTypeSize (which returns bytes) instead of
dataLayout.getTypeSizeInBits. This returned a value 8x too
small. Also handle the empty-union case where
getLargestMember returns nullptr.
Added:
clang/unittests/CIR/UnionTypeSizeTest.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 9f2342254a882..1ceeea954daa2 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -378,8 +378,12 @@ PointerType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
llvm::TypeSize
RecordType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
mlir::DataLayoutEntryListRef params) const {
- if (isUnion())
- return dataLayout.getTypeSize(getLargestMember(dataLayout));
+ if (isUnion()) {
+ mlir::Type largest = getLargestMember(dataLayout);
+ if (!largest)
+ return llvm::TypeSize::getFixed(0);
+ return dataLayout.getTypeSizeInBits(largest);
+ }
auto recordSize = static_cast<uint64_t>(computeStructSize(dataLayout));
return llvm::TypeSize::getFixed(recordSize * 8);
diff --git a/clang/unittests/CIR/CMakeLists.txt b/clang/unittests/CIR/CMakeLists.txt
index 0514dd961b7b9..796ab30137e01 100644
--- a/clang/unittests/CIR/CMakeLists.txt
+++ b/clang/unittests/CIR/CMakeLists.txt
@@ -6,6 +6,7 @@ include_directories(${MLIR_TABLEGEN_OUTPUT_DIR})
add_distinct_clang_unittest(CIRUnitTests
PointerLikeTest.cpp
RecordTypeMetadataTest.cpp
+ UnionTypeSizeTest.cpp
LLVM_COMPONENTS
Core
diff --git a/clang/unittests/CIR/UnionTypeSizeTest.cpp b/clang/unittests/CIR/UnionTypeSizeTest.cpp
new file mode 100644
index 0000000000000..a5b3f42cc0e99
--- /dev/null
+++ b/clang/unittests/CIR/UnionTypeSizeTest.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 union RecordType::getTypeSizeInBits.
+//
+//===----------------------------------------------------------------------===//
+
+#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;
+
+class UnionTypeSizeTest : public ::testing::Test {
+protected:
+ UnionTypeSizeTest() { context.loadDialect<cir::CIRDialect>(); }
+
+ MLIRContext context;
+
+ mlir::StringAttr getName(llvm::StringRef name) {
+ return mlir::StringAttr::get(&context, name);
+ }
+};
+
+TEST_F(UnionTypeSizeTest, SizeInBitsNotBytes) {
+ IntType i32 = IntType::get(&context, 32, true);
+ auto ty = RecordType::get(&context, getName("U"), RecordType::Union);
+ ty.complete({i32}, /*packed=*/false, /*padded=*/false);
+
+ OpBuilder builder(&context);
+ auto loc = builder.getUnknownLoc();
+ auto module = ModuleOp::create(loc);
+ mlir::DataLayout dl(module);
+
+ llvm::TypeSize size = dl.getTypeSizeInBits(ty);
+ EXPECT_EQ(size.getFixedValue(), 32u);
+
+ module->erase();
+}
+
+TEST_F(UnionTypeSizeTest, MultiMemberUnion) {
+ IntType i32 = IntType::get(&context, 32, true);
+ IntType i64 = IntType::get(&context, 64, true);
+ auto ty = RecordType::get(&context, getName("U2"), RecordType::Union);
+ ty.complete({i32, i64}, /*packed=*/false, /*padded=*/false);
+
+ OpBuilder builder(&context);
+ auto loc = builder.getUnknownLoc();
+ auto module = ModuleOp::create(loc);
+ mlir::DataLayout dl(module);
+
+ llvm::TypeSize size = dl.getTypeSizeInBits(ty);
+ EXPECT_EQ(size.getFixedValue(), 64u);
+
+ module->erase();
+}
+
+TEST_F(UnionTypeSizeTest, EmptyUnion) {
+ auto ty = RecordType::get(&context, getName("Empty"), RecordType::Union);
+ ty.complete({}, /*packed=*/false, /*padded=*/false);
+
+ OpBuilder builder(&context);
+ auto loc = builder.getUnknownLoc();
+ auto module = ModuleOp::create(loc);
+ mlir::DataLayout dl(module);
+
+ llvm::TypeSize size = dl.getTypeSizeInBits(ty);
+ EXPECT_EQ(size.getFixedValue(), 0u);
+
+ module->erase();
+}
More information about the cfe-commits
mailing list