aboutsummaryrefslogtreecommitdiff
path: root/test/profile
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:27 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:27 +0000
commit316d58822dada9440bd06ecfc758dcc2364d617c (patch)
treefe72ec2e6ce9a360dda74d9d57f7acdb0e3c39d6 /test/profile
parent0230fcf22fe7d19f03d981c9c2c59a3db0b72ea5 (diff)
downloadsrc-316d58822dada9440bd06ecfc758dcc2364d617c.tar.gz
src-316d58822dada9440bd06ecfc758dcc2364d617c.zip
Notes
Diffstat (limited to 'test/profile')
-rw-r--r--test/profile/CMakeLists.txt8
-rw-r--r--test/profile/Inputs/comdat_rename.h13
-rw-r--r--test/profile/Inputs/comdat_rename_1.cc33
-rw-r--r--test/profile/Inputs/comdat_rename_2.cc18
-rw-r--r--test/profile/Inputs/extern_template.h10
-rw-r--r--test/profile/Inputs/instrprof-comdat.h16
-rw-r--r--test/profile/Inputs/instrprof-dynamic-a.cpp10
-rw-r--r--test/profile/Linux/comdat_rename.test6
-rw-r--r--test/profile/Linux/coverage_ctors.cpp8
-rw-r--r--test/profile/Linux/coverage_dtor.cpp4
-rw-r--r--test/profile/Linux/coverage_test.cpp26
-rw-r--r--test/profile/Linux/extern_template.test4
-rw-r--r--test/profile/Linux/instrprof-comdat.test2
-rw-r--r--test/profile/Linux/instrprof-cs.c35
-rw-r--r--test/profile/Linux/lit.local.cfg1
-rw-r--r--test/profile/gcc-flag-compatibility.test8
-rw-r--r--test/profile/instrprof-basic.c43
-rw-r--r--test/profile/instrprof-darwin-dead-strip.c60
-rw-r--r--test/profile/instrprof-dump.c62
-rw-r--r--test/profile/instrprof-icall-promo.test14
-rw-r--r--test/profile/instrprof-override-filename-then-reset-default.c6
-rw-r--r--test/profile/instrprof-override-filename-with-env.c6
-rw-r--r--test/profile/instrprof-override-filename.c6
-rw-r--r--test/profile/instrprof-path.c39
-rw-r--r--test/profile/instrprof-set-filename-shared.test (renamed from test/profile/Linux/instrprof-set-filename-shared.test)4
-rw-r--r--test/profile/instrprof-value-prof-evict.test4
-rw-r--r--test/profile/instrprof-value-prof-reset.c47
-rw-r--r--test/profile/instrprof-value-prof-shared.test27
-rw-r--r--test/profile/instrprof-value-prof.test4
-rw-r--r--test/profile/instrprof-visibility.cpp52
-rw-r--r--test/profile/lit.cfg23
31 files changed, 482 insertions, 117 deletions
diff --git a/test/profile/CMakeLists.txt b/test/profile/CMakeLists.txt
index 0eb2b894748c..5a4cfa1012b0 100644
--- a/test/profile/CMakeLists.txt
+++ b/test/profile/CMakeLists.txt
@@ -14,13 +14,7 @@ endif()
foreach(arch ${PROFILE_TEST_ARCH})
set(PROFILE_TEST_TARGET_ARCH ${arch})
- if(${arch} MATCHES "arm|aarch64")
- # This is only true if we're cross-compiling.
- set(PROFILE_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS})
- else()
- get_target_flags_for_arch(${arch} PROFILE_TEST_TARGET_CFLAGS)
- string(REPLACE ";" " " PROFILE_TEST_TARGET_CFLAGS "${PROFILE_TEST_TARGET_CFLAGS}")
- endif()
+ get_test_cc_for_arch(${arch} PROFILE_TEST_TARGET_CC PROFILE_TEST_TARGET_CFLAGS)
set(CONFIG_NAME Profile-${arch})
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
diff --git a/test/profile/Inputs/comdat_rename.h b/test/profile/Inputs/comdat_rename.h
new file mode 100644
index 000000000000..d30628f13b63
--- /dev/null
+++ b/test/profile/Inputs/comdat_rename.h
@@ -0,0 +1,13 @@
+struct FOO {
+ FOO() : a(0), b(0) {}
+ int callee();
+ __attribute__((noinline)) void caller(int n) {
+ int r = callee();
+ if (r == 0) {
+ a += n;
+ b += 1;
+ }
+ }
+ int a;
+ int volatile b;
+};
diff --git a/test/profile/Inputs/comdat_rename_1.cc b/test/profile/Inputs/comdat_rename_1.cc
new file mode 100644
index 000000000000..688e305310c5
--- /dev/null
+++ b/test/profile/Inputs/comdat_rename_1.cc
@@ -0,0 +1,33 @@
+#include "comdat_rename.h"
+// callee's out-of-line instance profile data -- it comes
+// from external calls to it from comdat_rename_2.cc.
+// Its inline instance copy's profile data is different and
+// is collected in 'caller''s context.
+int FOO::callee() {
+ // CHECK-LABEL: define {{.*}}callee{{.*}}
+ // CHECK-NOT: br i1 {{.*}}
+ // CHECK: br {{.*}}label{{.*}}, label %[[BB1:.*]], !prof ![[PD1:[0-9]+]]
+ // CHECK: {{.*}}[[BB1]]:
+ if (b != 0)
+ return a / b;
+ if (a != 0)
+ return 10 / a;
+ return 0;
+}
+
+// This is the 'caller''s comdat copy (after renaming) in this module.
+// The profile counters include a copy of counters from 'callee':
+//
+// CHECK-LABEL: define {{.*}}caller{{.*}}
+// CHECK-NOT: br i1 {{.*}}
+// CHECK: br {{.*}}label{{.*}}, label %[[BB2:.*]], !prof ![[PD2:[0-9]+]]
+// CHECK: {{.*}}[[BB2]]:
+// CHECK: br {{.*}}label{{.*}}, label %{{.*}}, !prof !{{.*}}
+// CHECK: br {{.*}}label %[[BB3:.*]], label %{{.*}} !prof ![[PD3:[0-9]+]]
+// CHECK: {{.*}}[[BB3]]:
+//
+// CHECK:![[PD1]] = !{!"branch_weights", i32 0, i32 1}
+// CHECK:![[PD2]] = !{!"branch_weights", i32 1, i32 0}
+// CHECK:![[PD3]] = !{!"branch_weights", i32 {{.*}}, i32 0}
+
+void test(FOO *foo) { foo->caller(10); }
diff --git a/test/profile/Inputs/comdat_rename_2.cc b/test/profile/Inputs/comdat_rename_2.cc
new file mode 100644
index 000000000000..5cad79c9f9d8
--- /dev/null
+++ b/test/profile/Inputs/comdat_rename_2.cc
@@ -0,0 +1,18 @@
+#include "comdat_rename.h"
+extern void test(FOO *);
+FOO foo;
+int main() {
+ test(&foo);
+ foo.caller(20);
+ return 0;
+}
+
+// The copy of 'caller' defined in this module -- it has
+// 'callee' call remaining.
+//
+// CHECK-LABEL: define {{.*}}caller{{.*}}
+// CHECK: {{.*}} call {{.*}}
+// CHECK-NOT: br i1 {{.*}}
+// CHECK: br {{.*}}label %[[BB1:.*]], label{{.*}}!prof ![[PD1:[0-9]+]]
+// CHECK: {{.*}}[[BB1]]:
+// CHECK:![[PD1]] = !{!"branch_weights", i32 0, i32 1}
diff --git a/test/profile/Inputs/extern_template.h b/test/profile/Inputs/extern_template.h
index 01c1d1abfff5..aa59f6c1e600 100644
--- a/test/profile/Inputs/extern_template.h
+++ b/test/profile/Inputs/extern_template.h
@@ -1,10 +1,10 @@
template <typename T> struct Test {
Test() : M(10) {}
- void doIt(int N) { // CHECK: 2| [[@LINE]]| void doIt
- if (N > 10) { // CHECK: 2| [[@LINE]]| if (N > 10) {
- M += 2; // CHECK: 1| [[@LINE]]| M += 2;
- } else // CHECK: 1| [[@LINE]]| } else
- M -= 2; // CHECK: 1| [[@LINE]]| M -= 2;
+ void doIt(int N) { // CHECK: [[@LINE]]| 2| void doIt
+ if (N > 10) { // CHECK: [[@LINE]]| 2| if (N > 10) {
+ M += 2; // CHECK: [[@LINE]]| 1| M += 2;
+ } else // CHECK: [[@LINE]]| 1| } else
+ M -= 2; // CHECK: [[@LINE]]| 1| M -= 2;
}
T M;
};
diff --git a/test/profile/Inputs/instrprof-comdat.h b/test/profile/Inputs/instrprof-comdat.h
index db1a5ba63e58..61e283cc878e 100644
--- a/test/profile/Inputs/instrprof-comdat.h
+++ b/test/profile/Inputs/instrprof-comdat.h
@@ -12,12 +12,12 @@ private:
T t;
};
-template <class T> T FOO<T>::DoIt(T ti) { // HEADER: 2| [[@LINE]]|template
- for (T I = 0; I < ti; I++) { // HEADER: 22| [[@LINE]]| for (T
- t += I; // HEADER: 20| [[@LINE]]| t += I;
- if (I > ti / 2) // HEADER: 20| [[@LINE]]| if (I > ti
- t -= 1; // HEADER: 8| [[@LINE]]| t -= 1;
- } // HEADER: 10| [[@LINE]]| }
- // HEADER: 1| [[@LINE]]|
- return t; // HEADER: 1| [[@LINE]]| return t;
+template <class T> T FOO<T>::DoIt(T ti) { // HEADER: [[@LINE]]| 2|template
+ for (T I = 0; I < ti; I++) { // HEADER: [[@LINE]]| 22| for (T
+ t += I; // HEADER: [[@LINE]]| 20| t += I;
+ if (I > ti / 2) // HEADER: [[@LINE]]| 20| if (I > ti
+ t -= 1; // HEADER: [[@LINE]]| 8| t -= 1;
+ } // HEADER: [[@LINE]]| 10| }
+ // HEADER: [[@LINE]]| 1|
+ return t; // HEADER: [[@LINE]]| 1| return t;
}
diff --git a/test/profile/Inputs/instrprof-dynamic-a.cpp b/test/profile/Inputs/instrprof-dynamic-a.cpp
index 5faa9c2b2a80..7468cd4eb04e 100644
--- a/test/profile/Inputs/instrprof-dynamic-a.cpp
+++ b/test/profile/Inputs/instrprof-dynamic-a.cpp
@@ -1,7 +1,7 @@
#include "instrprof-dynamic-header.h"
-void a() { // COV: 1| [[@LINE]]|void a
- if (true) { // COV: 1| [[@LINE]]| if
- bar<void>(1); // COV: 1| [[@LINE]]| bar
- bar<char>(1); // COV: 1| [[@LINE]]| bar
- } // COV: 1| [[@LINE]]| }
+void a() { // COV: [[@LINE]]| 1|void a
+ if (true) { // COV: [[@LINE]]| 1| if
+ bar<void>(1); // COV: [[@LINE]]| 1| bar
+ bar<char>(1); // COV: [[@LINE]]| 1| bar
+ } // COV: [[@LINE]]| 1| }
}
diff --git a/test/profile/Linux/comdat_rename.test b/test/profile/Linux/comdat_rename.test
new file mode 100644
index 000000000000..cd5c672de4f2
--- /dev/null
+++ b/test/profile/Linux/comdat_rename.test
@@ -0,0 +1,6 @@
+// RUN: rm -fr %t.prof
+// RUN: %clangxx_pgogen=%t.prof/ -o %t.gen -O2 %S/../Inputs/comdat_rename_1.cc %S/../Inputs/comdat_rename_2.cc
+// RUN: %run %t.gen
+// RUN: llvm-profdata merge -o %t.profdata %t.prof/
+// RUN: %clangxx_profuse=%t.profdata -O2 -emit-llvm -S %S/../Inputs/comdat_rename_1.cc -o - | FileCheck %S/../Inputs/comdat_rename_1.cc
+// RUN: %clangxx_profuse=%t.profdata -O2 -emit-llvm -S %S/../Inputs/comdat_rename_2.cc -o - | FileCheck %S/../Inputs/comdat_rename_2.cc
diff --git a/test/profile/Linux/coverage_ctors.cpp b/test/profile/Linux/coverage_ctors.cpp
index 317dcfe18b50..021d9df5e734 100644
--- a/test/profile/Linux/coverage_ctors.cpp
+++ b/test/profile/Linux/coverage_ctors.cpp
@@ -15,9 +15,9 @@ struct Base {
};
struct Derived : public Base {
- Derived(const Derived &) = default; // CHECK: 2| [[@LINE]]| Derived(const Derived &) = default;
- Derived(Derived &&) = default; // CHECK: 1| [[@LINE]]| Derived(Derived &&) = default;
- Derived() = default; // CHECK: 1| [[@LINE]]| Derived() = default
+ Derived(const Derived &) = default; // CHECK: [[@LINE]]| 2| Derived(const Derived &) = default;
+ Derived(Derived &&) = default; // CHECK: [[@LINE]]| 1| Derived(Derived &&) = default;
+ Derived() = default; // CHECK: [[@LINE]]| 1| Derived() = default
};
Derived dd;
@@ -27,6 +27,6 @@ int main() {
Derived dd4(static_cast<Derived &&>(dd3));
if (dd.B != 0 || dd2.B != 5 || dd3.B != 10 || dd4.B != 20)
- return 1; // CHECK: 0| [[@LINE]]| return 1;
+ return 1; // CHECK: [[@LINE]]| 0| return 1;
return 0;
}
diff --git a/test/profile/Linux/coverage_dtor.cpp b/test/profile/Linux/coverage_dtor.cpp
index f35eb100fa12..16415122040c 100644
--- a/test/profile/Linux/coverage_dtor.cpp
+++ b/test/profile/Linux/coverage_dtor.cpp
@@ -12,7 +12,7 @@ struct Base {
struct Derived : public Base {
Derived(int K) : Base(K) {}
- ~Derived() = default; // CHECK: 2| [[@LINE]]| ~Derived() = default;
+ ~Derived() = default; // CHECK: [[@LINE]]| 2| ~Derived() = default;
};
int main() {
@@ -21,6 +21,6 @@ int main() {
Derived dd2(90);
}
if (g != 0)
- return 1; // CHECK: 0| [[@LINE]]| return 1;
+ return 1; // CHECK: [[@LINE]]| 0| return 1;
return 0;
}
diff --git a/test/profile/Linux/coverage_test.cpp b/test/profile/Linux/coverage_test.cpp
index 9b4ba073cf0a..db9a14e26e3c 100644
--- a/test/profile/Linux/coverage_test.cpp
+++ b/test/profile/Linux/coverage_test.cpp
@@ -17,19 +17,19 @@
// RUN: llvm-profdata merge -o %t.pie.profdata %t.pie.profraw
// RUN: llvm-cov show %t.pie -instr-profile %t.pie.profdata -filename-equivalence 2>&1 | FileCheck %s
-void foo(bool cond) { // CHECK: 1| [[@LINE]]|void foo(
- if (cond) { // CHECK: 1| [[@LINE]]| if (cond) {
- } // CHECK: 0| [[@LINE]]| }
-} // CHECK: 1| [[@LINE]]|}
-void bar() { // CHECK: 1| [[@LINE]]|void bar() {
-} // CHECK: 1| [[@LINE]]|}
-void func() { // CHECK: 0| [[@LINE]]|void func(
-} // CHECK: 0| [[@LINE]]|}
-int main() { // CHECK: 1| [[@LINE]]|int main(
- foo(false); // CHECK: 1| [[@LINE]]| foo(
- bar(); // CHECK: 1| [[@LINE]]| bar(
- return 0; // CHECK: 1| [[@LINE]]| return
-} // CHECK: 1| [[@LINE]]|}
+void foo(bool cond) { // CHECK: [[@LINE]]| 1|void foo(
+ if (cond) { // CHECK: [[@LINE]]| 1| if (cond) {
+ } // CHECK: [[@LINE]]| 0| }
+} // CHECK: [[@LINE]]| 1|}
+void bar() { // CHECK: [[@LINE]]| 1|void bar() {
+} // CHECK: [[@LINE]]| 1|}
+void func() { // CHECK: [[@LINE]]| 0|void func(
+} // CHECK: [[@LINE]]| 0|}
+int main() { // CHECK: [[@LINE]]| 1|int main(
+ foo(false); // CHECK: [[@LINE]]| 1| foo(
+ bar(); // CHECK: [[@LINE]]| 1| bar(
+ return 0; // CHECK: [[@LINE]]| 1| return
+} // CHECK: [[@LINE]]| 1|}
// COVMAP: __llvm_covmap {{.*}}
diff --git a/test/profile/Linux/extern_template.test b/test/profile/Linux/extern_template.test
index ada4d230e9bc..3ce362783199 100644
--- a/test/profile/Linux/extern_template.test
+++ b/test/profile/Linux/extern_template.test
@@ -1,12 +1,12 @@
// RUN: %clang -O2 -c -o %t.0.o %S/../Inputs/extern_template.cpp
// RUN: %clang_profgen -O2 -c -o %t.o %S/../Inputs/extern_template.cpp
// RUN: %clang_profgen -O2 -fcoverage-mapping %S/../Inputs/extern_template1.cpp %S/../Inputs/extern_template2.cpp %t.o -o %t
-// RUN: env LLVM_PROFILE_FILE=%t.profraw %t
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
// RUN: llvm-profdata show --all-functions %t.profraw | FileCheck %s
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
// RUN: llvm-cov show -instr-profile=%t.profdata %t | FileCheck %S/../Inputs/extern_template.h
// RUN: %clang_profgen -O2 -fcoverage-mapping %S/../Inputs/extern_template1.cpp %S/../Inputs/extern_template2.cpp %t.0.o -o %t.0
-// RUN: env LLVM_PROFILE_FILE=%t.0.profraw %t.0
+// RUN: env LLVM_PROFILE_FILE=%t.0.profraw %run %t.0
// RUN: llvm-profdata show --all-functions %t.0.profraw | FileCheck %s
// RUN: llvm-profdata merge -o %t.0.profdata %t.0.profraw
// RUN: llvm-cov show -instr-profile=%t.0.profdata %t.0 | FileCheck %S/../Inputs/extern_template.h
diff --git a/test/profile/Linux/instrprof-comdat.test b/test/profile/Linux/instrprof-comdat.test
index b933e96b4504..5a11a241ae6f 100644
--- a/test/profile/Linux/instrprof-comdat.test
+++ b/test/profile/Linux/instrprof-comdat.test
@@ -1,6 +1,6 @@
RUN: mkdir -p %t.d
RUN: %clangxx_profgen -o %t.d/comdat -fcoverage-mapping -fuse-ld=gold %S/../Inputs/instrprof-comdat-1.cpp %S/../Inputs/instrprof-comdat-2.cpp
-RUN: LLVM_PROFILE_FILE=%t-comdat.profraw %t.d/comdat
+RUN: LLVM_PROFILE_FILE=%t-comdat.profraw %run %t.d/comdat
RUN: llvm-profdata merge -o %t.d/comdat.prof %t-comdat.profraw
RUN: llvm-cov show --filename-equivalence --instr-profile=%t.d/comdat.prof %t.d/comdat | FileCheck --check-prefix=HEADER %S/../Inputs/instrprof-comdat.h
diff --git a/test/profile/Linux/instrprof-cs.c b/test/profile/Linux/instrprof-cs.c
new file mode 100644
index 000000000000..d825525a532d
--- /dev/null
+++ b/test/profile/Linux/instrprof-cs.c
@@ -0,0 +1,35 @@
+// RUN: rm -fr %t.prof
+// RUN: %clang_pgogen=%t.prof/ -o %t.gen.cs -O2 %s
+// RUN: %run %t.gen.cs
+// RUN: llvm-profdata merge -o %t.cs.profdata %t.prof/
+// Check context sensitive profile
+// RUN: %clang_profuse=%t.cs.profdata -O2 -emit-llvm -S %s -o - | FileCheck %s --check-prefix=CS
+//
+// RUN: %clang_profgen=%t.profraw -o %t.gen.cis -O2 %s
+// RUN: %run %t.gen.cis
+// RUN: llvm-profdata merge -o %t.cis.profdata %t.profraw
+// Check context insenstive profile
+// RUN: %clang_profuse=%t.cis.profdata -O2 -emit-llvm -S %s -o - | FileCheck %s --check-prefix=CIS
+int g1 = 1;
+int volatile g2 = 2;
+static void toggle(int t) {
+ if (t & 1)
+ g1 *= t;
+ else
+ g2 *= t;
+}
+
+int main() {
+ int i;
+ // CS: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+ // CIS: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD:[0-9]+]]
+ toggle(g1);
+ // CS: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]]
+ // CIS: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD:[0-9]+]]
+ toggle(g2);
+ return 0;
+}
+
+// CS: ![[PD1]] = !{!"branch_weights", i32 0, i32 1}
+// CS: ![[PD2]] = !{!"branch_weights", i32 1, i32 0}
+// CIS: ![[PD]] = !{!"branch_weights", i32 2, i32 2}
diff --git a/test/profile/Linux/lit.local.cfg b/test/profile/Linux/lit.local.cfg
index c8c79fc7d8a7..410ffd8c5b05 100644
--- a/test/profile/Linux/lit.local.cfg
+++ b/test/profile/Linux/lit.local.cfg
@@ -21,6 +21,7 @@ def is_gold_linker_available():
return False
clang_cmd = subprocess.Popen([config.clang, '-fuse-ld=gold', '-xc', '-'],
+ universal_newlines = True,
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
diff --git a/test/profile/gcc-flag-compatibility.test b/test/profile/gcc-flag-compatibility.test
index b1087615ec51..5b05e769cb14 100644
--- a/test/profile/gcc-flag-compatibility.test
+++ b/test/profile/gcc-flag-compatibility.test
@@ -2,16 +2,16 @@ RUN: rm -rf %t.d
RUN: mkdir -p %t.d
RUN: %clang_profgen_gcc=%t.d/d1/d2 -o %t.d/code %S/Inputs/gcc-flag-compatibility.c
-# Test that the instrumented code writes to %t.d/d1/d2/default.profraw
+# Test that the instrumented code writes to %t.d/d1/d2/
RUN: %run %t.d/code
-RUN: llvm-profdata merge -o %t.profdata %t.d/d1/d2/default.profraw
+RUN: llvm-profdata merge -o %t.profdata %t.d/d1/d2/
# Test that we can override the directory and file name with LLVM_PROFILE_FILE.
RUN: env LLVM_PROFILE_FILE=%t.d/x1/prof.raw %run %t.d/code
-RUN: llvm-profdata merge -o %t.profdata %t.d/x1/prof.raw
+RUN: llvm-profdata merge -o %t.profdata %t.d/x1/
# Test that we can specify a directory with -fprofile-use.
-RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/x1/prof.raw
+RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/x1/
RUN: %clang_profuse_gcc=%t.d -o %t.d/code %S/Inputs/gcc-flag-compatibility.c
# Test that we can specify a file with -fprofile-use.
diff --git a/test/profile/instrprof-basic.c b/test/profile/instrprof-basic.c
index 02549e1506ba..dd8f3fca3f9c 100644
--- a/test/profile/instrprof-basic.c
+++ b/test/profile/instrprof-basic.c
@@ -1,21 +1,46 @@
-// REQUIRES: shell
// RUN: %clang_profgen -o %t -O3 %s
// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=ORIG
//
-// RUN: rm -f %t.profraw_e_*
-// RUN: env LLVM_PROFILE_FILE=%t.profraw_e_%1m %run %t
-// RUN: env LLVM_PROFILE_FILE=%t.profraw_e_%1m %run %t
-// RUN: llvm-profdata merge -o %t.em.profdata %t.profraw_e_*
+// RUN: rm -fr %t.dir1
+// RUN: mkdir -p %t.dir1
+// RUN: env LLVM_PROFILE_FILE=%t.dir1/profraw_e_%1m %run %t
+// RUN: env LLVM_PROFILE_FILE=%t.dir1/profraw_e_%1m %run %t
+// RUN: llvm-profdata merge -o %t.em.profdata %t.dir1
// RUN: %clang_profuse=%t.em.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=MERGE
//
-// RUN: %clang_profgen=%t.%m.profraw -o %t.merge -O3 %s
-// RUN: rm -f %t.*.profraw*
+// RUN: rm -fr %t.dir2
+// RUN: mkdir -p %t.dir2
+// RUN: %clang_profgen=%t.dir2/%m.profraw -o %t.merge -O3 %s
// RUN: %run %t.merge
// RUN: %run %t.merge
-// RUN: llvm-profdata merge -o %t.m.profdata %t.*.profraw
+// RUN: llvm-profdata merge -o %t.m.profdata %t.dir2/
// RUN: %clang_profuse=%t.m.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=MERGE
+//
+// Test that merging is enabled by default with -fprofile-generate=
+// RUN: rm -fr %t.dir3
+// RUN: mkdir -p %t.dir3
+// RUN: %clang_pgogen=%t.dir3/ -o %t.merge3 -O0 %s
+// RUN: %run %t.merge3
+// RUN: %run %t.merge3
+// RUN: %run %t.merge3
+// RUN: %run %t.merge3
+// RUN: llvm-profdata merge -o %t.m3.profdata %t.dir3/
+// RUN: %clang_profuse=%t.m3.profdata -O0 -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=PGOMERGE
+//
+// Test that merging is enabled by default with -fprofile-generate
+// RUN: rm -fr %t.dir4
+// RUN: mkdir -p %t.dir4
+// RUN: %clang_pgogen -o %t.dir4/merge4 -O0 %s
+// RUN: cd %t.dir4
+// RUN: %run %t.dir4/merge4
+// RUN: %run %t.dir4/merge4
+// RUN: %run %t.dir4/merge4
+// RUN: %run %t.dir4/merge4
+// RUN: rm -f %t.dir4/merge4
+// RUN: llvm-profdata merge -o %t.m4.profdata ./
+// RUN: %clang_profuse=%t.m4.profdata -O0 -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=PGOMERGE
int begin(int i) {
// COMMON: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
@@ -45,3 +70,5 @@ int main(int argc, const char *argv[]) {
// ORIG: ![[PD2]] = !{!"branch_weights", i32 2, i32 1}
// MERGE: ![[PD1]] = !{!"branch_weights", i32 1, i32 3}
// MERGE: ![[PD2]] = !{!"branch_weights", i32 3, i32 1}
+// PGOMERGE: ![[PD1]] = !{!"branch_weights", i32 0, i32 4}
+// PGOMERGE: ![[PD2]] = !{!"branch_weights", i32 4, i32 0}
diff --git a/test/profile/instrprof-darwin-dead-strip.c b/test/profile/instrprof-darwin-dead-strip.c
new file mode 100644
index 000000000000..64a4895a9ef9
--- /dev/null
+++ b/test/profile/instrprof-darwin-dead-strip.c
@@ -0,0 +1,60 @@
+// REQUIRES: osx-ld64-live_support
+// REQUIRES: lto
+
+// RUN: %clang_profgen=%t.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -Wl,-dead_strip -o %t %s
+// RUN: %run %t
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: llvm-profdata show --all-functions %t.profdata | FileCheck %s -check-prefix=PROF
+// RUN: llvm-cov show %t -instr-profile %t.profdata | FileCheck %s -check-prefix=COV
+// RUN: nm %t | FileCheck %s -check-prefix=NM
+// RUN: otool -s __DATA __llvm_prf_names %t | FileCheck %s -check-prefix=PRF_NAMES
+// RUN: otool -s __DATA __llvm_prf_cnts %t | FileCheck %s -check-prefix=PRF_CNTS
+
+// RUN: %clang_lto_profgen=%t.lto.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -Wl,-dead_strip -flto -o %t.lto %s
+// RUN: %run %t.lto
+// RUN: llvm-profdata merge -o %t.lto.profdata %t.lto.profraw
+// RUN: llvm-profdata show --all-functions %t.lto.profdata | FileCheck %s -check-prefix=PROF
+// RUN: llvm-cov show %t.lto -instr-profile %t.lto.profdata | FileCheck %s -check-prefix=COV
+// RUN: nm %t.lto | FileCheck %s -check-prefix=NM
+// RUN: otool -s __DATA __llvm_prf_names %t.lto | FileCheck %s -check-prefix=PRF_NAMES
+// RUN: otool -s __DATA __llvm_prf_cnts %t.lto | FileCheck %s -check-prefix=PRF_CNTS
+
+// Note: We expect foo() and some of the profiling data associated with it to
+// be dead-stripped.
+
+// COV: [[@LINE+1]]{{ *}}|{{ *}}0|void foo()
+void foo() {}
+
+// COV: [[@LINE+1]]{{ *}}|{{ *}}1|int main
+int main() { return 0; }
+
+// NM-NOT: foo
+
+// PROF: Counters:
+// PROF-NEXT: main:
+// PROF-NEXT: Hash:
+// PROF-NEXT: Counters: 1
+// PROF-NEXT: Function count: 1
+// PROF-NEXT: Functions shown: 1
+// PROF-NEXT: Total functions: 1
+// PROF-NEXT: Maximum function count: 1
+// PROF-NEXT: Maximum internal block count: 0
+
+// Note: We don't expect the names of dead-stripped functions to disappear from
+// __llvm_prf_names, because collectPGOFuncNameStrings() glues the names
+// together.
+
+// PRF_NAMES: Contents of (__DATA,__llvm_prf_names) section
+// PRF_NAMES-NEXT: {{.*}} 08 00 66 6f 6f 01 6d 61 69 6e{{ +$}}
+// | | f o o # m a i n
+// | |___________|
+// | |
+// UncompressedLen = 8 |
+// |
+// CompressedLen = 0
+
+// Note: We expect the profile counters for dead-stripped functions to also be
+// dead-stripped.
+
+// PRF_CNTS: Contents of (__DATA,__llvm_prf_cnts) section
+// PRF_CNTS-NEXT: {{.*}} 00 00 00 00 00 00 00 00{{ +$}}
diff --git a/test/profile/instrprof-dump.c b/test/profile/instrprof-dump.c
new file mode 100644
index 000000000000..93c3c46f6916
--- /dev/null
+++ b/test/profile/instrprof-dump.c
@@ -0,0 +1,62 @@
+/*
+RUN: rm -fr %t.profdir
+RUN: %clang_profgen=%t.profdir/default_%m.profraw -o %t -O2 %s
+RUN: %run %t 2>&1 | FileCheck %s --check-prefix=NO_EXIT_WRITE
+RUN: llvm-profdata merge -o %t.profdata %t.profdir
+RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s --check-prefix=PROF
+
+NO_EXIT_WRITE: Profile data not written to file: already written
+*/
+
+int __llvm_profile_dump(void);
+void __llvm_profile_reset_counters(void);
+int foo(int);
+int bar(int);
+int skip(int);
+
+int main(int argc, const char *argv[]) {
+ int Ret = foo(0); /* region 1 */
+ __llvm_profile_dump();
+
+ /* not profiled -- cleared later. */
+ skip(0); /* skipped region */
+
+ __llvm_profile_reset_counters();
+ Ret += bar(0); /* region 2 */
+ __llvm_profile_dump();
+
+ skip(1);
+
+ __llvm_profile_reset_counters();
+ /* foo's profile will be merged. */
+ foo(1); /* region 3 */
+ __llvm_profile_dump();
+
+ return Ret;
+}
+
+__attribute__((noinline)) int foo(int X) {
+ /* PROF: define {{.*}} @foo({{.*}}!prof ![[ENT:[0-9]+]]
+ PROF: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
+ */
+ return X <= 0 ? -X : X;
+}
+
+__attribute__((noinline)) int skip(int X) {
+ /* PROF: define {{.*}} @skip(
+ PROF: br i1 %{{.*}}, label %{{.*}}, label %{{[^,]+$}}
+ */
+ return X <= 0 ? -X : X;
+}
+
+__attribute__((noinline)) int bar(int X) {
+ /* PROF-LABEL: define {{.*}} @bar(
+ PROF: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]]
+ */
+ return X <= 0 ? -X : X;
+}
+
+/*
+PROF: ![[ENT]] = !{!"function_entry_count", i64 2}
+PROF: ![[PD1]] = !{!"branch_weights", i32 2, i32 2}
+*/
diff --git a/test/profile/instrprof-icall-promo.test b/test/profile/instrprof-icall-promo.test
index 5332ef0e17c9..d9b16f67782e 100644
--- a/test/profile/instrprof-icall-promo.test
+++ b/test/profile/instrprof-icall-promo.test
@@ -1,16 +1,16 @@
-RUN: %clangxx_profgen -O2 -Xclang -fprofile-instrument=llvm -c -o %t.1.o %S/Inputs/instrprof-icall-promo_1.cc
-RUN: %clangxx_profgen -O2 -Xclang -fprofile-instrument=llvm -c -o %t.2.o %S/Inputs/instrprof-icall-promo_2.cc
+# IR based instrumentation
+RUN: %clangxx_pgogen -O2 -c -o %t.1.o %S/Inputs/instrprof-icall-promo_1.cc
+RUN: %clangxx_pgogen -O2 -c -o %t.2.o %S/Inputs/instrprof-icall-promo_2.cc
-RUN: %clangxx_profgen -O2 -Xclang -fprofile-instrument=llvm %t.2.o %t.1.o -o %t.gen.1
+RUN: %clangxx_pgogen -O2 %t.2.o %t.1.o -o %t.gen.1
RUN: env LLVM_PROFILE_FILE=%t-icall.profraw %run %t.gen.1
RUN: llvm-profdata merge -o %t-icall.profdata %t-icall.profraw
-RUN: %clangxx -O2 -Rpass=pgo-icall-prom -fprofile-instr-use=%t-icall.profdata -c -o %t.2.use.o %S/Inputs/instrprof-icall-promo_2.cc 2>&1 | FileCheck %s
+RUN: %clangxx_profuse=%t-icall.profdata -O2 -Rpass=pgo-icall-prom -c -o %t.2.use.o %S/Inputs/instrprof-icall-promo_2.cc 2>&1 | FileCheck %s
-RUN: %clangxx_profgen -O2 -Xclang -fprofile-instrument=llvm %t.1.o %t.2.o -o %t.gen.2
+RUN: %clangxx_pgogen -O2 %t.1.o %t.2.o -o %t.gen.2
RUN: env LLVM_PROFILE_FILE=%t-icall2.profraw %run %t.gen.2
RUN: llvm-profdata merge -o %t-icall2.profdata %t-icall2.profraw
-# The following test will be re-enabled once a compiler bug is fixed.
-RUN: %clangxx -O2 -Rpass=pgo-icall-prom -fprofile-instr-use=%t-icall2.profdata -c -o %t.2.use.o %S/Inputs/instrprof-icall-promo_2.cc 2>&1 | FileCheck %s
+RUN: %clangxx_profuse=%t-icall2.profdata -O2 -Rpass=pgo-icall-prom -c -o %t.2.use.o %S/Inputs/instrprof-icall-promo_2.cc 2>&1 | FileCheck %s
# CHECK: Promote indirect call to
diff --git a/test/profile/instrprof-override-filename-then-reset-default.c b/test/profile/instrprof-override-filename-then-reset-default.c
index 137a3b2f2291..3438227213ec 100644
--- a/test/profile/instrprof-override-filename-then-reset-default.c
+++ b/test/profile/instrprof-override-filename-then-reset-default.c
@@ -7,13 +7,13 @@
// RUN: %clang_profuse=%t.d/default.profdata -o - -S -emit-llvm %s | FileCheck %s
-void __llvm_profile_override_default_filename(const char *);
+void __llvm_profile_set_filename(const char *);
int main(int argc, const char *argv[]) {
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
if (argc < 2)
return 1;
- __llvm_profile_override_default_filename(argv[1]);
- __llvm_profile_override_default_filename(0);
+ __llvm_profile_set_filename(argv[1]);
+ __llvm_profile_set_filename(0);
return 0;
}
// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-override-filename-with-env.c b/test/profile/instrprof-override-filename-with-env.c
index cce83891663a..3f4e5c8d251c 100644
--- a/test/profile/instrprof-override-filename-with-env.c
+++ b/test/profile/instrprof-override-filename-with-env.c
@@ -1,14 +1,14 @@
-// RUN: %clang_profgen -o %t -O3 %s
+// RUN: %clang_profgen=%t.bad.profraw -o %t -O3 %s
// RUN: env LLVM_PROFILE_FILE=%t.good.profraw %run %t %t.bad.profraw
// RUN: llvm-profdata merge -o %t.profdata %t.good.profraw
// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
-void __llvm_profile_override_default_filename(const char *);
+void bar () {}
int main(int argc, const char *argv[]) {
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
if (argc < 2)
return 1;
- __llvm_profile_override_default_filename(argv[1]);
+ bar();
return 0;
}
// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-override-filename.c b/test/profile/instrprof-override-filename.c
index 59dea29e3b88..a67c7076afb5 100644
--- a/test/profile/instrprof-override-filename.c
+++ b/test/profile/instrprof-override-filename.c
@@ -1,14 +1,14 @@
-// RUN: %clang_profgen -o %t -O3 %s
+// RUN: %clang_profgen=%t.profraw -o %t -O3 %s
// RUN: %run %t %t.profraw
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s
-void __llvm_profile_override_default_filename(const char *);
+void bar() {}
int main(int argc, const char *argv[]) {
// CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]]
if (argc < 2)
return 1;
- __llvm_profile_override_default_filename(argv[1]);
+ bar();
return 0;
}
// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2}
diff --git a/test/profile/instrprof-path.c b/test/profile/instrprof-path.c
new file mode 100644
index 000000000000..28ee8ad0a484
--- /dev/null
+++ b/test/profile/instrprof-path.c
@@ -0,0 +1,39 @@
+// RUN: %clang_pgogen -O2 -o %t.0 %s
+// RUN: %clang_pgogen=%t.d1 -O2 -o %t.1 %s
+// RUN: %clang_pgogen=%t.d1/%t.d2 -O2 -o %t.2 %s
+//
+// RUN: %run %t.0 ""
+// RUN: env LLVM_PROFILE_FILE=%t.d1/default.profraw %run %t.0 %t.d1/
+// RUN: env LLVM_PROFILE_FILE=%t.d1/%t.d2/default.profraw %run %t.0 %t.d1/%t.d2/
+// RUN: %run %t.1 %t.d1/
+// RUN: %run %t.2 %t.d1/%t.d2/
+// RUN: %run %t.2 %t.d1/%t.d2/ %t.d1/%t.d2/%t.d3/blah.profraw %t.d1/%t.d2/%t.d3/
+
+#include <string.h>
+
+const char *__llvm_profile_get_path_prefix();
+void __llvm_profile_set_filanem(const char*);
+
+int main(int argc, const char *argv[]) {
+ int i;
+ const char *expected;
+ const char *prefix;
+ if (argc < 2)
+ return 1;
+
+ expected = argv[1];
+ prefix = __llvm_profile_get_path_prefix();
+
+ if (strcmp(prefix, expected))
+ return 1;
+
+ if (argc == 4) {
+ __llvm_profile_set_filename(argv[2]);
+ prefix = __llvm_profile_get_path_prefix();
+ expected = argv[3];
+ if (strcmp(prefix, expected))
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/test/profile/Linux/instrprof-set-filename-shared.test b/test/profile/instrprof-set-filename-shared.test
index 29e6713289d9..afcb4b4fd2d6 100644
--- a/test/profile/Linux/instrprof-set-filename-shared.test
+++ b/test/profile/instrprof-set-filename-shared.test
@@ -1,7 +1,7 @@
# Test that __llvm_profile_set_filename is honored by shared libary too.
RUN: mkdir -p %t.d
-RUN: %clang_profgen=%t.shared.profraw -fPIC -shared -o %t.d/t.shared %S/../Inputs/instrprof-dlopen-func.c
-RUN: %clang_profgen -DCALL_SHARED -o %t.m -O3 -rpath %t.d %t.d/t.shared %S/../instrprof-set-filename.c
+RUN: %clang_profgen=%t.shared.profraw -fPIC -shared -o %t.d/t.shared %S/Inputs/instrprof-dlopen-func.c
+RUN: %clang_profgen -DCALL_SHARED -o %t.m -O3 -rpath %t.d %t.d/t.shared %S/instrprof-set-filename.c
RUN: %run %t.m %t.main.profraw
RUN: llvm-profdata show %t.main.profraw | FileCheck --check-prefix=SHARED %s
diff --git a/test/profile/instrprof-value-prof-evict.test b/test/profile/instrprof-value-prof-evict.test
index de82581e451a..8b054fb24371 100644
--- a/test/profile/instrprof-value-prof-evict.test
+++ b/test/profile/instrprof-value-prof-evict.test
@@ -4,13 +4,13 @@
// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %S/Inputs/instrprof-value-prof-evict.c
// IR level instrumentation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=10 -Xclang -fprofile-instrument=llvm -o %t.ir %S/Inputs/instrprof-value-prof-evict.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=10 -o %t.ir %S/Inputs/instrprof-value-prof-evict.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.profraw %run %t.ir
// RUN: llvm-profdata merge -o %t.ir.profdata %t.ir.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.profdata | FileCheck %S/Inputs/instrprof-value-prof-evict.c
// IR level instrumentation, dynamic allocation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -Xclang -fprofile-instrument=llvm -o %t.ir.dyn %S/Inputs/instrprof-value-prof-evict.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -o %t.ir.dyn %S/Inputs/instrprof-value-prof-evict.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.dyn.profraw %run %t.ir.dyn
// RUN: llvm-profdata merge -o %t.ir.dyn.profdata %t.ir.dyn.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.dyn.profdata | FileCheck %S/Inputs/instrprof-value-prof-evict.c
diff --git a/test/profile/instrprof-value-prof-reset.c b/test/profile/instrprof-value-prof-reset.c
new file mode 100644
index 000000000000..b3744f573506
--- /dev/null
+++ b/test/profile/instrprof-value-prof-reset.c
@@ -0,0 +1,47 @@
+// RUN: %clang_profgen -O2 -mllvm -enable-value-profiling=true -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=3 -o %t %s
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %s
+
+// IR level instrumentation
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=3 -o %t.ir %s
+// RUN: env LLVM_PROFILE_FILE=%t.ir.profraw %run %t.ir
+// RUN: llvm-profdata merge -o %t.ir.profdata %t.ir.profraw
+// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.profdata | FileCheck %s
+
+// IR level instrumentation, dynamic allocation
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -o %t.ir.dyn %s
+// RUN: env LLVM_PROFILE_FILE=%t.ir.dyn.profraw %run %t.ir.dyn
+// RUN: llvm-profdata merge -o %t.ir.dyn.profdata %t.ir.dyn.profraw
+// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.dyn.profdata | FileCheck %s
+void callee_0() {}
+void callee_1() {}
+void callee_2() {}
+
+void *CalleeAddrs[] = {callee_0, callee_1, callee_2, callee_2, callee_2};
+extern void lprofSetMaxValsPerSite(unsigned);
+extern void __llvm_profile_reset_counters();
+
+typedef void (*FPT)(void);
+
+
+// Testing value profiling eviction algorithm.
+FPT getCalleeFunc(int I) { return CalleeAddrs[I]; }
+
+int main() {
+ int I;
+
+ // First fill up two value profile entries with two targets
+ lprofSetMaxValsPerSite(2);
+
+ for (I = 0; I < 5; I++) {
+ if (I == 2) {
+ __llvm_profile_reset_counters();
+ }
+ // CHECK: callee_2, 3
+ // CHECK-NEXT: callee_1, 0
+ // CHECK-NOT: callee_0,
+ FPT FP = getCalleeFunc(I);
+ FP();
+ }
+}
diff --git a/test/profile/instrprof-value-prof-shared.test b/test/profile/instrprof-value-prof-shared.test
index 5b6d627dbaf9..a45b0d55b236 100644
--- a/test/profile/instrprof-value-prof-shared.test
+++ b/test/profile/instrprof-value-prof-shared.test
@@ -7,8 +7,9 @@
// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=SHARED
// IR level instrumentation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir %t.d/t.ir.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir %t.d/t.ir.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
+// Profile data from shared library will be concatenated to the same raw file.
// RUN: env LLVM_PROFILE_FILE=%t.ir.profraw LLVM_VP_MAX_NUM_VALS_PER_SITE=255 %run %t.ir
// RUN: llvm-profdata merge -o %t.ir.profdata %t.ir.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
@@ -16,9 +17,23 @@
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=SHARED
// RUN: FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=IR < %t.ir.proftxt
+// Same as above but with profile online merging enabled.
+// RUN: rm -fr %t.prof/
+// RUN: mkdir -p %t.prof/
+// RUN: %clang_pgogen=%t.prof -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.m.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen=%t.prof -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir.m %t.d/t.ir.m.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
+// RUN: env LLVM_VP_MAX_NUM_VALS_PER_SITE=255 %run %t.ir.m
+// RUN: llvm-profdata merge -o %t.ir.m.profdata -dump-input-file-list %t.prof/ | count 2
+// RUN: llvm-profdata merge -o %t.ir.m.profdata %t.prof/
+// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.m.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
+// RUN: llvm-profdata merge -text %t.ir.m.profdata -o %t.ir.m.proftxt
+// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.m.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=SHARED
+// RUN: FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=IR < %t.ir.m.proftxt
+
+
// IR level instrumentation: dynamic memory allocation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.dyn.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir.dyn %t.d/t.ir.dyn.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.dyn.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir.dyn %t.d/t.ir.dyn.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.dyn.profraw %run %t.ir.dyn
// RUN: llvm-profdata merge -o %t.ir.dyn.profdata %t.ir.dyn.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.dyn.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
@@ -27,8 +42,8 @@
// RUN: FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=IR < %t.ir.dyn.proftxt
// IR level instrumentation: main program uses static counter, shared library uses dynamic memory alloc.
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.dyn.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir.mixed %t.d/t.ir.dyn.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -fPIC -shared -o %t.d/t.ir.dyn.shared -DSHARED_LIB %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -rpath %t.d -o %t.ir.mixed %t.d/t.ir.dyn.shared -DCALL_SHARED %S/Inputs/instrprof-value-prof-real.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.mixed.profraw LLVM_VP_MAX_NUM_VALS_PER_SITE=255 %run %t.ir.mixed
// RUN: llvm-profdata merge -o %t.ir.mixed.profdata %t.ir.mixed.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.mixed.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
diff --git a/test/profile/instrprof-value-prof.test b/test/profile/instrprof-value-prof.test
index 8e7f513d20cb..02038990bfd9 100644
--- a/test/profile/instrprof-value-prof.test
+++ b/test/profile/instrprof-value-prof.test
@@ -4,7 +4,7 @@
// RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
// IR level instrumentation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -o %t.ir %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=true -mllvm -vp-counters-per-site=256 -o %t.ir %S/Inputs/instrprof-value-prof-real.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.profraw LLVM_VP_MAX_NUM_VALS_PER_SITE=255 %run %t.ir
// RUN: llvm-profdata merge -o %t.ir.profdata %t.ir.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
@@ -12,7 +12,7 @@
// RUN: FileCheck %S/Inputs/instrprof-value-prof-real.c --check-prefix=IR < %t.ir.proftxt
// IR level instrumentation with dynamic memory allocation
-// RUN: %clang_profgen -O2 -mllvm -disable-vp=false -Xclang -fprofile-instrument=llvm -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -o %t.ir.dyn %S/Inputs/instrprof-value-prof-real.c
+// RUN: %clang_pgogen -O2 -mllvm -disable-vp=false -mllvm -vp-static-alloc=false -mllvm -vp-counters-per-site=256 -o %t.ir.dyn %S/Inputs/instrprof-value-prof-real.c
// RUN: env LLVM_PROFILE_FILE=%t.ir.dyn.profraw %run %t.ir.dyn
// RUN: llvm-profdata merge -o %t.ir.dyn.profdata %t.ir.dyn.profraw
// RUN: llvm-profdata show --all-functions -ic-targets %t.ir.dyn.profdata | FileCheck %S/Inputs/instrprof-value-prof-real.c
diff --git a/test/profile/instrprof-visibility.cpp b/test/profile/instrprof-visibility.cpp
index 08b886536fb4..6fbba9defc56 100644
--- a/test/profile/instrprof-visibility.cpp
+++ b/test/profile/instrprof-visibility.cpp
@@ -56,34 +56,34 @@ int main() {
// --- Check coverage for functions in the anonymous namespace.
// COV-DAG: instrprof-visibility.cpp:_ZN12_GLOBAL__N_14callEv
-// COV-DAG: 1|{{.*}}|void call() {
-// COV-DAG: 1|{{.*}}| f1();
-// COV-DAG: 1|{{.*}}|#ifndef NO_WEAK
-// COV-DAG: |{{.*}}| f2();
-// COV-DAG: |{{.*}}|#endif
-// COV-DAG: 1|{{.*}}| f3();
-// COV-DAG: 1|{{.*}}|#ifndef NO_EXTERN
-// COV-DAG: |{{.*}}| f4();
-// COV-DAG: |{{.*}}|#endif
-// COV-DAG: 1|{{.*}}| f5();
-// COV-DAG: 1|{{.*}}| f6();
-// COV-DAG: 1|{{.*}}| f7();
-// COV-DAG: 1|{{.*}}|}
+// COV-DAG: [[CALL:[0-9]+]]|{{ *}}1|void call() {
+// COV-DAG: {{.*}}|{{ *}}1| f1();
+// COV-DAG: {{.*}}|{{ *}}1|#ifndef NO_WEAK
+// COV-DAG: {{.*}}|{{ *}} | f2();
+// COV-DAG: {{.*}}|{{ *}} |#endif
+// COV-DAG: {{.*}}|{{ *}}1| f3();
+// COV-DAG: {{.*}}|{{ *}}1|#ifndef NO_EXTERN
+// COV-DAG: {{.*}}|{{ *}} | f4();
+// COV-DAG: {{.*}}|{{ *}} |#endif
+// COV-DAG: {{.*}}|{{ *}}1| f5();
+// COV-DAG: {{.*}}|{{ *}}1| f6();
+// COV-DAG: {{.*}}|{{ *}}1| f7();
+// COV-DAG: {{.*}}|{{ *}}1|}
// --- Check coverage for functions in namespace N1.
// COV-DAG: _ZN2N14callEv
-// COV-DAG: 1|{{.*}}|void call() {
-// COV-DAG: 1|{{.*}}| f1();
-// COV-DAG: 1|{{.*}}|#ifndef NO_WEAK
-// COV-DAG: 1|{{.*}}| f2();
-// COV-DAG: 1|{{.*}}|#endif
-// COV-DAG: 1|{{.*}}| f3();
-// COV-DAG: 1|{{.*}}|#ifndef NO_EXTERN
-// COV-DAG: 1|{{.*}}| f4();
-// COV-DAG: 1|{{.*}}|#endif
-// COV-DAG: 1|{{.*}}| f5();
-// COV-DAG: 1|{{.*}}| f6();
-// COV-DAG: 1|{{.*}}| f7();
-// COV-DAG: 1|{{.*}}|}
+// COV-DAG: {{ *}}[[CALL]]|{{ *}}1|void call() {
+// COV-DAG: {{.*}}|{{ *}}1| f1();
+// COV-DAG: {{.*}}|{{ *}}1|#ifndef NO_WEAK
+// COV-DAG: {{.*}}|{{ *}}1| f2();
+// COV-DAG: {{.*}}|{{ *}}1|#endif
+// COV-DAG: {{.*}}|{{ *}}1| f3();
+// COV-DAG: {{.*}}|{{ *}}1|#ifndef NO_EXTERN
+// COV-DAG: {{.*}}|{{ *}}1| f4();
+// COV-DAG: {{.*}}|{{ *}}1|#endif
+// COV-DAG: {{.*}}|{{ *}}1| f5();
+// COV-DAG: {{.*}}|{{ *}}1| f6();
+// COV-DAG: {{.*}}|{{ *}}1| f7();
+// COV-DAG: {{.*}}|{{ *}}1|}
// COV-DAG: instrprof-visibility.cpp
diff --git a/test/profile/lit.cfg b/test/profile/lit.cfg
index 3512e0abcf1a..a6e6ef81c622 100644
--- a/test/profile/lit.cfg
+++ b/test/profile/lit.cfg
@@ -49,20 +49,35 @@ target_cflags=[get_required_attr(config, "target_cflags")]
clang_cflags = target_cflags + extra_linkflags
clang_cxxflags = config.cxx_mode_flags + clang_cflags
-def build_invocation(compile_flags):
- return " " + " ".join([config.clang] + compile_flags) + " "
+def build_invocation(compile_flags, with_lto = False):
+ lto_flags = []
+ lto_prefix = []
+ if with_lto and config.lto_supported:
+ lto_flags += config.lto_flags
+ lto_prefix += config.lto_launch
+ return " " + " ".join(lto_prefix + [config.clang] + lto_flags + compile_flags) + " "
# Add clang substitutions.
config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) )
config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
config.substitutions.append( ("%clang_profgen ", build_invocation(clang_cflags) + " -fprofile-instr-generate ") )
config.substitutions.append( ("%clang_profgen=", build_invocation(clang_cflags) + " -fprofile-instr-generate=") )
-config.substitutions.append( ("%clang_profuse=", build_invocation(clang_cflags) + " -fprofile-instr-use=") )
+config.substitutions.append( ("%clang_pgogen ", build_invocation(clang_cflags) + " -fprofile-generate ") )
+config.substitutions.append( ("%clang_pgogen=", build_invocation(clang_cflags) + " -fprofile-generate=") )
+
config.substitutions.append( ("%clangxx_profgen ", build_invocation(clang_cxxflags) + " -fprofile-instr-generate ") )
-config.substitutions.append( ("%clangxx_profuse=", build_invocation(clang_cxxflags) + " -fprofile-instr-use=") )
+config.substitutions.append( ("%clangxx_profgen=", build_invocation(clang_cxxflags) + " -fprofile-instr-generate=") )
+config.substitutions.append( ("%clangxx_pgogen ", build_invocation(clang_cxxflags) + " -fprofile-generate ") )
+config.substitutions.append( ("%clangxx_pgogen=", build_invocation(clang_cxxflags) + " -fprofile-generate=") )
+
config.substitutions.append( ("%clang_profgen_gcc=", build_invocation(clang_cflags) + " -fprofile-generate=") )
config.substitutions.append( ("%clang_profuse_gcc=", build_invocation(clang_cflags) + " -fprofile-use=") )
+config.substitutions.append( ("%clang_profuse=", build_invocation(clang_cflags) + " -fprofile-instr-use=") )
+config.substitutions.append( ("%clangxx_profuse=", build_invocation(clang_cxxflags) + " -fprofile-instr-use=") )
+
+config.substitutions.append( ("%clang_lto_profgen=", build_invocation(clang_cflags, True) + " -fprofile-instr-generate=") )
+
if config.host_os not in ['Darwin', 'FreeBSD', 'Linux']:
config.unsupported = True