Files
clang-p2996/llvm/test/CodeGen/X86/jump-table-size-section.ll
Nabeel Omer fb6c10da1f [MC] Emit a jump table size section (#101962)
This patch will make LLVM emit a new section .llvm_jump_table_sizes 
containing tuples of (jump table address, entry count) in object files.
This section is useful for tools that need to statically reconstruct the
control flow of executables.

At the moment this is only enabled by default for the PS5 target.
2024-09-06 13:41:36 +01:00

210 lines
5.4 KiB
LLVM

; RUN: llc %s -o - -mtriple x86_64-sie-ps5 -emit-jump-table-sizes-section -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=PS5-CHECK %s
; RUN: llc %s -o - -mtriple x86_64-sie-ps5 -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOFLAG %s
; RUN: llc %s -o - -mtriple x86_64-sie-ps5 -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOTABLE %s
; RUN: llc %s -o - -mtriple x86_64-unknown-linux-gnu -emit-jump-table-sizes-section -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=ELF-CHECK %s
; RUN: llc %s -o - -mtriple x86_64-unknown-linux-gnu -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOFLAG %s
; RUN: llc %s -o - -mtriple x86_64-unknown-linux-gnu -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOTABLE %s
; RUN: llc %s -o - -mtriple x86_64-pc-windows-msvc -emit-jump-table-sizes-section -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=COFF-CHECK %s
; RUN: llc %s -o - -mtriple x86_64-pc-windows-msvc -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOFLAG %s
; RUN: llc %s -o - -mtriple x86_64-pc-windows-msvc -verify-machineinstrs --relocation-model=pic | FileCheck --check-prefix=NOTABLE %s
; This test verifies the jump table size section. Currently only enabled by default on the PS5 target.
$foo1 = comdat any
; Ensure proper comdat handling.
define void @foo1(i32 %x, ptr %to) comdat {
; PS5-CHECK-LABEL: foo1
; PS5-CHECK: .section .llvm_jump_table_sizes,"G",@llvm_jt_sizes,foo1,comdat
; PS5-CHECK-NEXT: .quad .LJTI0_0
; PS5-CHECK-NEXT: .quad 6
; ELF-CHECK-LABEL: foo1
; ELF-CHECK: .section .llvm_jump_table_sizes,"G",@llvm_jt_sizes,foo1,comdat
; ELF-CHECK-NEXT: .quad .LJTI0_0
; ELF-CHECK-NEXT: .quad 6
; COFF-CHECK-LABEL: foo1
; COFF-CHECK: .section .llvm_jump_table_sizes,"drD",associative,foo1
; COFF-CHECK-NEXT: .quad .LJTI0_0
; COFF-CHECK-NEXT: .quad 6
; NOFLAG-LABEL: foo1
; NOFLAG-NOT: .section .llvm_jump_table_sizes
entry:
switch i32 %x, label %default [
i32 0, label %bb0
i32 1, label %bb1
i32 2, label %bb2
i32 3, label %bb3
i32 4, label %bb4
i32 5, label %bb4
]
bb0:
store i32 0, ptr %to
br label %exit
bb1:
store i32 1, ptr %to
br label %exit
bb2:
store i32 2, ptr %to
br label %exit
bb3:
store i32 3, ptr %to
br label %exit
bb4:
store i32 4, ptr %to
br label %exit
exit:
ret void
default:
unreachable
}
define void @foo2(i32 %x, ptr %to) {
; PS5-CHECK-LABEL: foo2
; PS5-CHECK: .section .llvm_jump_table_sizes,"",@llvm_jt_sizes
; PS5-CHECK-NEXT: .quad .LJTI1_0
; PS5-CHECK-NEXT: .quad 5
; ELF-CHECK-LABEL: foo2
; ELF-CHECK: .section .llvm_jump_table_sizes,"",@llvm_jt_sizes
; ELF-CHECK-NEXT: .quad .LJTI1_0
; ELF-CHECK-NEXT: .quad 5
; COFF-CHECK-LABEL: foo2
; COFF-CHECK: .section .llvm_jump_table_sizes,"drD"
; COFF-CHECK-NEXT: .quad .LJTI1_0
; COFF-CHECK-NEXT: .quad 5
; NOFLAG-LABEL: foo1
; NOFLAG-NOT: .section .llvm_jump_table_sizes
entry:
switch i32 %x, label %default [
i32 0, label %bb0
i32 1, label %bb1
i32 2, label %bb2
i32 3, label %bb3
i32 4, label %bb4
]
bb0:
store i32 0, ptr %to
br label %exit
bb1:
store i32 1, ptr %to
br label %exit
bb2:
store i32 2, ptr %to
br label %exit
bb3:
store i32 3, ptr %to
br label %exit
bb4:
store i32 4, ptr %to
br label %exit
exit:
ret void
default:
unreachable
}
; Ensure that the section isn't produced if there is no jump table.
define void @foo3(i32 %x, ptr %to) {
; NOTABLE-LABEL: foo3
; NOTABLE-NOT: .section .llvm_jump_table_sizes
exit:
ret void
}
; Ensure we can deal with nested jump tables.
define void @nested(i32 %x, i32 %y, ptr %to) {
; PS5-CHECK-LABEL: nested
; PS5-CHECK: .section .llvm_jump_table_sizes,"",@llvm_jt_sizes
; PS5-CHECK-NEXT: .quad .LJTI3_0
; PS5-CHECK-NEXT: .quad 5
; PS5-CHECK-NEXT: .quad .LJTI3_1
; PS5-CHECK-NEXT: .quad 6
; ELF-CHECK-LABEL: nested
; ELF-CHECK: .section .llvm_jump_table_sizes,"",@llvm_jt_sizes
; ELF-CHECK-NEXT: .quad .LJTI3_0
; ELF-CHECK-NEXT: .quad 5
; ELF-CHECK-NEXT: .quad .LJTI3_1
; ELF-CHECK-NEXT: .quad 6
; COFF-CHECK-LABEL: nested
; COFF-CHECK: .section .llvm_jump_table_sizes,"drD"
; COFF-CHECK-NEXT: .quad .LJTI3_0
; COFF-CHECK-NEXT: .quad 5
; COFF-CHECK-NEXT: .quad .LJTI3_1
; COFF-CHECK-NEXT: .quad 6
; NOFLAG-LABEL: nested
; NOFLAG-NOT: .section .llvm_jump_table_sizes
entry:
switch i32 %x, label %default [
i32 0, label %bb0
i32 1, label %bb1
i32 2, label %bb2
i32 3, label %bb3
i32 4, label %bb4
]
bb0:
store i32 0, ptr %to
br label %exit
bb1:
store i32 1, ptr %to
br label %exit
bb2:
store i32 2, ptr %to
br label %exit
bb3:
store i32 3, ptr %to
br label %exit
bb4:
switch i32 %y, label %default [
i32 1, label %bb5
i32 2, label %bb6
i32 3, label %bb7
i32 4, label %bb8
i32 5, label %bb9
i32 6, label %bb10
]
br label %exit2
bb5:
store i32 4, ptr %to
br label %exit
bb6:
store i32 4, ptr %to
br label %exit
bb7:
store i32 4, ptr %to
br label %exit
bb8:
store i32 4, ptr %to
br label %exit
bb9:
store i32 4, ptr %to
br label %exit
bb10:
store i32 4, ptr %to
br label %exit
exit:
ret void
exit2:
ret void
default:
unreachable
}