Skip to content

Conversation

HerrCai0907
Copy link
Contributor

@HerrCai0907 HerrCai0907 commented Jun 22, 2025

In libstdc++ std::variant implementation, union without any fields is used.

According to current CodeGen logic, append 1 byte padding for this kind of union.
Handle this union in mlir::RecordType for getLargestMember` return nullptr also.

The original LLVM IR

%union.EmptyUnion = type { i8 }
@__const._Z2f0v.e = private unnamed_addr constant %union.EmptyUnion undef, align 1

define dso_local void @_Z2f0v() #0 {
entry:
  %e = alloca %union.EmptyUnion, align 1
  call void @llvm.memcpy.p0.p0.i64(ptr align 1 %e, ptr align 1 @__const._Z2f0v.e, i64 1, i1 false)
  ret void
}

The CIR lowered LLVM IR

%union.EmptyUnion = type { i8 }

define dso_local void @_Z2f0v() #0 {
  %1 = alloca %union.EmptyUnion, i64 1, align 1
  store %union.EmptyUnion undef, ptr %1, align 1
  ret void
}

The major different is original use global const and memcpy, the current use store. The difference between the two is not related to this revision.

In
[libstdc++ std::variant
implementation](https://github.com/gcc-mirror/gcc/blob/b0419798447ae25de2f58d1a695db6dadb5d8547/libstdc%2B%2B-v3/include/std/variant#L387-L394),
union without any fields is used.

According to current CodeGen logic, append 1 byte padding for this kind of union.
Handle this union in `mlir::RecordType` also
Copy link

github-actions bot commented Jun 22, 2025

✅ With the latest revision this PR passed the undef deprecator.

@bcardosolopes
Copy link
Member

The major different is original use global const and memcpy, the current use store. The difference between the two is not related to this revision.

Right, we're still lacking transforming struct load/stores to their proper memcpy equivalents.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly good, few nits

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM one more nit

@bcardosolopes bcardosolopes merged commit 6ef0921 into llvm:main Jun 26, 2025
9 checks passed
@HerrCai0907 HerrCai0907 deleted the handle-union-without-fields branch June 26, 2025 19:29
terapines-osc-cir pushed a commit to Terapines/clangir that referenced this pull request Sep 2, 2025
In [libstdc++ std::variant
implementation](https://github.com/gcc-mirror/gcc/blob/b0419798447ae25de2f58d1a695db6dadb5d8547/libstdc%2B%2B-v3/include/std/variant#L387-L394),
union without any fields is used.

According to current CodeGen logic, append 1 byte padding for this kind
of union.
Handle this union in `mlir::RecordType` for getLargestMember` return
nullptr also.

The original LLVM IR
```llvm
%union.EmptyUnion = type { i8 }
@__const._Z2f0v.e = private unnamed_addr constant %union.EmptyUnion undef, align 1

define dso_local void @_Z2f0v() #0 {
entry:
  %e = alloca %union.EmptyUnion, align 1
  call void @llvm.memcpy.p0.p0.i64(ptr align 1 %e, ptr align 1 @__const._Z2f0v.e, i64 1, i1 false)
  ret void
}
```
The CIR lowered LLVM IR
```llvm
%union.EmptyUnion = type { i8 }

define dso_local void @_Z2f0v() #0 {
  %1 = alloca %union.EmptyUnion, i64 1, align 1
  store %union.EmptyUnion undef, ptr %1, align 1
  ret void
}
```
The major different is original use global const and memcpy, the current
use store. The difference between the two is not related to this
revision.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants