1# REQUIRES: system-linux 2 3# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o 4# RUN: llvm-strip --strip-unneeded %t.o 5# RUN: %clang %cflags -no-pie -nostartfiles -nostdlib -lc %t.o -o %t.exe -Wl,-q 6 7# RUN: llvm-bolt %t.exe -o %t.exe.bolt --relocs=1 --lite=0 8 9# RUN: %t.exe.bolt 10 11## Check that BOLT's jump table detection diffrentiates between 12## __builtin_unreachable() targets and function pointers. 13 14## The test case was built from the following two source files and 15## modiffied for standalone build. main became _start, etc. 16## $ $(CC) a.c -O1 -S -o a.s 17## $ $(CC) b.c -O0 -S -o b.s 18 19## a.c: 20 21## typedef int (*fptr)(int); 22## void check_fptr(fptr, int); 23## 24## int foo(int a) { 25## check_fptr(foo, 0); 26## switch (a) { 27## default: 28## __builtin_unreachable(); 29## case 0: 30## return 3; 31## case 1: 32## return 5; 33## case 2: 34## return 7; 35## case 3: 36## return 11; 37## case 4: 38## return 13; 39## case 5: 40## return 17; 41## } 42## return 0; 43## } 44## 45## int main(int argc) { 46## check_fptr(main, 1); 47## return foo(argc); 48## } 49## 50## const fptr funcs[2] = {foo, main}; 51 52## b.c.: 53 54## typedef int (*fptr)(int); 55## extern const fptr funcs[2]; 56## 57## #define assert(C) { if (!(C)) (*(unsigned long long *)0) = 0; } 58## void check_fptr(fptr f, int i) { 59## assert(f == funcs[i]); 60## } 61 62 63 .text 64 .globl foo 65 .type foo, @function 66foo: 67.LFB0: 68 .cfi_startproc 69 pushq %rbx 70 .cfi_def_cfa_offset 16 71 .cfi_offset 3, -16 72 movl %edi, %ebx 73 movl $0, %esi 74 movl $foo, %edi 75 call check_fptr 76 movl %ebx, %ebx 77 jmp *.L4(,%rbx,8) 78.L8: 79 movl $5, %eax 80 jmp .L1 81.L7: 82 movl $7, %eax 83 jmp .L1 84.L6: 85 movl $11, %eax 86 jmp .L1 87.L5: 88 movl $13, %eax 89 jmp .L1 90.L3: 91 movl $17, %eax 92 jmp .L1 93.L10: 94 movl $3, %eax 95.L1: 96 popq %rbx 97 .cfi_def_cfa_offset 8 98 ret 99 .cfi_endproc 100.LFE0: 101 .size foo, .-foo 102 .globl _start 103 .type _start, @function 104_start: 105.LFB1: 106 .cfi_startproc 107 pushq %rbx 108 .cfi_def_cfa_offset 16 109 .cfi_offset 3, -16 110 movl %edi, %ebx 111 movl $1, %esi 112 movl $_start, %edi 113 call check_fptr 114 movl $1, %edi 115 call foo 116 popq %rbx 117 .cfi_def_cfa_offset 8 118 callq exit@PLT 119 .cfi_endproc 120.LFE1: 121 .size _start, .-_start 122 .globl check_fptr 123 .type check_fptr, @function 124check_fptr: 125.LFB2: 126 .cfi_startproc 127 pushq %rbp 128 .cfi_def_cfa_offset 16 129 .cfi_offset 6, -16 130 movq %rsp, %rbp 131 .cfi_def_cfa_register 6 132 movq %rdi, -8(%rbp) 133 movl %esi, -12(%rbp) 134 movl -12(%rbp), %eax 135 cltq 136 movq funcs(,%rax,8), %rax 137 cmpq %rax, -8(%rbp) 138 je .L33 139 movl $0, %eax 140 movq $0, (%rax) 141.L33: 142 nop 143 popq %rbp 144 .cfi_def_cfa 7, 8 145 ret 146 .cfi_endproc 147 148 .section .rodata 149 .align 8 150 .align 4 151.L4: 152 .quad .L10 153 .quad .L8 154 .quad .L7 155 .quad .L6 156 .quad .L5 157 .quad .L3 158 159 .globl funcs 160 .type funcs, @object 161 .size funcs, 16 162funcs: 163 .quad foo 164 .quad _start 165