================
@@ -388,26 +378,18 @@ llvm::TypeSize
 RecordType::getTypeSizeInBits(const mlir::DataLayout &dataLayout,
                               mlir::DataLayoutEntryListRef params) const {
   if (isUnion()) {
-    mlir::Type largest = getLargestMember(dataLayout);
-    if (!largest)
-      return llvm::TypeSize::getFixed(0);
-    // `getLargestMember` returns the highest-aligned variant (which dictates
-    // the union's alignment), not necessarily the largest by size.  When the
-    // union is `padded` -- i.e., its highest-aligned variant is strictly
-    // smaller than its layout size, as happens for any union containing both
-    // a small high-alignment scalar and a larger low-alignment array (e.g.,
-    // `union { char[16]; size_t; }`) -- `lowerUnion` appended a trailing
-    // byte-array member to extend the highest-aligned variant up to the
-    // layout size, and `LowerToLLVM` mirrors this by emitting the union as
-    // `{largest, padding}`.  Include that padding here so `getTypeSize`
-    // reports the same size `LowerToLLVM` produces; otherwise a parent
-    // record containing the union gets a spurious tail-padding member added
-    // by `insertPadding`, making `sizeof(parent)` and array GEPs off by the
-    // missing bytes.
-    llvm::TypeSize size = dataLayout.getTypeSizeInBits(largest);
-    if (mlir::Type tailPad = getPadding())
-      size += dataLayout.getTypeSizeInBits(tailPad);
-    return size;
+    // The size of a union is the size of the largest member.
+    llvm::ArrayRef<Type> members = getMembers();
+    if (members.empty() || (getPadded() && members.size() == 1))
+      return llvm::TypeSize::getFixed(8);
+
+    mlir::Type largestType = *std::max_element(
+        members.begin(), std::prev(members.end(), getPadded()),
+        [&](Type lhs, Type rhs) {
+          return dataLayout.getTypeSize(lhs) < dataLayout.getTypeSize(rhs);
+        });
+
+    return dataLayout.getTypeSizeInBits(largestType);
----------------
andykaylor wrote:

I don't think this is right. If we have user-specified alignment, we could have 
padding that forces us to increase the size of the union beyond the size of the 
largest member, right?

```
union alignas(32) U {
  int n[4];
  long long ll;
};

```
Gives me:

`%union.U = type { i64, [24 x i8] }`

https://github.com/llvm/llvm-project/pull/199292
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to