| # Test BOLT does not crash by trying to change the direction of a JRCXZ |
| |
| # REQUIRES: system-linux |
| |
| # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ |
| # RUN: %s -o %t.o |
| # RUN: link_fdata %s %t.o %t.fdata |
| # RUN: llvm-strip --strip-unneeded %t.o |
| # RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q |
| # RUN: llvm-bolt %t.exe --relocs=1 --reorder-blocks=ext-tsp --print-finalized \ |
| # RUN: -o %t.out --data %t.fdata | FileCheck %s |
| # RUN: %t.out 1 2 3 |
| |
| # CHECK: BOLT-INFO |
| |
| .text |
| .section .text.startup,"ax",@progbits |
| .p2align 5,,31 |
| .globl main |
| .type main, %function |
| main: |
| jmp test_function |
| |
| .globl test_function |
| .hidden test_function |
| .type test_function,@function |
| .align 32 |
| test_function: |
| # FDATA: 0 main 0 1 test_function 0 0 510 |
| xorq %rcx, %rcx |
| andq $3, %rdi |
| jmpq *jumptbl(,%rdi,8) |
| |
| # Here are the 4 possible targets of the indirect branch to simulate a simple |
| # CFG. What is important here is that BB1, the first block, conditionally |
| # transfers control to the exit block with JRCXZ (.J1). We create a mock profile |
| # saying that this branch is taken more often than not, causing BOLT to try to |
| # put the exit block after it, which would require us to change the direction |
| # of JRCXZ. |
| .BB1: |
| movl $0x0, %eax |
| .J1: |
| jrcxz .BBend |
| # FDATA: 1 test_function #.J1# 1 test_function #.BB2# 0 10 |
| # FDATA: 1 test_function #.J1# 1 test_function #.BBend# 0 500 |
| .BB2: |
| movl $0x2, %eax |
| jmp .BBend |
| .Lbb3: |
| movl $0x3, %eax |
| jmp .BBend |
| .Lbb4: |
| movl $0x4, %eax |
| .BBend: |
| retq |
| .Lend1: |
| |
| .section .rodata |
| .globl jumptbl |
| jumptbl: |
| .quad .BB1 |
| .quad .BB2 |
| .quad .Lbb3 |
| .quad .Lbb4 |