Skip to content

[KeyInstr][Clang] Copy ctor/assignment operator source atoms #144346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

OCHyams
Copy link
Contributor

@OCHyams OCHyams commented Jun 16, 2025

No description provided.

@OCHyams OCHyams requested review from jmorse and SLTozer June 16, 2025 12:56
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Jun 16, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 16, 2025

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-debuginfo

Author: Orlando Cazalet-Hyams (OCHyams)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/144346.diff

3 Files Affected:

  • (modified) clang/lib/CodeGen/CGClass.cpp (+4-1)
  • (added) clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp (+36)
  • (added) clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp (+38)
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 13792c1042046..c78267857bc9e 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1000,7 +1000,8 @@ namespace {
     void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
       DestPtr = DestPtr.withElementType(CGF.Int8Ty);
       SrcPtr = SrcPtr.withElementType(CGF.Int8Ty);
-      CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity());
+      auto *I = CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity());
+      CGF.addInstToCurrentSourceAtom(I, nullptr);
     }
 
     void addInitialField(FieldDecl *F) {
@@ -1341,6 +1342,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
     ApplyAtomGroup Grp(getDebugInfo());
     CM.addMemberInitializer(Member);
   }
+
+  ApplyAtomGroup Grp(getDebugInfo());
   CM.finish();
 }
 
diff --git a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp
new file mode 100644
index 0000000000000..3df5dc357169e
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions %s -gno-column-info -debug-info-kind=line-tables-only -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// g::h and i can be memcpy'd, check the assignment gets Key Instructions metadata.
+
+struct e {
+  e(e &);
+};
+
+struct g {
+  e f;
+  int h;
+  int i;
+};
+
+// CHECK: define{{.*}}void @_ZN1gC2ERS_
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %this.addr = alloca ptr, align 8
+// CHECK-NEXT: %.addr = alloca ptr, align 8
+// CHECK-NEXT: store ptr %this, ptr %this.addr, align 8
+// CHECK-NEXT: store ptr %0, ptr %.addr, align 8
+// CHECK-NEXT: %this1 = load ptr, ptr %this.addr, align 8
+// CHECK-NEXT: %1 = load ptr, ptr %.addr, align 8
+// CHECK-NEXT: call void @_ZN1eC1ERS_
+// CHECK-NEXT: %h = getelementptr inbounds nuw %struct.g, ptr %this1, i32 0, i32 1
+// CHECK-NEXT: %2 = load ptr, ptr %.addr, align 8
+// CHECK-NEXT: %h2 = getelementptr inbounds nuw %struct.g, ptr %2, i32 0, i32 1
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}(ptr align 4 %h, ptr align 4 %h2, i64 8, i1 false), !dbg [[G1R1:!.*]]
+// CHECK-NEXT: ret void, !dbg
+
+// CHECK: [[G1R1]] = !DILocation(line: 10, scope: ![[#]], atomGroup: 1, atomRank: 1)
+
+[[gnu::nodebug]]
+void fun(g *x) {
+  g y = g(*x);
+}
diff --git a/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp
new file mode 100644
index 0000000000000..b73683c660b4e
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions %s -gno-column-info -debug-info-kind=line-tables-only -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// g::h can be memcpy'd (in this case emitted as load/stored), check the
+// assignment gets Key Instructions metadata.
+
+struct e {
+  e(e &);
+};
+
+struct g {
+  e f;
+  int h;
+};
+
+// CHECK: define{{.*}}void @_ZN1gC2ERS_
+// CHECK-NEXT: entry:
+// CHECK-NEXT: %this.addr = alloca ptr, align 8
+// CHECK-NEXT: %.addr = alloca ptr, align 8
+// CHECK-NEXT: store ptr %this, ptr %this.addr, align 8
+// CHECK-NEXT: store ptr %0, ptr %.addr, align 8
+// CHECK-NEXT: %this1 = load ptr, ptr %this.addr, align 8
+// CHECK-NEXT: %1 = load ptr, ptr %.addr, align 8
+// CHECK-NEXT: call void @_ZN1eC1ERS_
+// CHECK-NEXT: %h = getelementptr inbounds nuw %struct.g, ptr %this1, i32 0, i32 1
+// CHECK-NEXT: %2 = load ptr, ptr %.addr, align 8
+// CHECK-NEXT: %h2 = getelementptr inbounds nuw %struct.g, ptr %2, i32 0, i32 1
+// CHECK-NEXT: %3 = load i32, ptr %h2, align 4, !dbg [[G1R2:!.*]]
+// CHECK-NEXT: store i32 %3, ptr %h, align 4, !dbg [[G1R1:!.*]]
+// CHECK-NEXT: ret void, !dbg
+
+// CHECK: [[G1R2]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 1, atomRank: 2)
+// CHECK: [[G1R1]] = !DILocation(line: 11, scope: ![[#]], atomGroup: 1, atomRank: 1)
+
+[[gnu::nodebug]]
+void fun(g *x) {
+  g y = g(*x);
+}

@OCHyams OCHyams changed the title [KeyInstr][Clang] Ctor memcpy-able members init source atom [KeyInstr][Clang] Copy ctor/assignment operator source atoms Jun 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category debuginfo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants