1# Test BOLT does not crash by trying to change the direction of a JRCXZ 2 3# REQUIRES: system-linux 4 5# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ 6# RUN: %s -o %t.o 7# RUN: link_fdata %s %t.o %t.fdata 8# RUN: llvm-strip --strip-unneeded %t.o 9# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q 10# RUN: llvm-bolt %t.exe --relocs=1 --reorder-blocks=ext-tsp --print-finalized \ 11# RUN: -o %t.out --data %t.fdata | FileCheck %s 12# RUN: %t.out 1 2 3 13 14# CHECK: BOLT-INFO 15 16 .text 17 .section .text.startup,"ax",@progbits 18 .p2align 5,,31 19 .globl main 20 .type main, %function 21main: 22 jmp test_function 23 24.globl test_function 25.hidden test_function 26.type test_function,@function 27.align 32 28test_function: 29# FDATA: 0 main 0 1 test_function 0 0 510 30 xorq %rcx, %rcx 31 andq $3, %rdi 32 jmpq *jumptbl(,%rdi,8) 33 34# Here are the 4 possible targets of the indirect branch to simulate a simple 35# CFG. What is important here is that BB1, the first block, conditionally 36# transfers control to the exit block with JRCXZ (.J1). We create a mock profile 37# saying that this branch is taken more often than not, causing BOLT to try to 38# put the exit block after it, which would require us to change the direction 39# of JRCXZ. 40.BB1: 41 movl $0x0, %eax 42.J1: 43 jrcxz .BBend 44# FDATA: 1 test_function #.J1# 1 test_function #.BB2# 0 10 45# FDATA: 1 test_function #.J1# 1 test_function #.BBend# 0 500 46.BB2: 47 movl $0x2, %eax 48 jmp .BBend 49.Lbb3: 50 movl $0x3, %eax 51 jmp .BBend 52.Lbb4: 53 movl $0x4, %eax 54.BBend: 55 retq 56.Lend1: 57 58 .section .rodata 59 .globl jumptbl 60jumptbl: 61 .quad .BB1 62 .quad .BB2 63 .quad .Lbb3 64 .quad .Lbb4 65