1## Check that BOLT handles correctly folding functions with --icf=safe that can be referenced by non-control flow instructions. 2## It invokes BOLT twice first testing CFG path, and second when functions have to be disassembled. 3 4# REQUIRES: system-linux, asserts 5# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o 6# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q 7# RUN: llvm-bolt --no-threads %t.exe --icf -debug-only=bolt-icf \ 8# RUN: -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s 9# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug-only=bolt-icf \ 10# RUN: -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s 11# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug-only=bolt-icf \ 12# RUN: --skip-funcs=helper1Func,main -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECKNOCFG %s 13 14# ICFCHECK: ICF iteration 1 15# ICFCHECK-NEXT: folding barAddFunc into fooAddFunc 16# ICFCHECK-NEXT: folding barSubFunc into fooSubFunc 17 18# SAFEICFCHECK: skipping function with reference taken barAddFunc 19# SAFEICFCHECK-NEXT: ICF iteration 1 20# SAFEICFCHECK-NEXT: folding barSubFunc into fooSubFunc 21# SAFEICFCHECK-NEXT: ===--------- 22 23# SAFEICFCHECKNOCFG: skipping function with reference taken barAddFunc 24# SAFEICFCHECKNOCFG-NEXT: ICF iteration 1 25# SAFEICFCHECKNOCFG-NEXT: folding barSubFunc into fooSubFunc 26# SAFEICFCHECKNOCFG-NEXT: ===--------- 27 28## clang++ -c main.cpp -o main.o 29## extern int FooVar; 30## extern int BarVar; 31## [[clang::noinline]] 32## int fooSub(int a, int b) { 33## return a - b; 34## } 35## [[clang::noinline]] 36## int barSub(int a, int b) { 37## return a - b; 38## } 39## [[clang::noinline]] 40## int fooAdd(int a, int b) { 41## return a + b; 42## } 43## [[clang::noinline]] 44## int barAdd(int a, int b) { 45## return a + b; 46## } 47## int main(int argc, char **argv) { 48## int temp = helper1(barAdd, FooVar, BarVar) + 49## fooSub(FooVar, BarVar) + 50## barSub(FooVar, BarVar) + fooAdd(FooVar, BarVar); 51## return temp; 52## } 53 .globl fooSubFunc 54 .type fooSubFunc,@function 55fooSubFunc: 56 subl -8(%rbp), %eax 57 retq 58 .size fooSubFunc, .-fooSubFunc 59 60 .globl barSubFunc 61 .type barSubFunc,@function 62barSubFunc: 63 subl -8(%rbp), %eax 64 retq 65 .size barSubFunc, .-barSubFunc 66 67 .globl fooAddFunc 68 .type fooAddFunc,@function 69fooAddFunc: 70 addl -8(%rbp), %eax 71 retq 72 .size fooAddFunc, .-fooAddFunc 73 74 .globl barAddFunc 75 .type barAddFunc,@function 76barAddFunc: 77 addl -8(%rbp), %eax 78 retq 79 .size barAddFunc, .-barAddFunc 80 81 .globl helper1Func 82 .type helper1Func,@function 83helper1Func: 84 leaq barAddFunc(%rip), %rax 85 cmpq %rax, -16(%rbp) 86 retq 87 .size helper1Func, .-helper1Func 88 89 .globl main 90 .type main,@function 91main: 92 leaq barAddFunc(%rip), %rdi 93 callq helper1Func 94 callq fooSubFunc 95 callq barSubFunc 96 callq fooAddFunc 97 retq 98 .size main, .-main 99