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

Reply via email to