[llvm] [BOLT] Add support for safe-icf (PR #116275)

Amir Ayupov via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 13 12:40:51 PST 2024


================
@@ -0,0 +1,155 @@
+## Check that BOLT handles correctly folding functions with --icf=safe
+## that can be referenced through a non control flow instruction when ICP optimization is enabled.
+## This tests also checks that destructors are not folded.
+
+# REQUIRES: system-linux
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t1.o
+# RUN: %clang %cflags %t1.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --no-threads %t.exe --icf      -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=ICFCHECK %s
+# RUN: llvm-bolt --no-threads %t.exe --icf=safe -debug -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck --check-prefix=SAFEICFCHECK %s
+
+# ICFCHECK:      ICF iteration 1
+# ICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
+# ICFCHECK-NEXT: folding _ZNK8Derived34funcEii into _ZNK8Derived24funcEii
+
+# SAFEICFCHECK: skipping function _ZNK8Derived34funcEii
+# SAFEICFCHECK-NEXT: ICF iteration 1
+# SAFEICFCHECK-NEXT: folding _ZN8Derived3D0Ev into _ZN8Derived2D0Ev
+# SAFEICFCHECK-NEXT: ===---------
+
+
+## generate profile
+## clang++ -O2 -fprofile-generate=. main.cpp   -c -o mainProf.o
+## PROF=test.profdata
+## clang++ -m64  -fprofile-use=$PROF \
+##   -mllvm -disable-icp=true -mllvm -print-after-all \
+##   -g0 -flto=thin -fwhole-program-vtables -fno-split-lto-unit -O2 \
+##   -fdebug-types-section \
+##   main.cpp -c -o mainProfLTO.bc
+## PASS='pgo-icall-prom'
+## clang++ -m64  -fprofile-use=$PROF \
+##   -O3 -Rpass=$PASS \
+##   -mllvm -print-before=$PASS \
+##   -mllvm -print-after=$PASS \
+##   -mllvm -filter-print-funcs=main \
+##   -mllvm -debug-only=$PASS \
+##   -x ir \
+##   mainProfLTO.bc -c -o mainProfFinal.o
+
+## class Base {
+## public:
+##   virtual int func(int a, int b) const = 0;
+##
+##   virtual ~Base() {};
+## };
+##
+## //namespace {
+## class Derived2 : public Base {
+##   int c = 5;
+## public:
+##   __attribute__((noinline)) int func(int a, int b)const override { return a * (a - b) + this->c; }
+##
+##   ~Derived2() {}
+## };
+##
+## class Derived3 : public Base {
+##   int c = 500;
+## public:
+##   __attribute__((noinline)) int func(int a, int b) const override { return a * (a - b) + this->c; }
+##   ~Derived3() {}
+## };
+## //} // namespace//
+##
+## __attribute__((noinline)) Base *createType(int a) {
+##     Base *base = nullptr;
+##     if (a == 4)
+##       base = new Derived2();
+##     else
+##       base = new Derived3();
+##     return base;
+## }
+##
+## extern int returnFive();
+## extern int returnFourOrFive(int val);
+## int main(int argc, char **argv) {
+##   int sum = 0;
+##   int a = returnFourOrFive(argc);
+##   int b = returnFive();
+##   Base *ptr = createType(a);
+##   Base *ptr2 = createType(b);
+##   sum += ptr->func(b, a) + ptr2->func(b, a);
+##   return 0;
+## }
+## clang++ -c helper.cpp -o helper.o
+## int FooVar = 1;
+## int BarVar = 2;
+##
+## int fooGlobalFuncHelper(int a, int b) {
+##   return 5;
+## }
+## Manually modified to remove "extra" assembly.
+	.globl	main
+	.type	main, at function
+main:
+	leaq	_ZNK8Derived34funcEii(%rip), %rcx
+	callq	_ZNK8Derived34funcEii
+	.size	main, .-main
+
+	.section	.text.hot._ZNK8Derived24funcEii,"axG", at progbits,_ZNK8Derived24funcEii,comdat
----------------
aaupov wrote:

Is it essential for this test to have .text, .text.hot, .text.unlikely sections?

https://github.com/llvm/llvm-project/pull/116275


More information about the llvm-commits mailing list