[clang] [clang][DebugInfo] Add inlined subprogram metadata for compiler built-ins (PR #189969)
J. Ryan Stinnett via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 16 03:44:05 PDT 2026
https://github.com/jryans updated https://github.com/llvm/llvm-project/pull/189969
>From 5c58ea209cb9d91abad168f0eef5695ff63e81f0 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <ryan at convolv.es>
Date: Wed, 1 Apr 2026 15:09:06 +0100
Subject: [PATCH 1/5] [clang][DebugInfo] Add inlined subprogram metadata for
compiler built-ins
This wraps compiler built-ins in an artificial inlined subprogram for
debug info purposes. This makes compiler built-in usage legible to debug
info consumers like profilers, which can then annotate time spent with
the built-in function name. For example, calls to e.g.
`__builtin_alloca` and `__builtin_memset` become visible to profilers
and debuggers, improving the correspondence to the source program.
---
clang/lib/CodeGen/CGBuiltin.cpp | 5 +++++
clang/lib/CodeGen/CGDebugInfo.cpp | 21 +++++++++++++++++++++
clang/lib/CodeGen/CGDebugInfo.h | 16 ++++++++++++++++
clang/test/DebugInfo/Generic/builtin.c | 26 ++++++++++++++++++++++++++
4 files changed, 68 insertions(+)
create mode 100644 clang/test/DebugInfo/Generic/builtin.c
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4d74d681cd320..3bb1977094cf9 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2648,6 +2648,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
assert(!getContext().BuiltinInfo.isImmediate(BuiltinID) &&
"Should not codegen for consteval builtins");
+ // Treat built-in as call to artificial inlined function in debug info.
+ // This enables e.g. profiling tools to annotate time spent in user-called
+ // built-ins with the built-in function name.
+ ApplyBuiltinDebugLocation DebugScope(*this, GD);
+
const FunctionDecl *FD = GD.getDecl()->getAsFunction();
// See if we can constant fold this builtin. If so, don't emit it at all.
// TODO: Extend this handling to all builtin calls that we can constant-fold.
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index dbd400343d9e1..cd056dfae25fe 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -347,6 +347,19 @@ ApplyInlineDebugLocation::~ApplyInlineDebugLocation() {
DI.EmitLocation(CGF->Builder, SavedLocation);
}
+static llvm::DILocation *createBuiltinInlineAt(CodeGenFunction &CGF,
+ GlobalDecl GD) {
+ if (!CGF.getDebugInfo()) {
+ return nullptr;
+ }
+ auto &DI = *CGF.getDebugInfo();
+ return DI.createBuiltinFunctionLocation(CGF.Builder, GD);
+}
+
+ApplyBuiltinDebugLocation::ApplyBuiltinDebugLocation(CodeGenFunction &CGF,
+ GlobalDecl BuiltinFn)
+ : Apply(CGF, createBuiltinInlineAt(CGF, BuiltinFn)) {}
+
void CGDebugInfo::setLocation(SourceLocation Loc) {
// If the new location isn't valid return.
if (Loc.isInvalid())
@@ -5122,6 +5135,14 @@ void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
}
+llvm::DILocation *
+CGDebugInfo::createBuiltinFunctionLocation(CGBuilderTy &Builder,
+ GlobalDecl GD) {
+ const auto *FD = cast<FunctionDecl>(GD.getDecl());
+ return CreateSyntheticInlineAt(Builder.getCurrentDebugLocation(),
+ getFunctionName(FD));
+}
+
void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
// Update our current location
setLocation(Loc);
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 8e1eda2d93ac0..93fef4f06b656 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -503,6 +503,10 @@ class CGDebugInfo {
/// End an inlined function scope.
void EmitInlineFunctionEnd(CGBuilderTy &Builder);
+ /// Create location for an inlined built-in function.
+ llvm::DILocation *createBuiltinFunctionLocation(CGBuilderTy &Builder,
+ GlobalDecl GD);
+
/// Emit debug info for a function declaration.
/// \p Fn is set only when a declaration for a debug call site gets created.
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
@@ -995,6 +999,18 @@ class ApplyInlineDebugLocation {
ApplyInlineDebugLocation &operator=(ApplyInlineDebugLocation &) = delete;
};
+/// A scoped helper to set the current debug location to a inlined location for
+/// a built-in function. The function is marked as artificial in debug info to
+/// convey the built-in aspect.
+class ApplyBuiltinDebugLocation {
+ ApplyDebugLocation Apply;
+
+public:
+ ApplyBuiltinDebugLocation(CodeGenFunction &CGF, GlobalDecl BuiltinFn);
+ ApplyBuiltinDebugLocation(const ApplyBuiltinDebugLocation &) = delete;
+ ApplyBuiltinDebugLocation &operator=(ApplyBuiltinDebugLocation &) = delete;
+};
+
class SanitizerDebugLocation {
CodeGenFunction *CGF;
ApplyDebugLocation Apply;
diff --git a/clang/test/DebugInfo/Generic/builtin.c b/clang/test/DebugInfo/Generic/builtin.c
new file mode 100644
index 0000000000000..396b8024e8566
--- /dev/null
+++ b/clang/test/DebugInfo/Generic/builtin.c
@@ -0,0 +1,26 @@
+
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -debug-info-kind=limited -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+void fun() {
+ // CHECK: %0 = alloca i8, i64 4{{.*}}, !dbg [[B1:!.*]]
+ void *a = __builtin_alloca(4);
+
+ // CHECK: %1 = alloca i8, i64 4{{.*}}, !dbg [[B2:!.*]]
+ // Ensure calling same built-in twice only produces one `DISubprogram` entry
+ void *b = __builtin_alloca(4);
+
+ // CHECK: call void @llvm.memset{{.*}}, !dbg [[B3:!.*]]
+ __builtin_memset(a, 0, 4);
+}
+
+// CHECK: [[B1]] = !DILocation(line: 0, scope: [[S1:!.*]], inlinedAt: [[I1:!.*]])
+// CHECK: [[S1]] = distinct !DISubprogram(name: "__builtin_alloca"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I1]] = !DILocation(line: 6,
+
+// Second call should reuse same `DISubprogram` scope
+// CHECK: [[B2]] = !DILocation(line: 0, scope: [[S1:!.*]], inlinedAt: [[I2:!.*]])
+// CHECK: [[I2]] = !DILocation(line: 10,
+
+// CHECK: [[B3]] = !DILocation(line: 0, scope: [[S3:!.*]], inlinedAt: [[I3:!.*]])
+// CHECK: [[S3]] = distinct !DISubprogram(name: "__builtin_memset"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I3]] = !DILocation(line: 13,
>From c5adbe7ab5bca01a0d0007d5c64d9a27f1ea0324 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <ryan at convolv.es>
Date: Wed, 8 Apr 2026 15:03:55 +0100
Subject: [PATCH 2/5] Exclude various non-call-like built-ins
Several categories of built-ins should not be part of the artificial
inlined function debug info treatment:
- target-specific built-ins
- library functions emitted as direct calls
- optimisation hint built-ins
- trap and exception built-ins
- annotation built-ins
---
clang/lib/CodeGen/CGBuiltin.cpp | 73 +++++++++++++++++++++++++-
clang/lib/CodeGen/CGDebugInfo.h | 2 -
clang/test/DebugInfo/Generic/builtin.c | 35 ++++++++++--
3 files changed, 102 insertions(+), 8 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 3bb1977094cf9..0024f05ed1d3a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2642,6 +2642,65 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
return RValue::get(CGF->Builder.CreateCall(UBF, Args));
}
+/// Determines whether we should treat a given built-in as a call to an
+/// artificial inlined function in debug info.
+static bool shouldUseBuiltinDebugLocation(unsigned BuiltinID) {
+ switch (BuiltinID) {
+ case Builtin::BI__builtin_unpredictable:
+ case Builtin::BI__builtin_expect:
+ case Builtin::BI__builtin_expect_with_probability:
+ case Builtin::BI__builtin_assume_aligned:
+ case Builtin::BI__builtin_assume_dereferenceable:
+ case Builtin::BI__assume:
+ case Builtin::BI__builtin_assume:
+ case Builtin::BI__builtin_assume_separate_storage:
+ case Builtin::BI__builtin_allow_runtime_check:
+ case Builtin::BI__builtin_allow_sanitize_check:
+ case Builtin::BI__builtin_constant_p:
+ case Builtin::BI__builtin_prefetch:
+ case Builtin::BI__builtin___clear_cache:
+ case Builtin::BI__builtin_unreachable: {
+ // Exclude optimisation hint built-ins. These are a form of communicating
+ // additional constraints to the compiler.
+ return false;
+ }
+ case Builtin::BI__builtin_trap:
+ case Builtin::BI__builtin_verbose_trap:
+ case Builtin::BI__debugbreak:
+ case Builtin::BI__builtin_eh_return:
+ case Builtin::BI__builtin_unwind_init:
+ case Builtin::BI__exception_code:
+ case Builtin::BI_exception_code:
+ case Builtin::BI__exception_info:
+ case Builtin::BI_exception_info:
+ case Builtin::BI__abnormal_termination:
+ case Builtin::BI_abnormal_termination: {
+ // Exclude trap and exception built-ins. These may use their own debug
+ // location handling, so we avoid making debug changes so they may inspect
+ // the caller as-is without additional debug info layers.
+ return false;
+ }
+ case Builtin::BI__annotation:
+ case Builtin::BI__builtin_annotation: {
+ // Exclude annotation built-ins. These attach debug-time information.
+ return false;
+ }
+ case Builtin::BI__builtin_operator_new:
+ case Builtin::BI__builtin_operator_delete: {
+ // Exclude C++ operator built-ins. These are emitted as normal calls.
+ return false;
+ }
+ }
+
+ // Most generic (non-target-specific) built-ins are call-like, so we default
+ // to enabling this debug info treatment.
+ return true;
+
+ // See also further exclusions of library functions emitted as normal calls
+ // and target-specific built-ins towards the end of `EmitBuiltinExpr` which
+ // overrides the value returned here.
+}
+
RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
@@ -2651,7 +2710,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
// Treat built-in as call to artificial inlined function in debug info.
// This enables e.g. profiling tools to annotate time spent in user-called
// built-ins with the built-in function name.
- ApplyBuiltinDebugLocation DebugScope(*this, GD);
+ // See `useBuiltinDebugLocation` for cases where this treatment is disabled.
+ auto DebugScope =
+ shouldUseBuiltinDebugLocation(BuiltinID)
+ ? std::make_optional<ApplyBuiltinDebugLocation>(*this, GD)
+ : std::nullopt;
const FunctionDecl *FD = GD.getDecl()->getAsFunction();
// See if we can constant fold this builtin. If so, don't emit it at all.
@@ -6490,6 +6553,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
}
}
+ // All cases beyond this point are excluded from the artificial inlined
+ // function in debug info treatment:
+ // - library functions handled below are emitted as normal calls, so an
+ // inlined wrapper of the same function is redundant
+ // - target-specific built-ins are mainly assembly-like concepts, so they
+ // should not be recorded in debug info as if they were calls
+ DebugScope = std::nullopt;
+
// If this is an alias for a lib function (e.g. __builtin_sin), emit
// the call using the normal call path, but using the unmangled
// version of the function name.
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 93fef4f06b656..30000d12d7cdc 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -1007,8 +1007,6 @@ class ApplyBuiltinDebugLocation {
public:
ApplyBuiltinDebugLocation(CodeGenFunction &CGF, GlobalDecl BuiltinFn);
- ApplyBuiltinDebugLocation(const ApplyBuiltinDebugLocation &) = delete;
- ApplyBuiltinDebugLocation &operator=(ApplyBuiltinDebugLocation &) = delete;
};
class SanitizerDebugLocation {
diff --git a/clang/test/DebugInfo/Generic/builtin.c b/clang/test/DebugInfo/Generic/builtin.c
index 396b8024e8566..f6aa94de53f21 100644
--- a/clang/test/DebugInfo/Generic/builtin.c
+++ b/clang/test/DebugInfo/Generic/builtin.c
@@ -2,25 +2,50 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -debug-info-kind=limited -emit-llvm -disable-llvm-passes -o - | FileCheck %s
void fun() {
+ // Most call-like built-ins are wrapped in an artificial inlined function in
+ // debug info, making them visible to e.g. profiling tools.
// CHECK: %0 = alloca i8, i64 4{{.*}}, !dbg [[B1:!.*]]
void *a = __builtin_alloca(4);
+ // Ensure calling same built-in only produces one `DISubprogram` entry.
// CHECK: %1 = alloca i8, i64 4{{.*}}, !dbg [[B2:!.*]]
- // Ensure calling same built-in twice only produces one `DISubprogram` entry
void *b = __builtin_alloca(4);
// CHECK: call void @llvm.memset{{.*}}, !dbg [[B3:!.*]]
__builtin_memset(a, 0, 4);
+
+ // Ensure certain built-ins like optimisation hints are excluded.
+ // CHECK: call void @llvm.assume{{.*}}, !dbg [[B4:!.*]]
+ __builtin_assume(a != 0);
+
+ // Ensure target-specific built-ins are excluded.
+ // CHECK: call i64 @llvm.x86.rdtsc(), !dbg [[B5:!.*]]
+ __builtin_ia32_rdtsc();
+
+ // Ensure library functions emitted as normal calls are excluded.
+ // CHECK: call ptr @malloc{{.*}}, !dbg [[B6:!.*]]
+ void *c = __builtin_malloc(4);
}
// CHECK: [[B1]] = !DILocation(line: 0, scope: [[S1:!.*]], inlinedAt: [[I1:!.*]])
// CHECK: [[S1]] = distinct !DISubprogram(name: "__builtin_alloca"{{.*}}, flags: DIFlagArtificial
-// CHECK: [[I1]] = !DILocation(line: 6,
+// CHECK: [[I1]] = !DILocation(line: 8,
-// Second call should reuse same `DISubprogram` scope
+// Second call should reuse same `DISubprogram` scope.
// CHECK: [[B2]] = !DILocation(line: 0, scope: [[S1:!.*]], inlinedAt: [[I2:!.*]])
-// CHECK: [[I2]] = !DILocation(line: 10,
+// CHECK: [[I2]] = !DILocation(line: 12,
// CHECK: [[B3]] = !DILocation(line: 0, scope: [[S3:!.*]], inlinedAt: [[I3:!.*]])
// CHECK: [[S3]] = distinct !DISubprogram(name: "__builtin_memset"{{.*}}, flags: DIFlagArtificial
-// CHECK: [[I3]] = !DILocation(line: 13,
+// CHECK: [[I3]] = !DILocation(line: 15,
+
+// Excluded built-ins should use location without inlined function wrapper.
+
+// CHECK: [[B4]] = !DILocation(line: 19,
+// CHECK-NOT: distinct !DISubprogram(name: "__builtin_assume"{{.*}}, flags: DIFlagArtificial
+
+// CHECK: [[B5]] = !DILocation(line: 23,
+// CHECK-NOT: distinct !DISubprogram(name: "__builtin_ia32_rdtsc"{{.*}}, flags: DIFlagArtificial
+
+// CHECK: [[B6]] = !DILocation(line: 27,
+// CHECK-NOT: distinct !DISubprogram(name: "__builtin_malloc"{{.*}}, flags: DIFlagArtificial
>From 16306a8eff2964b247e98f9fe0609468e8940391 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <ryan at convolv.es>
Date: Wed, 1 Apr 2026 15:26:16 +0100
Subject: [PATCH 3/5] Adjust test KeyInstructions/builtin.c for inlined
compiler built-ins
---
.../test/DebugInfo/KeyInstructions/builtin.c | 102 +++++++++++-------
1 file changed, 65 insertions(+), 37 deletions(-)
diff --git a/clang/test/DebugInfo/KeyInstructions/builtin.c b/clang/test/DebugInfo/KeyInstructions/builtin.c
index ce8c6124fe923..c7f63ff8420df 100644
--- a/clang/test/DebugInfo/KeyInstructions/builtin.c
+++ b/clang/test/DebugInfo/KeyInstructions/builtin.c
@@ -13,78 +13,106 @@ int v = 3;
void fun() {
// CHECK: %a = alloca ptr, align 8
-// CHECK: %0 = alloca i8, i64 4{{.*}}, !dbg [[G1R2:!.*]]
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G1R1:!.*]], !annotation
+// CHECK: %0 = alloca i8, i64 4{{.*}}, !dbg [[B1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B1:!.*]], !annotation
// CHECK: store ptr %0, ptr %a{{.*}}, !dbg [[G1R1:!.*]]
void *a = __builtin_alloca(4);
-// CHECK: %1 = alloca i8, i64 4{{.*}}, !dbg [[G2R2:!.*]]
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G2R1:!.*]], !annotation
+// CHECK: %1 = alloca i8, i64 4{{.*}}, !dbg [[B2:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B2:!.*]], !annotation
// CHECK: store ptr %1, ptr %b{{.*}}, !dbg [[G2R1:!.*]]
void *b = __builtin_alloca_with_align(4, 8);
// CHECK: %2 = load <4 x float>, ptr @mat{{.*}}, !dbg [[G3R2:!.*]]
-// CHECK: call void @llvm.matrix.column.major.store.v4f32{{.*}}, !dbg [[G3R1:!.*]]
+// CHECK: call void @llvm.matrix.column.major.store.v4f32{{.*}}, !dbg [[B3:!.*]]
__builtin_matrix_column_major_store(mat, f4, sizeof(float) * 2);
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G4R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B4:!.*]]
__builtin_bzero(f4, sizeof(float) * 2);
-// CHECK: call void @llvm.memmove{{.*}}, !dbg [[G5R1:!.*]]
+// CHECK: call void @llvm.memmove{{.*}}, !dbg [[B5:!.*]]
__builtin_bcopy(f4, f8, sizeof(float) * 4);
-// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G6R1:!.*]]
+// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[B6:!.*]]
__builtin_memcpy(f4, f8, sizeof(float) * 4);
-// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G7R1:!.*]]
+// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[B7:!.*]]
__builtin_mempcpy(f4, f8, sizeof(float) * 4);
-// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G8R1:!.*]]
+// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[B8:!.*]]
__builtin_memcpy_inline(f4, f8, sizeof(float) * 4);
-// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[G9R1:!.*]]
+// CHECK: call void @llvm.memcpy{{.*}}, !dbg [[B9:!.*]]
__builtin___memcpy_chk(f4, f8, sizeof(float) * 4, -1);
-// CHECK: call void @llvm.memmove{{.*}}, !dbg [[G10R1:!.*]]
+// CHECK: call void @llvm.memmove{{.*}}, !dbg [[B10:!.*]]
__builtin___memmove_chk(f4, f8, sizeof(float) * 4, -1);
-// CHECK: call void @llvm.memmove{{.*}}, !dbg [[G11R1:!.*]]
+// CHECK: call void @llvm.memmove{{.*}}, !dbg [[B11:!.*]]
__builtin_memmove(f4, f8, sizeof(float) * 4);
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G12R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B12:!.*]]
__builtin_memset(f4, 0, sizeof(float) * 4);
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G13R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B13:!.*]]
__builtin_memset_inline(f4, 0, sizeof(float) * 4);
-// CHECK: call void @llvm.memset{{.*}}, !dbg [[G14R1:!.*]]
+// CHECK: call void @llvm.memset{{.*}}, !dbg [[B14:!.*]]
__builtin___memset_chk(f4, 0, sizeof(float), -1);
-// CHECK: %3 = load i32, ptr @v{{.*}}, !dbg [[G15R3:!.*]]
-// CHECK-NEXT: %4 = trunc i32 %3 to i8, !dbg [[G15R2:!.*]]
-// CHECK-NEXT: call void @llvm.memset{{.*}}, !dbg [[G15R1:!.*]]
+// CHECK: %3 = load i32, ptr @v{{.*}}, !dbg [[G4R3:!.*]]
+// CHECK-NEXT: %4 = trunc i32 %3 to i8, !dbg [[B15:!.*]]
+// CHECK-NEXT: call void @llvm.memset{{.*}}, !dbg [[B15:!.*]]
__builtin_memset(f4, v, sizeof(float) * 4);
-// CHECK: ret{{.*}}, !dbg [[RET:!.*]]
+// CHECK: ret{{.*}}, !dbg [[G5R1:!.*]]
}
-// CHECK: [[G1R2]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 2)
+// CHECK: [[B1]] = !DILocation(line: 0, scope: [[S1:!.*]], inlinedAt: [[I1:!.*]])
+// CHECK: [[S1]] = distinct !DISubprogram(name: "__builtin_alloca"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I1]] = !DILocation(line: 19,
// CHECK: [[G1R1]] = !DILocation({{.*}}, atomGroup: 1, atomRank: 1)
-// CHECK: [[G2R2]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 2)
+// CHECK: [[B2]] = !DILocation(line: 0, scope: [[S2:!.*]], inlinedAt: [[I2:!.*]])
+// CHECK: [[S2]] = distinct !DISubprogram(name: "__builtin_alloca_with_align"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I2]] = !DILocation(line: 24,
// CHECK: [[G2R1]] = !DILocation({{.*}}, atomGroup: 2, atomRank: 1)
// CHECK: [[G3R2]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 2)
-// CHECK: [[G3R1]] = !DILocation({{.*}}, atomGroup: 3, atomRank: 1)
-// CHECK: [[G4R1]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 1)
+// CHECK: [[B3]] = !DILocation(line: 0, scope: [[S3:!.*]], inlinedAt: [[I3:!.*]])
+// CHECK: [[S3]] = distinct !DISubprogram(name: "__builtin_matrix_column_major_store"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I3]] = !DILocation(line: 28,
+// CHECK: [[B4]] = !DILocation(line: 0, scope: [[S4:!.*]], inlinedAt: [[I4:!.*]])
+// CHECK: [[S4]] = distinct !DISubprogram(name: "__builtin_bzero"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I4]] = !DILocation(line: 31,
+// CHECK: [[B5]] = !DILocation(line: 0, scope: [[S5:!.*]], inlinedAt: [[I5:!.*]])
+// CHECK: [[S5]] = distinct !DISubprogram(name: "__builtin_bcopy"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I5]] = !DILocation(line: 34,
+// CHECK: [[B6]] = !DILocation(line: 0, scope: [[S6:!.*]], inlinedAt: [[I6:!.*]])
+// CHECK: [[S6]] = distinct !DISubprogram(name: "__builtin_memcpy"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I6]] = !DILocation(line: 37,
+// CHECK: [[B7]] = !DILocation(line: 0, scope: [[S7:!.*]], inlinedAt: [[I7:!.*]])
+// CHECK: [[S7]] = distinct !DISubprogram(name: "__builtin_mempcpy"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I7]] = !DILocation(line: 40,
+// CHECK: [[B8]] = !DILocation(line: 0, scope: [[S8:!.*]], inlinedAt: [[I8:!.*]])
+// CHECK: [[S8]] = distinct !DISubprogram(name: "__builtin_memcpy_inline"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I8]] = !DILocation(line: 43,
+// CHECK: [[B9]] = !DILocation(line: 0, scope: [[S9:!.*]], inlinedAt: [[I9:!.*]])
+// CHECK: [[S9]] = distinct !DISubprogram(name: "__builtin___memcpy_chk"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I9]] = !DILocation(line: 46,
+// CHECK: [[B10]] = !DILocation(line: 0, scope: [[S10:!.*]], inlinedAt: [[I10:!.*]])
+// CHECK: [[S10]] = distinct !DISubprogram(name: "__builtin___memmove_chk"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I10]] = !DILocation(line: 49,
+// CHECK: [[B11]] = !DILocation(line: 0, scope: [[S11:!.*]], inlinedAt: [[I11:!.*]])
+// CHECK: [[S11]] = distinct !DISubprogram(name: "__builtin_memmove"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I11]] = !DILocation(line: 52,
+// CHECK: [[B12]] = !DILocation(line: 0, scope: [[S12:!.*]], inlinedAt: [[I12:!.*]])
+// CHECK: [[S12]] = distinct !DISubprogram(name: "__builtin_memset"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I12]] = !DILocation(line: 55,
+// CHECK: [[B13]] = !DILocation(line: 0, scope: [[S13:!.*]], inlinedAt: [[I13:!.*]])
+// CHECK: [[S13]] = distinct !DISubprogram(name: "__builtin_memset_inline"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I13]] = !DILocation(line: 58,
+// CHECK: [[B14]] = !DILocation(line: 0, scope: [[S14:!.*]], inlinedAt: [[I14:!.*]])
+// CHECK: [[S14]] = distinct !DISubprogram(name: "__builtin___memset_chk"{{.*}}, flags: DIFlagArtificial
+// CHECK: [[I14]] = !DILocation(line: 61,
+// CHECK: [[G4R3]] = !DILocation({{.*}}, atomGroup: 4, atomRank: 3)
+// CHECK: [[B15]] = !DILocation(line: 0, scope: [[S12]], inlinedAt: [[I15:!.*]])
+// CHECK: [[I15]] = !DILocation(line: 66,
// CHECK: [[G5R1]] = !DILocation({{.*}}, atomGroup: 5, atomRank: 1)
-// CHECK: [[G6R1]] = !DILocation({{.*}}, atomGroup: 6, atomRank: 1)
-// CHECK: [[G7R1]] = !DILocation({{.*}}, atomGroup: 7, atomRank: 1)
-// CHECK: [[G8R1]] = !DILocation({{.*}}, atomGroup: 8, atomRank: 1)
-// CHECK: [[G9R1]] = !DILocation({{.*}}, atomGroup: 9, atomRank: 1)
-// CHECK: [[G10R1]] = !DILocation({{.*}}, atomGroup: 10, atomRank: 1)
-// CHECK: [[G11R1]] = !DILocation({{.*}}, atomGroup: 11, atomRank: 1)
-// CHECK: [[G12R1]] = !DILocation({{.*}}, atomGroup: 12, atomRank: 1)
-// CHECK: [[G13R1]] = !DILocation({{.*}}, atomGroup: 13, atomRank: 1)
-// CHECK: [[G14R1]] = !DILocation({{.*}}, atomGroup: 14, atomRank: 1)
-// 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)
>From 32f72e24ec1d1e81c959bf6946cbcaec4c434246 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <ryan at convolv.es>
Date: Thu, 2 Apr 2026 14:37:51 +0100
Subject: [PATCH 4/5] Adjust test
CodeGenOpenCL/enqueue-kernel-non-entry-block.cl for inlined compiler
built-ins
---
clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl b/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl
index 8e970f121bca8..e927a188afc13 100644
--- a/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl
+++ b/clang/test/CodeGenOpenCL/enqueue-kernel-non-entry-block.cl
@@ -18,7 +18,7 @@ kernel void test(int i) {
// SPIR64: %block_sizes = alloca [1 x i64]
// COMMON-LABEL: if.then:
// COMMON-NOT: alloca
-// CHECK-DEBUG: getelementptr {{.*}} %block_sizes{{.*}}, {{.*}} !dbg ![[TEMPLOCATION:[0-9]+]]
+// CHECK-DEBUG: getelementptr {{.*}} %block_sizes{{.*}}, {{.*}} !dbg ![[BUILTINLOCATION:[0-9]+]]
// COMMON-LABEL: if.end
queue_t default_queue;
unsigned flags = 0;
@@ -38,4 +38,6 @@ kernel void test(int i) {
// CHECK-DEBUG: ![[TESTFILE:[0-9]+]] = !DIFile(filename: "<stdin>"
// CHECK-DEBUG: ![[TESTSCOPE:[0-9]+]] = distinct !DISubprogram(name: "test", linkageName: "__clang_ocl_kern_imp_test", {{.*}} file: ![[TESTFILE]]
// CHECK-DEBUG: ![[IFSCOPE:[0-9]+]] = distinct !DILexicalBlock(scope: ![[TESTSCOPE]], file: ![[TESTFILE]], line: 26)
-// CHECK-DEBUG: ![[TEMPLOCATION]] = !DILocation(line: 27, scope: ![[IFSCOPE]])
+// CHECK-DEBUG: ![[TEMPLOCATION:[0-9]+]] = !DILocation(line: 27, scope: ![[IFSCOPE]])
+// CHECK-DEBUG: ![[BUILTINLOCATION]] = !DILocation(line: 0, scope: ![[BUILTINSCOPE:[0-9]+]], inlinedAt: ![[TEMPLOCATION]])
+// CHECK-DEBUG: ![[BUILTINSCOPE]] = distinct !DISubprogram(name: "enqueue_kernel"{{.*}}, flags: DIFlagArtificial
>From 4e55f4f036b05d1896cc2f4c8f0435770b0128e5 Mon Sep 17 00:00:00 2001
From: "J. Ryan Stinnett" <ryan at convolv.es>
Date: Tue, 14 Apr 2026 17:37:55 +0100
Subject: [PATCH 5/5] Fix constructor type comment
---
clang/lib/CodeGen/CGDebugInfo.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 30000d12d7cdc..5a5c417b391b3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -939,7 +939,7 @@ class ApplyDebugLocation {
Other.CGF = nullptr;
}
- // Define copy assignment operator.
+ // Define move assignment operator.
ApplyDebugLocation &operator=(ApplyDebugLocation &&Other) {
if (this != &Other) {
CGF = Other.CGF;
More information about the cfe-commits
mailing list