|
| 1 | +## This reproduces an issue where the function is split into three fragments |
| 2 | +## and all fragments access the same jump table. |
| 3 | + |
| 4 | +# REQUIRES: system-linux |
| 5 | + |
| 6 | +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o |
| 7 | +# RUN: llvm-strip --strip-unneeded %t.o |
| 8 | +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q |
| 9 | +# RUN: llvm-bolt %t.exe -o %t.out -v=1 -print-only=main.warm -print-cfg 2>&1 | FileCheck %s |
| 10 | + |
| 11 | +# CHECK-DAG: BOLT-INFO: marking main.warm as a fragment of main |
| 12 | +# CHECK-DAG: BOLT-INFO: marking main.cold as a fragment of main |
| 13 | +# CHECK-DAG: BOLT-INFO: processing main.warm as a sibling of non-ignored function |
| 14 | +# CHECK-DAG: BOLT-INFO: processing main.cold as a sibling of non-ignored function |
| 15 | +# CHECK-DAG: BOLT-WARNING: Ignoring main.cold |
| 16 | +# CHECK-DAG: BOLT-WARNING: Ignoring main.warm |
| 17 | +# CHECK-DAG: BOLT-WARNING: Ignoring main |
| 18 | +# CHECK: BOLT-WARNING: skipped 3 functions due to cold fragments |
| 19 | + |
| 20 | +# CHECK: PIC Jump table JUMP_TABLE for function main, main.warm, main.cold |
| 21 | +# CHECK-NEXT: 0x0000 : __ENTRY_main@0x[[#]] |
| 22 | +# CHECK-NEXT: 0x0004 : __ENTRY_main@0x[[#]] |
| 23 | +# CHECK-NEXT: 0x0008 : __ENTRY_main.cold@0x[[#]] |
| 24 | +# CHECK-NEXT: 0x000c : __ENTRY_main@0x[[#]] |
| 25 | + .globl main |
| 26 | + .type main, %function |
| 27 | + .p2align 2 |
| 28 | +main: |
| 29 | +LBB0: |
| 30 | + andl $0xf, %ecx |
| 31 | + cmpb $0x4, %cl |
| 32 | + ## exit through ret |
| 33 | + ja LBB3 |
| 34 | + |
| 35 | +## jump table dispatch, jumping to label indexed by val in %ecx |
| 36 | +LBB1: |
| 37 | + leaq JUMP_TABLE(%rip), %r8 |
| 38 | + movzbl %cl, %ecx |
| 39 | + movslq (%r8,%rcx,4), %rax |
| 40 | + addq %rax, %r8 |
| 41 | + jmpq *%r8 |
| 42 | + |
| 43 | +LBB2: |
| 44 | + xorq %rax, %rax |
| 45 | +LBB3: |
| 46 | + addq $0x8, %rsp |
| 47 | + ret |
| 48 | +.size main, .-main |
| 49 | + |
| 50 | + .globl main.warm |
| 51 | + .type main.warm, %function |
| 52 | + .p2align 2 |
| 53 | +main.warm: |
| 54 | +LBB20: |
| 55 | + andl $0xb, %ebx |
| 56 | + cmpb $0x1, %cl |
| 57 | + # exit through ret |
| 58 | + ja LBB23 |
| 59 | + |
| 60 | +## jump table dispatch, jumping to label indexed by val in %ecx |
| 61 | +LBB21: |
| 62 | + leaq JUMP_TABLE(%rip), %r8 |
| 63 | + movzbl %cl, %ecx |
| 64 | + movslq (%r8,%rcx,4), %rax |
| 65 | + addq %rax, %r8 |
| 66 | + jmpq *%r8 |
| 67 | + |
| 68 | +LBB22: |
| 69 | + xorq %rax, %rax |
| 70 | +LBB23: |
| 71 | + addq $0x8, %rsp |
| 72 | + ret |
| 73 | +.size main.warm, .-main.warm |
| 74 | + |
| 75 | +## cold fragment is only reachable through jump table |
| 76 | + .globl main.cold |
| 77 | + .type main.cold, %function |
| 78 | +main.cold: |
| 79 | + leaq JUMP_TABLE(%rip), %r8 |
| 80 | + movzbl %cl, %ecx |
| 81 | + movslq (%r8,%rcx,4), %rax |
| 82 | + addq %rax, %r8 |
| 83 | + jmpq *%r8 |
| 84 | +LBB4: |
| 85 | + callq abort |
| 86 | +.size main.cold, .-main.cold |
| 87 | + |
| 88 | + .rodata |
| 89 | +## jmp table, entries must be R_X86_64_PC32 relocs |
| 90 | + .globl JUMP_TABLE |
| 91 | +JUMP_TABLE: |
| 92 | + .long LBB2-JUMP_TABLE |
| 93 | + .long LBB3-JUMP_TABLE |
| 94 | + .long LBB4-JUMP_TABLE |
| 95 | + .long LBB3-JUMP_TABLE |
0 commit comments