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(); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
