[clang] be75ded - [KeyInstr][Clang] Copy ctor/assignment operator source atoms (#144346)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 30 04:27:48 PDT 2025
Author: Orlando Cazalet-Hyams
Date: 2025-06-30T12:27:44+01:00
New Revision: be75ded3fea900718a72298276d2428ea227ceaf
URL: https://github.com/llvm/llvm-project/commit/be75ded3fea900718a72298276d2428ea227ceaf
DIFF: https://github.com/llvm/llvm-project/commit/be75ded3fea900718a72298276d2428ea227ceaf.diff
LOG: [KeyInstr][Clang] Copy ctor/assignment operator source atoms (#144346)
Added:
clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp
clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp
Modified:
clang/lib/CodeGen/CGClass.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 13792c1042046..4a465e6526da0 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -627,6 +627,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
CXXCtorInitializer *MemberInit,
const CXXConstructorDecl *Constructor,
FunctionArgList &Args) {
+ ApplyAtomGroup Grp(CGF.getDebugInfo());
ApplyDebugLocation Loc(CGF, MemberInit->getSourceLocation());
assert(MemberInit->isAnyMemberInitializer() &&
"Must have member initializer!");
@@ -1000,7 +1001,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) {
@@ -1113,6 +1115,7 @@ namespace {
}
pushEHDestructors();
+ ApplyAtomGroup Grp(CGF.getDebugInfo());
emitMemcpy();
AggregatedInits.clear();
}
@@ -1248,6 +1251,7 @@ namespace {
reset();
}
+ ApplyAtomGroup Grp(CGF.getDebugInfo());
emitMemcpy();
AggregatedStmts.clear();
}
@@ -1338,9 +1342,9 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
assert(!Member->isBaseInitializer());
assert(Member->isAnyMemberInitializer() &&
"Delegating initializer on non-delegating constructor");
- ApplyAtomGroup Grp(getDebugInfo());
CM.addMemberInitializer(Member);
}
+
CM.finish();
}
@@ -1563,6 +1567,7 @@ void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
AssignmentMemcpyizer AM(*this, AssignOp, Args);
for (auto *I : RootCS->body())
AM.emitAssignment(I);
+
AM.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..c94fc588bf13b
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable-2.cpp
@@ -0,0 +1,59 @@
+// 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 &);
+ e& operator=(const e&);
+};
+
+struct g {
+ e f;
+ int h;
+ int i;
+};
+
+// Copy assignment operator.
+// CHECK: define{{.*}}ptr @_ZN1gaSERKS_
+// 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 = call {{.*}}ptr @_ZN1eaSERKS_(ptr {{.*}}%this1, ptr {{.*}}%1)
+// 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 [[S1_G1R1:!.*]]
+// CHECK-NEXT: ret ptr %this1, !dbg
+
+// Copy ctor.
+// 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 [[S2_G1R1:!.*]]
+// CHECK-NEXT: ret void, !dbg
+
+// CHECK: [[S1:!.*]] = distinct !DISubprogram(name: "operator=",
+// CHECK: [[S1_G1R1]] = !DILocation(line: 11, scope: [[S1]], atomGroup: 1, atomRank: 1)
+
+// CHECK: [[S2:!.*]] = distinct !DISubprogram(name: "g",
+// CHECK: [[S2_G1R1]] = !DILocation(line: 11, scope: [[S2]], atomGroup: 1, atomRank: 1)
+
+[[gnu::nodebug]]
+void fun(g *x) {
+ g y = g(*x);
+ y = *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..cd3807735fa32
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/init-member-memcopyable.cpp
@@ -0,0 +1,62 @@
+// 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&);
+ e& operator=(const e&);
+};
+
+struct g {
+ e f;
+ int h;
+};
+
+// Copy assignment operator.
+// CHECK: define{{.*}}ptr @_ZN1gaSERKS_
+// 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 = call {{.*}}ptr @_ZN1eaSERKS_(ptr {{.*}}%this1, ptr {{.*}}%1)
+// CHECK-NEXT: %2 = load ptr, ptr %.addr, align 8
+// CHECK-NEXT: %h = getelementptr inbounds nuw %struct.g, ptr %2, i32 0, i32 1
+// CHECK-NEXT: %3 = load i32, ptr %h, align 4, !dbg [[S1_G1R2:!.*]]
+// CHECK-NEXT: %h2 = getelementptr inbounds nuw %struct.g, ptr %this1, i32 0, i32 1
+// CHECK-NEXT: store i32 %3, ptr %h2, align 4, !dbg [[S1_G1R1:!.*]]
+// CHECK-NEXT: ret ptr %this1, !dbg
+
+// Copy ctor.
+// 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 [[S2_G1R2:!.*]]
+// CHECK-NEXT: store i32 %3, ptr %h, align 4, !dbg [[S2_G1R1:!.*]]
+// CHECK-NEXT: ret void, !dbg
+
+// CHECK: [[S1:!.*]] = distinct !DISubprogram(name: "operator=",
+// CHECK: [[S1_G1R2]] = !DILocation(line: 12, scope: [[S1]], atomGroup: 1, atomRank: 2)
+// CHECK: [[S1_G1R1]] = !DILocation(line: 12, scope: [[S1]], atomGroup: 1, atomRank: 1)
+
+// CHECK: [[S2:!.*]] = distinct !DISubprogram(name: "g",
+// CHECK: [[S2_G1R2]] = !DILocation(line: 12, scope: [[S2]], atomGroup: 1, atomRank: 2)
+// CHECK: [[S2_G1R1]] = !DILocation(line: 12, scope: [[S2]], atomGroup: 1, atomRank: 1)
+
+void fun(g *x) {
+ g y = g(*x);
+ y = *x;
+}
More information about the cfe-commits
mailing list