[llvm-branch-commits] [clang] [KeyInstr][Clang] Assignment atom group (PR #134637)
Orlando Cazalet-Hyams via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu May 22 07:54:42 PDT 2025
https://github.com/OCHyams updated https://github.com/llvm/llvm-project/pull/134637
>From 3b4ca1b09a659e575e022109fd8c607c9df3864f Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 2 Apr 2025 18:01:48 +0100
Subject: [PATCH 01/12] [KeyInstr][Clang] Assignment atom group
This patch is part of a stack that teaches Clang to generate Key Instructions
metadata for C and C++.
The Key Instructions project is introduced, including a "quick summary" section
at the top which adds context for this PR, here:
https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
The feature is only functional in LLVM if LLVM is built with CMake flag
LLVM_EXPERIMENTAL_KEY_INSTRUCTIONs. Eventually that flag will be removed.
The Clang-side work is demoed here:
https://github.com/llvm/llvm-project/pull/130943
---
clang/lib/CodeGen/CGExpr.cpp | 9 +++++++++
clang/test/DebugInfo/KeyInstructions/assign.cpp | 9 +++++++++
2 files changed, 18 insertions(+)
create mode 100644 clang/test/DebugInfo/KeyInstructions/assign.cpp
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1e426586620a2..9681fd9325fa7 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5985,6 +5985,15 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");
+ // This covers both LHS and RHS expressions, though nested RHS
+ // expressions may get subsequently separately grouped.
+ // FIXME(OCH): Not clear yet if we've got fine enough control
+ // to pick and choose when we need to. Currently looks ok:
+ // a = b = c -> Two atoms.
+ // x = new(1) -> One atom (for both addr store and value store).
+ // Complex and agg assignment -> One atom.
+ ApplyAtomGroup Grp(getDebugInfo());
+
// Note that in all of these cases, __block variables need the RHS
// evaluated first just in case the variable gets moved by the RHS.
diff --git a/clang/test/DebugInfo/KeyInstructions/assign.cpp b/clang/test/DebugInfo/KeyInstructions/assign.cpp
new file mode 100644
index 0000000000000..b09137430156f
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/assign.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang -gkey-instructions %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+unsigned long long g;
+void fun() { g = 0; }
+
+// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
+
+// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
>From b6274d2afefac7c4546ba5b295b01ce2a3fa74d9 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 2 Apr 2025 18:27:59 +0100
Subject: [PATCH 02/12] [KeyInstr][Clang] Multiple assignment (x = y = z)
---
clang/lib/CodeGen/CGExprScalar.cpp | 1 +
.../test/DebugInfo/KeyInstructions/assign.cpp | 18 ++++++++++++++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 5d618658bc615..1cc5c147c595b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5067,6 +5067,7 @@ llvm::Value *CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment(
}
Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
+ ApplyAtomGroup Grp(CGF.getDebugInfo());
bool Ignore = TestAndClearIgnoreResultAssign();
Value *RHS;
diff --git a/clang/test/DebugInfo/KeyInstructions/assign.cpp b/clang/test/DebugInfo/KeyInstructions/assign.cpp
index b09137430156f..d50062d21935b 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/assign.cpp
@@ -2,8 +2,22 @@
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
unsigned long long g;
-void fun() { g = 0; }
-
+void fun() {
// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
+ g = 0;
+
+// Treat the two assignments as two atoms.
+//
+// FIXME: Because of the atomGroup implementation the load can only be
+// associated with one of the two stores, despite being a good backup
+// loction for both.
+// CHECK-NEXT: %0 = load i64, ptr @g{{.*}}, !dbg [[G2R2:!.*]]
+// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G2R1:!.*]]
+ g = g = g;
+}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
>From 0ce86c40443015f1f84d7e75dc60cf3e6fe6f7fa Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 3 Apr 2025 11:05:29 +0100
Subject: [PATCH 03/12] Compound assign
---
clang/lib/CodeGen/CGExprScalar.cpp | 2 ++
.../DebugInfo/KeyInstructions/assign-scalar.c | 34 +++++++++++++++++++
.../test/DebugInfo/KeyInstructions/assign.cpp | 13 ++++++-
3 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 clang/test/DebugInfo/KeyInstructions/assign-scalar.c
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 1cc5c147c595b..366393dbdaf15 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -898,6 +898,7 @@ class ScalarExprEmitter
return result; \
} \
Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
+ ApplyAtomGroup Grp(CGF.getDebugInfo()); \
return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
}
HANDLEBINOP(Mul)
@@ -5850,6 +5851,7 @@ LValue CodeGenFunction::EmitObjCIsaExpr(const ObjCIsaExpr *E) {
LValue CodeGenFunction::EmitCompoundAssignmentLValue(
const CompoundAssignOperator *E) {
+ ApplyAtomGroup Grp(getDebugInfo());
ScalarExprEmitter Scalar(*this);
Value *Result = nullptr;
switch (E->getOpcode()) {
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
new file mode 100644
index 0000000000000..1e08195b06eb5
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -0,0 +1,34 @@
+// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+// RUN: %clang -gkey-instructions -x c %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+unsigned long long g;
+void fun() {
+// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
+ g = 0;
+
+// Treat the two assignments as two atoms.
+//
+// FIXME: Because of the atomGroup implementation the load can only be
+// associated with one of the two stores, despite being a good backup
+// loction for both.
+// CHECK-NEXT: %0 = load i64, ptr @g{{.*}}, !dbg [[G2R2:!.*]]
+// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G2R1:!.*]]
+ g = g = g;
+
+// Compound assignment.
+// CHECK: %1 = load i64, ptr @g
+// CHECK: %add = add i64 %1, 50, !dbg [[G4R2:!.*]]
+// CHECK: store i64 %add, ptr @g{{.*}}, !dbg [[G4R1:!.*]]
+ g += 50;
+}
+
+// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
+// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign.cpp b/clang/test/DebugInfo/KeyInstructions/assign.cpp
index d50062d21935b..1e08195b06eb5 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/assign.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang -gkey-instructions %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+// RUN: %clang -gkey-instructions -x c %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
unsigned long long g;
@@ -15,9 +18,17 @@ void fun() {
// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G3R1:!.*]]
// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G2R1:!.*]]
g = g = g;
+
+// Compound assignment.
+// CHECK: %1 = load i64, ptr @g
+// CHECK: %add = add i64 %1, 50, !dbg [[G4R2:!.*]]
+// CHECK: store i64 %add, ptr @g{{.*}}, !dbg [[G4R1:!.*]]
+ g += 50;
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
+// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
>From 1ccc74bc5b36e1444f0c646320dd756dfb134b89 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 3 Apr 2025 11:12:26 +0100
Subject: [PATCH 04/12] Pre/Post Inc/Dec
---
clang/lib/CodeGen/CGExprScalar.cpp | 1 +
.../test/DebugInfo/KeyInstructions/assign-scalar.c | 14 ++++++++++++++
2 files changed, 15 insertions(+)
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 366393dbdaf15..b9eb12efd6670 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3015,6 +3015,7 @@ class OMPLastprivateConditionalUpdateRAII {
llvm::Value *
ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre) {
+ ApplyAtomGroup Grp(CGF.getDebugInfo());
OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
QualType type = E->getSubExpr()->getType();
llvm::PHINode *atomicPHI = nullptr;
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index 1e08195b06eb5..1f1fe8fda39e6 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -24,6 +24,16 @@ void fun() {
// CHECK: %add = add i64 %1, 50, !dbg [[G4R2:!.*]]
// CHECK: store i64 %add, ptr @g{{.*}}, !dbg [[G4R1:!.*]]
g += 50;
+
+// Pre/Post Inc/Dec.
+// CHECK: %2 = load i64, ptr @g
+// CHECK: %inc = add i64 %2, 1, !dbg [[G5R2:!.*]]
+// CHECK: store i64 %inc, ptr @g{{.*}}, !dbg [[G5R1:!.*]]
+ ++g;
+// CHECK: %3 = load i64, ptr @g
+// CHECK: %dec = add i64 %3, -1, !dbg [[G6R2:!.*]]
+// CHECK: store i64 %dec, ptr @g{{.*}}, !dbg [[G6R1:!.*]]
+ g--;
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -32,3 +42,7 @@ void fun() {
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[G5R2]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 2)
+// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
+// CHECK: [[G6R2]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 2)
+// CHECK: [[G6R1]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
>From 99c0f3a69161ee2a92e063a60fe082e40e89e20f Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 3 Apr 2025 11:27:18 +0100
Subject: [PATCH 05/12] Rename test & run C & C++
---
.../test/DebugInfo/KeyInstructions/init-agg.c | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 clang/test/DebugInfo/KeyInstructions/init-agg.c
diff --git a/clang/test/DebugInfo/KeyInstructions/init-agg.c b/clang/test/DebugInfo/KeyInstructions/init-agg.c
new file mode 100644
index 0000000000000..ad298715286cd
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/init-agg.c
@@ -0,0 +1,41 @@
+
+// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gno-column-info -S -emit-llvm -o - -ftrivial-auto-var-init=pattern \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+// RUN: %clang -gkey-instructions -x c %s -gmlt -gno-column-info -S -emit-llvm -o - -ftrivial-auto-var-init=pattern \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+// The implicit-check-not is important; we don't want the GEPs created for the
+// store locations to be included in the atom group.
+
+int g;
+void a() {
+// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G1R1:!.*]]
+ int A[] = { 1, 2, 3 };
+
+// CHECK: store i32 1, ptr %{{.*}}, !dbg [[G2R1:!.*]]
+// CHECK: store i32 2, ptr %{{.*}}, !dbg [[G2R1]]
+// CHECK: %0 = load i32, ptr @g{{.*}}, !dbg [[G2R2:!.*]]
+// CHECK: store i32 %0, ptr %{{.*}}, !dbg [[G2R1]]
+ int B[] = { 1, 2, g };
+
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK: store i8 97{{.*}}, !dbg [[G3R1]]
+// CHECK: store i8 98{{.*}}, !dbg [[G3R1]]
+// CHECK: store i8 99{{.*}}, !dbg [[G3R1]]
+// CHECK: store i8 100{{.*}}, !dbg [[G3R1]]
+ char big[65536] = { 'a', 'b', 'c', 'd' };
+
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[G4R1:!.*]]
+ char arr[] = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, };
+
+// CHECK: store i8 -86, ptr %uninit{{.*}}, !dbg [[G5R1:!.*]], !annotation
+ char uninit; // -ftrivial-auto-var-init=pattern
+}
+
+// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
>From 6f0135b3afce0539c406feee562dfb27dccb367a Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Wed, 21 May 2025 14:55:20 +0100
Subject: [PATCH 06/12] %cc1 and rename a .cpp -> c test
---
clang/test/DebugInfo/KeyInstructions/assign-scalar.c | 4 ++--
clang/test/DebugInfo/KeyInstructions/{assign.cpp => assign.c} | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
rename clang/test/DebugInfo/KeyInstructions/{assign.cpp => assign.c} (85%)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index 1f1fe8fda39e6..903402b6d698c 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -1,7 +1,7 @@
-// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: %clang_cc1 -gkey-instructions -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-// RUN: %clang -gkey-instructions -x c %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
unsigned long long g;
diff --git a/clang/test/DebugInfo/KeyInstructions/assign.cpp b/clang/test/DebugInfo/KeyInstructions/assign.c
similarity index 85%
rename from clang/test/DebugInfo/KeyInstructions/assign.cpp
rename to clang/test/DebugInfo/KeyInstructions/assign.c
index 1e08195b06eb5..d2ce2dceed2f8 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/assign.c
@@ -1,7 +1,7 @@
-// RUN: %clang -gkey-instructions -x c++ %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: %clang_cc1 -gkey-instructions -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-// RUN: %clang -gkey-instructions -x c %s -gmlt -gcolumn-info -S -emit-llvm -o - -Wno-unused-variable \
+// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
unsigned long long g;
>From 7695d2f7ee990d79ce8592ea7a8f3e9371c7eb67 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 14:10:50 +0100
Subject: [PATCH 07/12] improve comment
---
clang/lib/CodeGen/CGExpr.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 9681fd9325fa7..ff9c1db04b276 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5985,13 +5985,13 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");
- // This covers both LHS and RHS expressions, though nested RHS
- // expressions may get subsequently separately grouped.
- // FIXME(OCH): Not clear yet if we've got fine enough control
- // to pick and choose when we need to. Currently looks ok:
- // a = b = c -> Two atoms.
- // x = new(1) -> One atom (for both addr store and value store).
- // Complex and agg assignment -> One atom.
+ // Create a Key Instructions source location atom group that covers both
+ // LHS and RHS expressions. Nested RHS expressions may get subsequently
+ // separately grouped (1 below):
+ //
+ // 1. `a = b = c` -> Two atoms.
+ // 2. `x = new(1)` -> One atom (for both addr store and value store).
+ // 3. Complex and agg assignment -> One atom.
ApplyAtomGroup Grp(getDebugInfo());
// Note that in all of these cases, __block variables need the RHS
>From dd5949e0552d62338f336bbd982a783a2e45d42e Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 14:57:35 +0100
Subject: [PATCH 08/12] test g += ++h;
---
.../DebugInfo/KeyInstructions/assign-scalar.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index 903402b6d698c..8ec31c9a80e63 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -4,7 +4,7 @@
// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-unsigned long long g;
+unsigned long long g, h;
void fun() {
// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
g = 0;
@@ -34,6 +34,16 @@ void fun() {
// CHECK: %dec = add i64 %3, -1, !dbg [[G6R2:!.*]]
// CHECK: store i64 %dec, ptr @g{{.*}}, !dbg [[G6R1:!.*]]
g--;
+
+// Compound assignment with assignment on RHS, the assignments should have
+// their own separate atom groups.
+// CHECK: %4 = load i64, ptr @h{{.*}}, !dbg [[load_h_loc:!.*]]
+// CHECK: %inc1 = add i64 %4, 1, !dbg [[G8R2:!.*]]
+// CHECK: store i64 %inc1, ptr @h{{.*}}, !dbg [[G8R1:!.*]]
+// CHECK: %5 = load i64, ptr @g{{.*}}, !dbg [[load_g_loc:!.*]]
+// CHECK: %add2 = add i64 %5, %inc1, !dbg [[G7R2:!.*]]
+// CHECK: store i64 %add2, ptr @g{{.*}}, !dbg [[G7R1:!.*]]
+ g += ++h;
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -46,3 +56,9 @@ void fun() {
// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
// CHECK: [[G6R2]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 2)
// CHECK: [[G6R1]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
+// CHECK: [[load_h_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
+// CHECK: [[G8R2]] = !DILocation({{.*}}, atomGroup: 8, atomRank: 2)
+// CHECK: [[G8R1]] = !DILocation({{.*}}, atomGroup: 8, atomRank: 1)
+// CHECK: [[load_g_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
+// CHECK: [[G7R2]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 2)
+// CHECK: [[G7R1]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 1)
>From 098e77a299faa3926c138f26eddd4f133d55831a Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 15:01:46 +0100
Subject: [PATCH 09/12] rm accidental redundant test
---
clang/test/DebugInfo/KeyInstructions/assign.c | 34 -------------------
1 file changed, 34 deletions(-)
delete mode 100644 clang/test/DebugInfo/KeyInstructions/assign.c
diff --git a/clang/test/DebugInfo/KeyInstructions/assign.c b/clang/test/DebugInfo/KeyInstructions/assign.c
deleted file mode 100644
index d2ce2dceed2f8..0000000000000
--- a/clang/test/DebugInfo/KeyInstructions/assign.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -gkey-instructions -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \
-// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-
-// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
-// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-
-unsigned long long g;
-void fun() {
-// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
- g = 0;
-
-// Treat the two assignments as two atoms.
-//
-// FIXME: Because of the atomGroup implementation the load can only be
-// associated with one of the two stores, despite being a good backup
-// loction for both.
-// CHECK-NEXT: %0 = load i64, ptr @g{{.*}}, !dbg [[G2R2:!.*]]
-// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G3R1:!.*]]
-// CHECK-NEXT: store i64 %0, ptr @g{{.*}}, !dbg [[G2R1:!.*]]
- g = g = g;
-
-// Compound assignment.
-// CHECK: %1 = load i64, ptr @g
-// CHECK: %add = add i64 %1, 50, !dbg [[G4R2:!.*]]
-// CHECK: store i64 %add, ptr @g{{.*}}, !dbg [[G4R1:!.*]]
- g += 50;
-}
-
-// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
-// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
-// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
-// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
-// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
-// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
>From bcf5a3d7e196ad2e69e74d7cf256daa119f5d435 Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 15:18:39 +0100
Subject: [PATCH 10/12] improve mem* checks in agg test
---
clang/test/DebugInfo/KeyInstructions/init-agg.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/test/DebugInfo/KeyInstructions/init-agg.c b/clang/test/DebugInfo/KeyInstructions/init-agg.c
index ad298715286cd..21b26092e5acf 100644
--- a/clang/test/DebugInfo/KeyInstructions/init-agg.c
+++ b/clang/test/DebugInfo/KeyInstructions/init-agg.c
@@ -10,7 +10,7 @@
int g;
void a() {
-// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G1R1:!.*]]
+// CHECK: call void @llvm.memcpy{{.*}}%A{{.*}}, !dbg [[G1R1:!.*]]
int A[] = { 1, 2, 3 };
// CHECK: store i32 1, ptr %{{.*}}, !dbg [[G2R1:!.*]]
@@ -19,14 +19,14 @@ void a() {
// CHECK: store i32 %0, ptr %{{.*}}, !dbg [[G2R1]]
int B[] = { 1, 2, g };
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}%big{{.*}}, !dbg [[G3R1:!.*]]
// CHECK: store i8 97{{.*}}, !dbg [[G3R1]]
// CHECK: store i8 98{{.*}}, !dbg [[G3R1]]
// CHECK: store i8 99{{.*}}, !dbg [[G3R1]]
// CHECK: store i8 100{{.*}}, !dbg [[G3R1]]
char big[65536] = { 'a', 'b', 'c', 'd' };
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G4R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}%arr{{.*}}, !dbg [[G4R1:!.*]]
char arr[] = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, };
// CHECK: store i8 -86, ptr %uninit{{.*}}, !dbg [[G5R1:!.*]], !annotation
>From 93cd43bd94f189dc1935f585a0586c642528636e Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 15:18:47 +0100
Subject: [PATCH 11/12] add comma operator coverage to test
---
.../DebugInfo/KeyInstructions/assign-scalar.c | 35 +++++++++++++++----
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index 8ec31c9a80e63..f80f221bc8b6c 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -4,7 +4,7 @@
// RUN: %clang_cc1 -gkey-instructions -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
-unsigned long long g, h;
+unsigned long long g, h, i;
void fun() {
// CHECK: store i64 0, ptr @g{{.*}}, !dbg [[G1R1:!.*]]
g = 0;
@@ -37,13 +37,27 @@ void fun() {
// Compound assignment with assignment on RHS, the assignments should have
// their own separate atom groups.
-// CHECK: %4 = load i64, ptr @h{{.*}}, !dbg [[load_h_loc:!.*]]
-// CHECK: %inc1 = add i64 %4, 1, !dbg [[G8R2:!.*]]
-// CHECK: store i64 %inc1, ptr @h{{.*}}, !dbg [[G8R1:!.*]]
-// CHECK: %5 = load i64, ptr @g{{.*}}, !dbg [[load_g_loc:!.*]]
-// CHECK: %add2 = add i64 %5, %inc1, !dbg [[G7R2:!.*]]
-// CHECK: store i64 %add2, ptr @g{{.*}}, !dbg [[G7R1:!.*]]
+// CHECK-NEXT: %4 = load i64, ptr @h{{.*}}, !dbg [[load_h_loc:!.*]]
+// CHECK-NEXT: %inc1 = add i64 %4, 1, !dbg [[G8R2:!.*]]
+// CHECK-NEXT: store i64 %inc1, ptr @h{{.*}}, !dbg [[G8R1:!.*]]
+// CHECK-NEXT: %5 = load i64, ptr @g{{.*}}, !dbg [[load_g_loc:!.*]]
+// CHECK-NEXT: %add2 = add i64 %5, %inc1, !dbg [[G7R2:!.*]]
+// CHECK-NEXT: store i64 %add2, ptr @g{{.*}}, !dbg [[G7R1:!.*]]
g += ++h;
+
+// Double check the comma operator doesn't disturb atom groupings. There
+// are three assignments, so we should get three groups.
+// FIXME: Same situation as earlier in the test - because of the atomGroup
+// implementation the load (from h) can only be associated with one of the two
+// stores (to h and g) despite being a good backup location for both.
+// CHECK-NEXT: %6 = load i64, ptr @h{{.*}}, !dbg [[load_h_loc2:!.*]]
+// CHECK-NEXT: %inc3 = add i64 %6, 1, !dbg [[G9R2:!.*]]
+// CHECK-NEXT: store i64 %inc3, ptr @h{{.*}}, !dbg [[G10R1:!.*]]
+// CHECK-NEXT: store i64 %inc3, ptr @g{{.*}}, !dbg [[G9R1:!.*]]
+// CHECK-NEXT: %7 = load i64, ptr @i{{.*}}, !dbg [[load_i_loc:!.*]]
+// CHECK-NEXT: %inc4 = add i64 %7, 1, !dbg [[G11R2:!.*]]
+// CHECK-NEXT: store i64 %inc4, ptr @i{{.*}}, !dbg [[G11R1:!.*]]
+ g = ++h, ++i;
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -62,3 +76,10 @@ void fun() {
// CHECK: [[load_g_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
// CHECK: [[G7R2]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 2)
// CHECK: [[G7R1]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 1)
+// CHECK: [[load_h_loc2]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
+// CHECK: [[G9R2]] = !DILocation({{.*}}, atomGroup: 9, atomRank: 2)
+// CHECK: [[G10R1]] = !DILocation({{.*}}, atomGroup: 10, atomRank: 1)
+// CHECK: [[G9R1]] = !DILocation({{.*}}, atomGroup: 9, atomRank: 1)
+// CHECK: [[load_i_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
+// CHECK: [[G11R2]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 2)
+// CHECK: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
\ No newline at end of file
>From d2d43d91f9e97b46761bb9da1fa55da57c0536de Mon Sep 17 00:00:00 2001
From: Orlando Cazalet-Hyams <orlando.hyams at sony.com>
Date: Thu, 22 May 2025 15:54:25 +0100
Subject: [PATCH 12/12] newline
---
clang/test/DebugInfo/KeyInstructions/assign-scalar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index f80f221bc8b6c..98d005b2e925c 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -82,4 +82,4 @@ void fun() {
// CHECK: [[G9R1]] = !DILocation({{.*}}, atomGroup: 9, atomRank: 1)
// CHECK: [[load_i_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
// CHECK: [[G11R2]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 2)
-// CHECK: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
\ No newline at end of file
+// CHECK: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
More information about the llvm-branch-commits
mailing list