[clang] 54d544b - [KeyInstr][Clang] Ret atom (#134652)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 4 07:43:53 PDT 2025
Author: Orlando Cazalet-Hyams
Date: 2025-06-04T15:43:49+01:00
New Revision: 54d544b83141dc0b20727673f68793728ed54793
URL: https://github.com/llvm/llvm-project/commit/54d544b83141dc0b20727673f68793728ed54793
DIFF: https://github.com/llvm/llvm-project/commit/54d544b83141dc0b20727673f68793728ed54793.diff
LOG: [KeyInstr][Clang] Ret atom (#134652)
This patch is part of a stack that teaches Clang to generate Key Instructions
metadata for C and C++.
When returning a value, stores to the `retval` allocas and branches to `return`
block are put in the same atom group. They are both rank 1, which could in
theory introduce an extra step in some optimized code. This low risk currently
feels an acceptable for keeping the code a bit simpler (as opposed to adding
scaffolding to make the store rank 2).
In the case of a single return (no control flow) the return instruction inherits
the atom group of the branch to the return block when the blocks get folded
togather.
RFC:
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.
Added:
clang/test/DebugInfo/KeyInstructions/return-va-arg.c
clang/test/DebugInfo/KeyInstructions/return.c
Modified:
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/test/DebugInfo/KeyInstructions/agg.c
clang/test/DebugInfo/KeyInstructions/assign-scalar.c
clang/test/DebugInfo/KeyInstructions/bitfield.cpp
clang/test/DebugInfo/KeyInstructions/builtin.c
clang/test/DebugInfo/KeyInstructions/cast.c
clang/test/DebugInfo/KeyInstructions/coerced-packed.c
clang/test/DebugInfo/KeyInstructions/coerced-ptr.c
clang/test/DebugInfo/KeyInstructions/coerced-through-memory.c
clang/test/DebugInfo/KeyInstructions/coerced.c
clang/test/DebugInfo/KeyInstructions/complex.c
clang/test/DebugInfo/KeyInstructions/do.c
clang/test/DebugInfo/KeyInstructions/for.c
clang/test/DebugInfo/KeyInstructions/if.c
clang/test/DebugInfo/KeyInstructions/init-agg.c
clang/test/DebugInfo/KeyInstructions/init-member.cpp
clang/test/DebugInfo/KeyInstructions/init-scalar.c
clang/test/DebugInfo/KeyInstructions/init-static.cpp
clang/test/DebugInfo/KeyInstructions/multi-func.c
clang/test/DebugInfo/KeyInstructions/new.cpp
clang/test/DebugInfo/KeyInstructions/switch.c
clang/test/DebugInfo/KeyInstructions/try-catch.cpp
clang/test/DebugInfo/KeyInstructions/while.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 056caf64525a5..a67b0d8a91afb 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3929,9 +3929,9 @@ llvm::Value *CodeGenFunction::EmitCMSEClearRecord(llvm::Value *Src,
return R;
}
-void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
- bool EmitRetDbgLoc,
- SourceLocation EndLoc) {
+void CodeGenFunction::EmitFunctionEpilog(
+ const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc,
+ uint64_t RetKeyInstructionsSourceAtom) {
if (FI.isNoReturn()) {
// Noreturn functions don't return.
EmitUnreachable(EndLoc);
@@ -3946,7 +3946,11 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
// Functions with no result always return void.
if (!ReturnValue.isValid()) {
- Builder.CreateRetVoid();
+ auto *I = Builder.CreateRetVoid();
+ if (RetKeyInstructionsSourceAtom)
+ addInstToSpecificSourceAtom(I, nullptr, RetKeyInstructionsSourceAtom);
+ else
+ addInstToNewSourceAtom(I, nullptr);
return;
}
@@ -4126,6 +4130,12 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
if (RetDbgLoc)
Ret->setDebugLoc(std::move(RetDbgLoc));
+
+ llvm::Value *Backup = RV ? Ret->getOperand(0) : nullptr;
+ if (RetKeyInstructionsSourceAtom)
+ addInstToSpecificSourceAtom(Ret, Backup, RetKeyInstructionsSourceAtom);
+ else
+ addInstToNewSourceAtom(Ret, Backup);
}
void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index dc92493ac70fa..8742f8e0fc04a 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1605,6 +1605,7 @@ static bool isSwiftAsyncCallee(const CallExpr *CE) {
/// if the function returns void, or may be missing one if the function returns
/// non-void. Fun stuff :).
void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
+ ApplyAtomGroup Grp(getDebugInfo());
if (requiresReturnValueCheck()) {
llvm::Constant *SLoc = EmitCheckSourceLocation(S.getBeginLoc());
auto *SLocPtr =
@@ -1680,16 +1681,19 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
// If this function returns a reference, take the address of the expression
// rather than the value.
RValue Result = EmitReferenceBindingToExpr(RV);
- Builder.CreateStore(Result.getScalarVal(), ReturnValue);
+ auto *I = Builder.CreateStore(Result.getScalarVal(), ReturnValue);
+ addInstToCurrentSourceAtom(I, I->getValueOperand());
} else {
switch (getEvaluationKind(RV->getType())) {
case TEK_Scalar: {
llvm::Value *Ret = EmitScalarExpr(RV);
- if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect)
+ if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect) {
EmitStoreOfScalar(Ret, MakeAddrLValue(ReturnValue, RV->getType()),
/*isInit*/ true);
- else
- Builder.CreateStore(Ret, ReturnValue);
+ } else {
+ auto *I = Builder.CreateStore(Ret, ReturnValue);
+ addInstToCurrentSourceAtom(I, I->getValueOperand());
+ }
break;
}
case TEK_Complex:
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0388c67d0100d..2ac7e9d498044 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -444,8 +444,10 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Reset the debug location to that of the simple 'return' expression, if any
// rather than that of the end of the function's scope '}'.
+ uint64_t RetKeyInstructionsAtomGroup = Loc ? Loc->getAtomGroup() : 0;
ApplyDebugLocation AL(*this, Loc);
- EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc);
+ EmitFunctionEpilog(*CurFnInfo, EmitRetDbgLoc, EndLoc,
+ RetKeyInstructionsAtomGroup);
EmitEndEHSpec(CurCodeDecl);
assert(EHStack.empty() &&
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index f0f051a1d26f5..cecc8c0ade729 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2551,9 +2551,12 @@ class CodeGenFunction : public CodeGenTypeCache {
const FunctionArgList &Args);
/// EmitFunctionEpilog - Emit the target specific LLVM code to return the
- /// given temporary.
+ /// given temporary. Specify the source location atom group (Key Instructions
+ /// debug info feature) for the `ret` using \p RetKeyInstructionsSourceAtom.
+ /// If it's 0, the `ret` will get added to a new source atom group.
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
- SourceLocation EndLoc);
+ SourceLocation EndLoc,
+ uint64_t RetKeyInstructionsSourceAtom);
/// Emit a test that checks if the return value \p RV is nonnull.
void EmitReturnValueCheck(llvm::Value *RV);
diff --git a/clang/test/DebugInfo/KeyInstructions/agg.c b/clang/test/DebugInfo/KeyInstructions/agg.c
index 33b3a0141a0f1..58d923d1d9328 100644
--- a/clang/test/DebugInfo/KeyInstructions/agg.c
+++ b/clang/test/DebugInfo/KeyInstructions/agg.c
@@ -24,6 +24,8 @@ void fun(Struct a) {
// CHECK: %matins = insertelement <25 x float> %3, float 0.000000e+00, i64 0, !dbg [[G4R2:!.*]]
// CHECK: store <25 x float> %matins, ptr @m{{.*}}, !dbg [[G4R1:!.*]]
m[0][0] = 0;
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -32,3 +34,4 @@ void fun(Struct a) {
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
index afb0ed8ebdfd7..0bba1830e42a3 100644
--- a/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/assign-scalar.c
@@ -58,6 +58,7 @@ void fun() {
// CHECK-NEXT: %inc4 = add i64 %7, 1, !dbg [[G11R2:!.*]]
// CHECK-NEXT: store i64 %inc4, ptr @i{{.*}}, !dbg [[G11R1:!.*]]
g = ++h, ++i;
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -83,3 +84,4 @@ void fun() {
// CHECK: [[load_i_loc]] = !DILocation(line: [[#]], column: [[#]], scope: ![[#]])
// CHECK: [[G11R2]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 2)
// CHECK: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 12, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/bitfield.cpp b/clang/test/DebugInfo/KeyInstructions/bitfield.cpp
index a14b4fbaf5854..e1d4c264a426a 100644
--- a/clang/test/DebugInfo/KeyInstructions/bitfield.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/bitfield.cpp
@@ -10,7 +10,10 @@ void foo(int x, S s) {
// CHECK: %bf.set = or i8 %bf.clear, %bf.value, !dbg [[G1R2:!.*]]
// CHECK: store i8 %bf.set, ptr %s, align 4, !dbg [[G1R1:!.*]]
s.a = x;
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/builtin.c b/clang/test/DebugInfo/KeyInstructions/builtin.c
index 359d52ca3862e..ce8c6124fe923 100644
--- a/clang/test/DebugInfo/KeyInstructions/builtin.c
+++ b/clang/test/DebugInfo/KeyInstructions/builtin.c
@@ -64,6 +64,7 @@ void fun() {
// CHECK-NEXT: %4 = trunc i32 %3 to i8, !dbg [[G15R2:!.*]]
// CHECK-NEXT: call void @llvm.memset{{.*}}, !dbg [[G15R1:!.*]]
__builtin_memset(f4, v, sizeof(float) * 4);
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
@@ -86,3 +87,4 @@ void fun() {
// CHECK: [[G15R3]] = !DILocation({{.*}}, atomGroup: 15, atomRank: 3)
// CHECK: [[G15R2]] = !DILocation({{.*}}, atomGroup: 15, atomRank: 2)
// CHECK: [[G15R1]] = !DILocation({{.*}}, atomGroup: 15, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 16, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/cast.c b/clang/test/DebugInfo/KeyInstructions/cast.c
index 927a1f2a704c7..62f2c3d1d3e51 100644
--- a/clang/test/DebugInfo/KeyInstructions/cast.c
+++ b/clang/test/DebugInfo/KeyInstructions/cast.c
@@ -13,8 +13,10 @@ void a() {
// CHECK: %conv = fptosi float %0 to i32{{.*}}, !dbg [[G1R2:!.*]]
// CHECK: store i32 %conv, ptr %a{{.*}}, !dbg [[G1R1:!.*]]
int a = g;
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R3]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 3)
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/coerced-packed.c b/clang/test/DebugInfo/KeyInstructions/coerced-packed.c
index 90ec8420b0d8c..1bd2760149705 100644
--- a/clang/test/DebugInfo/KeyInstructions/coerced-packed.c
+++ b/clang/test/DebugInfo/KeyInstructions/coerced-packed.c
@@ -14,7 +14,9 @@ void f() {
// CHECK: [[call:%.*]] = call i40{{.*}}getS{{.*}}, !dbg [[G1R2:!.*]]
// CHECK: store i40 [[call]], ptr %s, align 1, !dbg [[G1R1:!.*]]
S s = getS();
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/coerced-ptr.c b/clang/test/DebugInfo/KeyInstructions/coerced-ptr.c
index 0002e9051220b..1205b312e43c4 100644
--- a/clang/test/DebugInfo/KeyInstructions/coerced-ptr.c
+++ b/clang/test/DebugInfo/KeyInstructions/coerced-ptr.c
@@ -12,8 +12,10 @@ void f() {
// CHECK: [[i2p:%.*]] = inttoptr i64 %call to ptr, !dbg [[G1R2:!.*]]
// CHECK: store ptr [[i2p]], ptr [[gep]], align 8, !dbg [[G1R1:!.*]]
Ptr p = getPtr();
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R3]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 3)
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/coerced-through-memory.c b/clang/test/DebugInfo/KeyInstructions/coerced-through-memory.c
index 98361aa9806ef..f8667b73b111b 100644
--- a/clang/test/DebugInfo/KeyInstructions/coerced-through-memory.c
+++ b/clang/test/DebugInfo/KeyInstructions/coerced-through-memory.c
@@ -18,7 +18,9 @@ void f() {
// CHECK: store [2 x i64] %call, ptr %tmp.coerce, align 8
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %s, ptr align 8 %tmp.coerce, i64 12, i1 false), !dbg [[G1R1:!.*]]
S s = getS();
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/coerced.c b/clang/test/DebugInfo/KeyInstructions/coerced.c
index b5a254fb641c9..036f6d66fa670 100644
--- a/clang/test/DebugInfo/KeyInstructions/coerced.c
+++ b/clang/test/DebugInfo/KeyInstructions/coerced.c
@@ -16,6 +16,7 @@ void test() {
// CHECK: %3 = extractvalue { ptr, ptr } %call, 1, !dbg [[G1R2]]
// CHECK: store ptr %3, ptr {{.*}}, !dbg [[G1R1:!.*]]
Struct s = get();
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
typedef struct { int i; } Int;
@@ -27,10 +28,13 @@ void test2() {
// CHECK: %call = call i32 @{{(_Z6)?}}getInt{{v?}}(), !dbg [[T2_G1R2:!.*]]
// CHECK: [[gep:%.*]] = getelementptr inbounds nuw %struct.Int, ptr %i, i32 0, i32 0
// CHECK: store i32 %call, ptr [[gep]]{{.*}}, !dbg [[T2_G1R1:!.*]]
+// CHECK: ret{{.*}}, !dbg [[T2_RET:!.*]]
Int i = getInt();
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[T2_G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[T2_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[T2_RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/complex.c b/clang/test/DebugInfo/KeyInstructions/complex.c
index 9647d0e4009ee..d5cb67fed99d6 100644
--- a/clang/test/DebugInfo/KeyInstructions/complex.c
+++ b/clang/test/DebugInfo/KeyInstructions/complex.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -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: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-CXX
// RUN: %clang_cc1 -triple x86_64-linux-gnu -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 --check-prefixes=CHECK,CHECK-C
@@ -71,6 +71,7 @@ void test() {
// CHECK-C: store float %mul.rl, ptr @f, align 4, !dbg [[G11R1:!.*]]
f *= ci;
#endif
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
@@ -95,3 +96,5 @@ void test() {
// CHECK-C: [[G10R1]] = !DILocation({{.*}}, atomGroup: 10, atomRank: 1)
// CHECK-C: [[G11R2]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 2)
// CHECK-C: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
+// CHECK-C: [[RET]] = !DILocation({{.*}}, atomGroup: 12, atomRank: 1)
+// CHECK-CXX: [[RET]] = !DILocation({{.*}}, atomGroup: 8, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/do.c b/clang/test/DebugInfo/KeyInstructions/do.c
index 4f0d388f94047..cc3749e6e56c5 100644
--- a/clang/test/DebugInfo/KeyInstructions/do.c
+++ b/clang/test/DebugInfo/KeyInstructions/do.c
@@ -25,9 +25,12 @@ void a(int A) {
// CHECK: %tobool = icmp ne i32 %dec, 0, !dbg [[G2R1:!.*]]
// CHECK: br i1 %tobool, label %do.body, label %do.end, !dbg [[G3R1:!.*]], !llvm.loop
do { } while (--A);
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/for.c b/clang/test/DebugInfo/KeyInstructions/for.c
index 89345db9fb85f..e7c1567c14d60 100644
--- a/clang/test/DebugInfo/KeyInstructions/for.c
+++ b/clang/test/DebugInfo/KeyInstructions/for.c
@@ -27,6 +27,7 @@ void a(int A) {
// CHECK: store i32 %inc, ptr %i{{.*}}, !dbg [[G4R1:!.*]]
for (int i = 0; i < A; ++i) {
}
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
void b(int A) {
@@ -55,6 +56,7 @@ void b(int A) {
if (A > 1)
;
}
+// CHECK: ret{{.*}}, !dbg [[bRET:!.*]]
}
void c(int A) {
@@ -111,6 +113,7 @@ void e() {
// CHECK-NEXT: br label %for.inc, !dbg [[eG4R1:!.*]]
for (; i < 3; ee())
x = i;
+// CHECK: ret{{.*}}, !dbg [[eRET:!.*]]
}
@@ -138,6 +141,7 @@ void g() {
{
break;
}
+// CHECK: ret{{.*}}, !dbg [[gRET:!.*]]
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -146,30 +150,34 @@ void g() {
// CHECK: [[G5R1]] = !DILocation(line: 29,{{.*}} atomGroup: 5, atomRank: 1)
// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
// CHECK: [[bG1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[bG2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[bG3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
// CHECK: [[bG4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[bG4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
-// CHECK: [[bG6R1]] = !DILocation(line: 57,{{.*}} atomGroup: 6, atomRank: 1)
+// CHECK: [[bG6R1]] = !DILocation(line: 58,{{.*}} atomGroup: 6, atomRank: 1)
// CHECK: [[bG5R2]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 2)
// CHECK: [[bG5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
+// CHECK: [[bRET]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 1)
// CHECK: [[cG1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[cG1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
-// CHECK: [[cG3R1]] = !DILocation(line: 81,{{.*}} atomGroup: 3, atomRank: 1)
+// CHECK: [[cG3R1]] = !DILocation(line: 83,{{.*}} atomGroup: 3, atomRank: 1)
// CHECK: [[cG2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
// CHECK: [[cG2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
-// CHECK: [[dG1R1]] = !DILocation(line: 91, column: 3, scope: ![[#]], atomGroup: 1, atomRank: 1)
+// CHECK: [[dG1R1]] = !DILocation(line: 93, column: 3, scope: ![[#]], atomGroup: 1, atomRank: 1)
// CHECK: [[eG1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[eG2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[eG3R2]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 2)
// CHECK: [[eG3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
-// CHECK: [[eG4R1]] = !DILocation(line: 113, column: 5, scope: ![[#]], atomGroup: 4, atomRank: 1)
+// CHECK: [[eG4R1]] = !DILocation(line: 115, column: 5, scope: ![[#]], atomGroup: 4, atomRank: 1)
+// CHECK: [[eRET]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
-// CHECK: [[fG1R1]] = !DILocation(line: 126, column: 5, scope: ![[#]], atomGroup: 1, atomRank: 1)
+// CHECK: [[fG1R1]] = !DILocation(line: 129, column: 5, scope: ![[#]], atomGroup: 1, atomRank: 1)
-// CHECK: [[gG1R1]] = !DILocation(line: 139, column: 5, scope: ![[#]], atomGroup: 1, atomRank: 1)
+// CHECK: [[gG1R1]] = !DILocation(line: 142, column: 5, scope: ![[#]], atomGroup: 1, atomRank: 1)
+// CHECK: [[gRET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/if.c b/clang/test/DebugInfo/KeyInstructions/if.c
index b16dec7b91c4f..edadd04cf0e18 100644
--- a/clang/test/DebugInfo/KeyInstructions/if.c
+++ b/clang/test/DebugInfo/KeyInstructions/if.c
@@ -2,7 +2,7 @@
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-CXX
// RUN: %clang_cc1 -triple x86_64-linux-gnu -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: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-C
int g;
void a(int A) {
@@ -32,6 +32,8 @@ void a(int A) {
if (int B = A; B)
;
#endif
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
@@ -44,3 +46,5 @@ void a(int A) {
// CHECK-CXX: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
// CHECK-CXX: [[G5R2]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 2)
// CHECK-CXX: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
+// CHECK-CXX: [[RET]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
+// CHECK-C: [[RET]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/init-agg.c b/clang/test/DebugInfo/KeyInstructions/init-agg.c
index 1021490bd75b4..711d8ad3de57f 100644
--- a/clang/test/DebugInfo/KeyInstructions/init-agg.c
+++ b/clang/test/DebugInfo/KeyInstructions/init-agg.c
@@ -37,6 +37,8 @@ void a() {
// CHECK: store i8 {{.*}}, ptr %uninit{{.*}}, !dbg [[G5R1:!.*]], !annotation
char uninit; // -ftrivial-auto-var-init=pattern
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
@@ -47,3 +49,4 @@ void a() {
// CHECK: [[big_LINE]] = !DILocation(line: 33, scope: ![[#]])
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/init-member.cpp b/clang/test/DebugInfo/KeyInstructions/init-member.cpp
index 4d8e1b9dace3f..0c45c07886d4f 100644
--- a/clang/test/DebugInfo/KeyInstructions/init-member.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/init-member.cpp
@@ -17,6 +17,8 @@ void fun() {
// CHECK: store i32 1, ptr %x{{.*}}, !dbg [[G1R1:!.*]]
// CHECK: store float 5.000000e+00, ptr %y{{.*}}, !dbg [[G2R1:!.*]]
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/init-scalar.c b/clang/test/DebugInfo/KeyInstructions/init-scalar.c
index d4802a709b89a..217a2496c6751 100644
--- a/clang/test/DebugInfo/KeyInstructions/init-scalar.c
+++ b/clang/test/DebugInfo/KeyInstructions/init-scalar.c
@@ -10,8 +10,10 @@ void a() {
// CHECK: %add = add {{.*}}, !dbg [[G2R2:!.*]]
// CHECK: store i32 %add, ptr %B, align 4, !dbg [[G2R1:!.*]]
int B = 2 * A + 1;
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/init-static.cpp b/clang/test/DebugInfo/KeyInstructions/init-static.cpp
index 2cac57e1d9fff..ee73275edb761 100644
--- a/clang/test/DebugInfo/KeyInstructions/init-static.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/init-static.cpp
@@ -4,10 +4,12 @@
// CHECK: [[b_addr:@.*]] = {{.*}}global ptr
void g(int *a) {
- // CHECK: [[v:%.*]] = load ptr, ptr %a.addr{{.*}}, !dbg [[G1R2:!.*]]
- // CHECK: store ptr [[v]], ptr [[b_addr]]{{.*}}, !dbg [[G1R1:!.*]]
+// CHECK: [[v:%.*]] = load ptr, ptr %a.addr{{.*}}, !dbg [[G1R2:!.*]]
+// CHECK: store ptr [[v]], ptr [[b_addr]]{{.*}}, !dbg [[G1R1:!.*]]
static int &b = *a;
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/multi-func.c b/clang/test/DebugInfo/KeyInstructions/multi-func.c
index 6e225eed81de8..ce311bad00d16 100644
--- a/clang/test/DebugInfo/KeyInstructions/multi-func.c
+++ b/clang/test/DebugInfo/KeyInstructions/multi-func.c
@@ -8,12 +8,17 @@
int g;
// CHECK: store{{.*}}, !dbg [[AG:!.*]]
+// CHECK: ret{{.*}}, !dbg [[ARET:!.*]]
void a() { g = 0; }
// CHECK: store{{.*}}, !dbg [[BG:!.*]]
+// CHECK: ret{{.*}}, !dbg [[BRET:!.*]]
void b() { g = 0; }
// CHECK: [[A:!.*]] = distinct !DISubprogram(name: "a",
-// CHECK: [[AG]] = !DILocation(line: 11, scope: [[A]], atomGroup: 1, atomRank: 1)
+// CHECK: [[AG]] = !DILocation(line: 12, scope: [[A]], atomGroup: 1, atomRank: 1)
+// CHECK: [[ARET]] = !DILocation(line: 12, scope: [[A]], atomGroup: 2, atomRank: 1)
+
// CHECK: [[B:!.*]] = distinct !DISubprogram(name: "b",
-// CHECK: [[BG]] = !DILocation(line: 14, scope: [[B]], atomGroup: 1, atomRank: 1)
+// CHECK: [[BG]] = !DILocation(line: 16, scope: [[B]], atomGroup: 1, atomRank: 1)
+// CHECK: [[BRET]] = !DILocation(line: 16, scope: [[B]], atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/new.cpp b/clang/test/DebugInfo/KeyInstructions/new.cpp
index 5ac2cf31d1380..f939e784a4575 100644
--- a/clang/test/DebugInfo/KeyInstructions/new.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/new.cpp
@@ -18,6 +18,7 @@ void f(int x) {
// CHECK: %3 = load ptr, ptr %n
// CHECK: store i32 %2, ptr %3{{.*}}, !dbg [[G3R1:!.*]]
*n = x;
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2_C12]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
@@ -32,3 +33,5 @@ void f(int x) {
// CHECK: [[G3R2]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 2)
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/return-va-arg.c b/clang/test/DebugInfo/KeyInstructions/return-va-arg.c
new file mode 100644
index 0000000000000..0773bf5353177
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/return-va-arg.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -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 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
+// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank
+
+typedef struct {
+ struct{} a;
+ double b;
+} s1;
+
+s1 f(int z, ...) {
+ __builtin_va_list list;
+ __builtin_va_start(list, z);
+// CHECK: vaarg.end:
+// CHECK-NEXT: %vaarg.addr = phi ptr
+// CHECK-NEXT: call void @llvm.memcpy{{.*}}, !dbg [[G1R1:!.*]]
+// CHECK-NEXT: {{.*}} = getelementptr{{.*}}
+// CHECK-NEXT: [[LOAD:%.*]] = load double{{.*}}, !dbg [[G1R2:!.*]]
+// CHECK-NEXT: ret double [[LOAD]], !dbg [[G1R1]]
+ return __builtin_va_arg(list, s1);
+}
+
+// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
diff --git a/clang/test/DebugInfo/KeyInstructions/return.c b/clang/test/DebugInfo/KeyInstructions/return.c
new file mode 100644
index 0000000000000..c79e9d930f317
--- /dev/null
+++ b/clang/test/DebugInfo/KeyInstructions/return.c
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c++ %s -debug-info-kind=line-tables-only -emit-llvm -o - \
+// RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-CXX
+
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -gkey-instructions -gno-column-info -x c %s -debug-info-kind=line-tables-only -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check the stores to `retval` allocas and branches to `return` block are in
+// the same atom group. They are both rank 1, which could in theory introduce
+// an extra step in some optimized code. This low risk currently feels an
+// acceptable for keeping the code a bit simpler (as opposed to adding
+// scaffolding to make the store rank 2).
+
+// Also check that in the case of a single return (no control flow) the
+// return instruction inherits the atom group of the branch to the return
+// block when the blocks get folded togather.
+
+#ifdef __cplusplus
+#define nomangle extern "C"
+#else
+#define nomangle
+#endif
+
+int g;
+nomangle float a() {
+// CHECK: float @a()
+ if (g)
+// CHECK: if.then:
+// CHECK-NEXT: %1 = load i32, ptr @g{{.*}}, !dbg [[G2R3:!.*]]
+// CHECK-NEXT: %conv = sitofp i32 %1 to float{{.*}}, !dbg [[G2R2:!.*]]
+// CHECK-NEXT: store float %conv, ptr %retval{{.*}}, !dbg [[G2R1:!.*]]
+// CHECK-NEXT: br label %return{{.*}}, !dbg [[G2R1]]
+ return g;
+// CHECK: if.end:
+// CHECK-NEXT: store float 1.000000e+00, ptr %retval{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK-NEXT: br label %return, !dbg [[G3R1]]
+
+// CHECK: return:
+// CHECK-NEXT: %2 = load float, ptr %retval{{.*}}, !dbg [[G4R2:!.*]]
+// CHECK-NEXT: ret float %2{{.*}}, !dbg [[G4R1:!.*]]
+ return 1;
+}
+
+// CHECK: void @b()
+// CHECK: ret void{{.*}}, !dbg [[B_G1R1:!.*]]
+nomangle void b() { return; }
+
+// CHECK: i32 @c()
+// CHECK: %add = add{{.*}}, !dbg [[C_G1R2:!.*]]
+// CHECK: ret i32 %add{{.*}}, !dbg [[C_G1R1:!.*]]
+nomangle int c() { return g + 1; }
+
+// NOTE: (return) (g = 1) are two separate atoms.
+// CHECK: i32 @d()
+// CHECK: store{{.*}}, !dbg [[D_G2R1:!.*]]
+// CHECK: ret i32 1{{.*}}, !dbg [[D_G1R1:!.*]]
+nomangle int d() { return g = 1; }
+
+// The implicit return here get the line number of the closing brace; make it
+// key to match existing behaviour.
+// CHECK: void @e()
+// CHECK: ret void, !dbg [[E_G1R1:!.*]]
+nomangle void e() {}
+
+#ifdef __cplusplus
+// CHECK-CXX: ptr @_Z1fRi
+int &f(int &r) {
+// Include ctrl-flow to stop ret value store being elided.
+ if (r)
+// CHECK-CXX: if.then:
+// CHECK-CXX-NEXT: %2 = load ptr, ptr %r.addr{{.*}}, !dbg [[F_G2R2:!.*]], !nonnull
+// CHECK-CXX-NEXT: store ptr %2, ptr %retval{{.*}}, !dbg [[F_G2R1:!.*]]
+// CHECK-CXX-NEXT: br label %return, !dbg [[F_G2R1:!.*]]
+ return r;
+
+// CHECK-CXX: if.end:
+// CHECK-CXX-NEXT: store ptr @g, ptr %retval{{.*}}, !dbg [[F_G3R1:!.*]]
+// CHECK-CXX-NEXT: br label %return, !dbg [[F_G3R1:!.*]]
+// CHECK-CXX: return:
+// CHECK-CXX-NEXT: %3 = load ptr, ptr %retval{{.*}}, !dbg [[F_G4R2:!.*]]
+// CHECK-CXX-NEXT: ret ptr %3, !dbg [[F_G4R1:!.*]]
+ return g;
+}
+#endif
+
+// CHECK: [[G2R3]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 3)
+// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
+// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[B_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[C_G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
+// CHECK: [[C_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[D_G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK: [[D_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[E_G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK-CXX: [[F_G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK-CXX: [[F_G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
+// CHECK-CXX: [[F_G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK-CXX: [[F_G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
+// CHECK-CXX: [[F_G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/switch.c b/clang/test/DebugInfo/KeyInstructions/switch.c
index 96b18592621d5..cd8fced67eed9 100644
--- a/clang/test/DebugInfo/KeyInstructions/switch.c
+++ b/clang/test/DebugInfo/KeyInstructions/switch.c
@@ -2,7 +2,7 @@
// RUN: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-CXX
// RUN: %clang_cc1 -triple x86_64-linux-gnu -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: | FileCheck %s --implicit-check-not atomGroup --implicit-check-not atomRank --check-prefixes=CHECK,CHECK-C
int g;
void a(int A, int B) {
@@ -40,6 +40,7 @@ void a(int A, int B) {
}
};
}
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
@@ -49,3 +50,5 @@ void a(int A, int B) {
// CHECK: [[G4R2]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 2)
// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
// CHECK-CXX: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
+// CHECK-CXX: [[RET]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
+// CHECK-C: [[RET]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/try-catch.cpp b/clang/test/DebugInfo/KeyInstructions/try-catch.cpp
index 918eb4c97db9a..c1887bc525187 100644
--- a/clang/test/DebugInfo/KeyInstructions/try-catch.cpp
+++ b/clang/test/DebugInfo/KeyInstructions/try-catch.cpp
@@ -14,7 +14,10 @@ void attempt() {
// CHECK: store i32 %5, ptr %e{{.*}}, !dbg [[G1R1:!.*]]
// CHECK: call void @__cxa_end_catch()
catch (int e) { }
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
diff --git a/clang/test/DebugInfo/KeyInstructions/while.c b/clang/test/DebugInfo/KeyInstructions/while.c
index 38cdb8433dd27..9c9eab399f345 100644
--- a/clang/test/DebugInfo/KeyInstructions/while.c
+++ b/clang/test/DebugInfo/KeyInstructions/while.c
@@ -26,9 +26,12 @@ void a(int A) {
// CHECK: %tobool = icmp ne i32 %dec, 0, !dbg [[G2R1:!.*]]
// CHECK: br i1 %tobool, label %while.body, label %while.end, !dbg [[G3R1:!.*]]
while (--A) { };
+
+// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
}
// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
+// CHECK: [[RET]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
More information about the cfe-commits
mailing list