xref: /llvm-project/bolt/test/X86/icf-safe-test1.test (revision 3c357a49d61e4c81a1ac016502ee504521bc8dda)
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