[llvm-branch-commits] [LowerTypeTests] Add debug info to jump table entries (PR #192736)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Apr 17 13:54:12 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Vitaly Buka (vitalybuka)
<details>
<summary>Changes</summary>
When Control Flow Integrity (CFI) is enabled, jump tables are used to
redirect indirect calls. Previously, these jump table entries lacked
debug information, making it difficult for profilers and debuggers to
attribute execution time correctly.
---
Full diff: https://github.com/llvm/llvm-project/pull/192736.diff
3 Files Affected:
- (modified) llvm/lib/Transforms/IPO/LowerTypeTests.cpp (+35)
- (modified) llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll (+11-4)
- (modified) llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll (+22-8)
``````````diff
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index a390b983b1ded..cf653ab15beea 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -1529,11 +1529,46 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
}
+static llvm::DILocation *createDebugInfo(Function *F) {
+ Module &M = *F->getParent();
+ DICompileUnit *CU = nullptr;
+ auto CUs = M.debug_compile_units();
+ if (!CUs.empty())
+ CU = *CUs.begin();
+
+ DIBuilder DIB(M, /*AllowUnresolved=*/true, CU);
+ llvm::DIFile *File = DIB.createFile("ubsan_interface.h", "sanitizer");
+ if (!CU) {
+ CU = DIB.createCompileUnit(
+ DISourceLanguageName(dwarf::DW_LANG_C), File, "llvm", true, "", 0, "",
+ DICompileUnit::DebugEmissionKind::LineTablesOnly);
+ }
+
+ DISubroutineType *DIFnTy = DIB.createSubroutineType(nullptr);
+
+ llvm::DISubprogram *NormalSP = DIB.createFunction(
+ File, F->getName(), StringRef(), File, 0, DIFnTy, 0,
+ DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+ F->setSubprogram(NormalSP);
+
+ llvm::DISubprogram *InlineSP = DIB.createFunction(
+ File, "__ubsan_check_cfi_icall_jt", StringRef(), File, 0, DIFnTy, 0,
+ DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
+
+ DIB.finalize();
+
+ return llvm::DILocation::get(
+ M.getContext(), 0, 0, InlineSP,
+ llvm::DILocation::get(M.getContext(), 0, 0, NormalSP));
+}
+
void LowerTypeTestsModule::createJumpTable(
Function *F, ArrayRef<GlobalTypeMember *> Functions,
Triple::ArchType JumpTableArch) {
BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
IRBuilder<> IRB(BB);
+ if (ClAnnotateDebugInfo)
+ IRB.SetCurrentDebugLocation(createDebugInfo(F));
InlineAsm *JumpTableAsm = createJumpTableEntryAsm(JumpTableArch);
diff --git a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
index 00c11b5b85bc7..e3e6de3d76c31 100644
--- a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
+++ b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll
@@ -85,9 +85,9 @@ define i1 @foo(ptr %p) {
; AARCH64_DBG: Function Attrs: naked noinline
; AARCH64_DBG-LABEL: @.cfi.jumptable(
; AARCH64_DBG-NEXT: entry:
-; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi)
-; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi)
-; AARCH64_DBG-NEXT: unreachable
+; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; AARCH64_DBG-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; AARCH64_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;.
; AARCH64: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -102,5 +102,12 @@ define i1 @foo(ptr %p) {
; AARCH64: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
;.
; AARCH64_DBG: [[META0:![0-9]+]] = !{i32 4, !"branch-target-enforcement", i32 1}
-; AARCH64_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; AARCH64_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; AARCH64_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; AARCH64_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; AARCH64_DBG: [[META5]] = !DISubroutineType(types: null)
+; AARCH64_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; AARCH64_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; AARCH64_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
diff --git a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
index 4a8cb0166cc12..e752392b1f058 100644
--- a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
+++ b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll
@@ -112,9 +112,9 @@ define i1 @foo(ptr %p) {
;
; X86_32_DBG-LABEL: @.cfi.jumptable(
; X86_32_DBG-NEXT: entry:
-; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_32_DBG-NEXT: unreachable
+; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; X86_32_DBG-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; X86_32_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;
; X86_64_DBG-LABEL: @f.cfi(
@@ -135,9 +135,9 @@ define i1 @foo(ptr %p) {
;
; X86_64_DBG-LABEL: @.cfi.jumptable(
; X86_64_DBG-NEXT: entry:
-; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi)
-; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)
-; X86_64_DBG-NEXT: unreachable
+; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi), !dbg [[DBG6:![0-9]+]]
+; X86_64_DBG-NEXT: call void asm sideeffect "endbr64\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi), !dbg [[DBG6]]
+; X86_64_DBG-NEXT: unreachable, !dbg [[DBG6]]
;
;.
; X86_32: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
@@ -163,8 +163,22 @@ define i1 @foo(ptr %p) {
; X86_64: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
;.
; X86_32_DBG: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
-; X86_32_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_32_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_32_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_32_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_32_DBG: [[META5]] = !DISubroutineType(types: null)
+; X86_32_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; X86_32_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_32_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
; X86_64_DBG: [[META0:![0-9]+]] = !{i32 8, !"cf-protection-branch", i32 1}
-; X86_64_DBG: [[META1:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64_DBG: [[META1:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C, file: [[META2:![0-9]+]], producer: "llvm", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly)
+; X86_64_DBG: [[META2]] = !DIFile(filename: "{{.*}}ubsan_interface.h", directory: {{.*}})
+; X86_64_DBG: [[META3:![0-9]+]] = !{i32 0, !"typeid1"}
+; X86_64_DBG: [[META4:![0-9]+]] = distinct !DISubprogram(name: ".cfi.jumptable", scope: [[META2]], file: [[META2]], type: [[META5:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_64_DBG: [[META5]] = !DISubroutineType(types: null)
+; X86_64_DBG: [[DBG6]] = !DILocation(line: 0, scope: [[META7:![0-9]+]], inlinedAt: [[META8:![0-9]+]])
+; X86_64_DBG: [[META7]] = distinct !DISubprogram(name: "__ubsan_check_cfi_icall_jt", scope: [[META2]], file: [[META2]], type: [[META5]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META1]])
+; X86_64_DBG: [[META8]] = !DILocation(line: 0, scope: [[META4]])
;.
``````````
</details>
https://github.com/llvm/llvm-project/pull/192736
More information about the llvm-branch-commits
mailing list