67 lines · plain
1## This checks that shrink wrapping uses the red zone defined in the X86 ABI by2## placing restores that access elements already deallocated by the stack.3 4# REQUIRES: system-linux5 6# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \7# RUN: %s -o %t.o8# RUN: link_fdata %s %t.o %t.fdata9# RUN: llvm-strip --strip-unneeded %t.o10# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib11# RUN: llvm-bolt -relocs %t.exe -o %t.out -data %t.fdata \12# RUN: -frame-opt=all -simplify-conditional-tail-calls=false \13# RUN: -experimental-shrink-wrapping \14# RUN: -eliminate-unreachable=false | FileCheck %s15# RUN: llvm-objdump -d %t.out --print-imm-hex | \16# RUN: FileCheck --check-prefix CHECK-OBJDUMP %s17 18 19## Here we create a CFG where the restore position matches the previous (deleted)20## restore position. Shrink wrapping then will put a stack access to an element21## that was deallocated at the previously deleted POP, which falls in the red22## zone and should be safe for X86 Linux ABI.23 .globl _start24 .type _start, %function25_start:26 .cfi_startproc27# FDATA: 0 [unknown] 0 1 _start 0 0 128 push %rbp29 mov %rsp, %rbp30 push %rbx31 push %r1432 subq $0x20, %rsp33b: je hot_path34# FDATA: 1 _start #b# 1 _start #hot_path# 0 135cold_path:36 mov %r14, %rdi37 mov %rbx, %rdi38 movq rel(%rip), %rdi # Add this to create a relocation and run bolt w/ relocs39 leaq -0x20(%rbp), %r1440 movq -0x20(%rbp), %rdi41 leaq -0x10(%rbp), %rsp42 pop %r1443 pop %rbx44 pop %rbp45 ret46hot_path:47 addq $0x20, %rsp48 pop %r1449 pop %rbx50 pop %rbp51 ret52 .cfi_endproc53end:54 .size _start, .-_start55 56 .data57rel: .quad end58 59# CHECK: BOLT-INFO: Shrink wrapping moved 2 spills inserting load/stores and 0 spills inserting push/pops60 61# CHECK-OBJDUMP: <_start>:62# CHECK-OBJDUMP: leaq (%rbp), %rsp63# CHECK-OBJDUMP-NEXT: popq %rbp64# CHECK-OBJDUMP-NEXT: movq -0x10(%rsp), %rbx65# CHECK-OBJDUMP-NEXT: movq -0x18(%rsp), %r1466# CHECK-OBJDUMP-NEXT: retq67