[compiler-rt] effb87d - [profile] Add -fprofile-instr-generate tests for weak definition and various linkages

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 2 16:12:13 PDT 2021


Author: Fangrui Song
Date: 2021-06-02T16:12:08-07:00
New Revision: effb87dfa810a28e763f914fe3e6e984782cc846

URL: https://github.com/llvm/llvm-project/commit/effb87dfa810a28e763f914fe3e6e984782cc846
DIFF: https://github.com/llvm/llvm-project/commit/effb87dfa810a28e763f914fe3e6e984782cc846.diff

LOG: [profile] Add -fprofile-instr-generate tests for weak definition and various linkages

Added: 
    compiler-rt/test/profile/Linux/coverage-linkage-lld.cpp
    compiler-rt/test/profile/Linux/coverage-linkage.cpp
    compiler-rt/test/profile/Linux/coverage-weak-lld.cpp
    compiler-rt/test/profile/Windows/coverage-linkage-lld.cpp
    compiler-rt/test/profile/Windows/coverage-linkage.cpp
    compiler-rt/test/profile/Windows/coverage-weak-lld.cpp

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/compiler-rt/test/profile/Linux/coverage-linkage-lld.cpp b/compiler-rt/test/profile/Linux/coverage-linkage-lld.cpp
new file mode 100644
index 0000000000000..549633867c759
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/coverage-linkage-lld.cpp
@@ -0,0 +1,8 @@
+// REQUIRES: lld-available
+/// With lld --gc-sections we can ensure discarded[01] and their profc/profd
+/// variables are discarded.
+
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -fuse-ld=lld -Wl,--gc-sections %S/coverage-linkage.cpp -o %t
+// RUN: llvm-nm %t | FileCheck %s
+
+// CHECK-NOT: discarded{{.*}}

diff  --git a/compiler-rt/test/profile/Linux/coverage-linkage.cpp b/compiler-rt/test/profile/Linux/coverage-linkage.cpp
new file mode 100644
index 0000000000000..df0674ec0329f
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/coverage-linkage.cpp
@@ -0,0 +1,46 @@
+/// Test instrumentation can handle various linkages.
+// RUN: %clang_profgen -fcoverage-mapping %s -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s
+
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -Wl,--gc-sections %s -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s
+
+// CHECK:      {{.*}}external{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}weak{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      main:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}internal{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}linkonce_odr{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+
+#include <stdio.h>
+
+void discarded0() {}
+__attribute__((weak)) void discarded1() {}
+
+void external() { puts("external"); }
+__attribute__((weak)) void weak() { puts("weak"); }
+static void internal() { puts("internal"); }
+__attribute__((noinline)) inline void linkonce_odr() { puts("linkonce_odr"); }
+
+int main() {
+  internal();
+  external();
+  weak();
+  linkonce_odr();
+}

diff  --git a/compiler-rt/test/profile/Linux/coverage-weak-lld.cpp b/compiler-rt/test/profile/Linux/coverage-weak-lld.cpp
new file mode 100644
index 0000000000000..de624dd73b859
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/coverage-weak-lld.cpp
@@ -0,0 +1,103 @@
+// REQUIRES: lld-available
+
+// RUN: %clang_profgen -fcoverage-mapping -c %s -o %t0.o
+// RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_1 -o %t1.o
+// RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_2 -o %t2.o
+
+/// An external symbol can override a weak external symbol.
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
+
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_NOGC
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_GC
+
+/// Repeat the above tests with -ffunction-sections.
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -o %t0.o
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_1 -o %t1.o
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_2 -o %t2.o
+
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_GC
+
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_NOGC
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_GC
+
+// CHECK1: strong
+// CHECK1: strong
+
+/// __profc__Z4weakv in %t1.o is local and has a zero value.
+/// Without GC it takes a duplicate entry.
+// PROFILE1_NOGC:      _Z4weakv:
+// PROFILE1_NOGC-NEXT:    Hash:
+// PROFILE1_NOGC-NEXT:    Counters: 1
+// PROFILE1_NOGC-NEXT:    Function count: 0
+// PROFILE1_NOGC:      _Z4weakv:
+// PROFILE1_NOGC-NEXT:    Hash:
+// PROFILE1_NOGC-NEXT:    Counters: 1
+// PROFILE1_NOGC-NEXT:    Function count: 2
+
+// PROFILE1_GC:      _Z4weakv:
+// PROFILE1_GC-NEXT:    Hash:
+// PROFILE1_GC-NEXT:    Counters: 1
+// PROFILE1_GC-NEXT:    Function count: 2
+// PROFILE1_GC-NOT:  _Z4weakv:
+
+// CHECK2: weak
+// CHECK2: weak
+
+/// __profc__Z4weakv in %t2.o is weak and resolves to the value of %t0.o's copy.
+/// Without GC it takes a duplicate entry.
+// PROFILE2_NOGC:      _Z4weakv:
+// PROFILE2_NOGC-NEXT:    Hash:
+// PROFILE2_NOGC-NEXT:    Counters: 1
+// PROFILE2_NOGC-NEXT:    Function count: 2
+// PROFILE2_NOGC:      _Z4weakv:
+// PROFILE2_NOGC-NEXT:    Hash:
+// PROFILE2_NOGC-NEXT:    Counters: 1
+// PROFILE2_NOGC-NEXT:    Function count: 2
+
+// PROFILE2_GC:      _Z4weakv:
+// PROFILE2_GC-NEXT:    Hash:
+// PROFILE2_GC-NEXT:    Counters: 1
+// PROFILE2_GC-NEXT:    Function count: 2
+// PROFILE2_GC-NOT:  _Z4weakv:
+
+#ifdef OBJ_1
+#include <stdio.h>
+
+void weak() { puts("strong"); }
+void foo() { weak(); }
+
+#elif defined(OBJ_2)
+#include <stdio.h>
+
+__attribute__((weak)) void weak() { puts("unreachable"); }
+void foo() { weak(); }
+
+#else
+#include <stdio.h>
+
+__attribute__((weak)) void weak() { puts("weak"); }
+void foo();
+
+int main() {
+  foo();
+  weak();
+}
+#endif

diff  --git a/compiler-rt/test/profile/Windows/coverage-linkage-lld.cpp b/compiler-rt/test/profile/Windows/coverage-linkage-lld.cpp
new file mode 100644
index 0000000000000..714e4513bc20f
--- /dev/null
+++ b/compiler-rt/test/profile/Windows/coverage-linkage-lld.cpp
@@ -0,0 +1,11 @@
+// REQUIRES: lld-available
+/// With lld -opt:ref we can ensure discarded[01] and their profc/profd
+/// variables are discarded.
+
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -fuse-ld=lld -Wl,-debug:symtab,-opt:noref %S/coverage-linkage.cpp -o %t
+// RUN: llvm-nm %t | FileCheck %s --check-prefix=NOGC
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -fuse-ld=lld -Wl,-debug:symtab,-opt:ref %S/coverage-linkage.cpp -o %t
+// RUN: llvm-nm %t | FileCheck %s --check-prefix=GC
+
+// NOGC:   T ?discarded{{.*}}
+// GC-NOT: T ?discarded{{.*}}

diff  --git a/compiler-rt/test/profile/Windows/coverage-linkage.cpp b/compiler-rt/test/profile/Windows/coverage-linkage.cpp
new file mode 100644
index 0000000000000..648b3fb73a5d4
--- /dev/null
+++ b/compiler-rt/test/profile/Windows/coverage-linkage.cpp
@@ -0,0 +1,46 @@
+/// Test instrumentation can handle various linkages.
+// RUN: %clang_profgen -fcoverage-mapping %s -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s
+
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -Wl,-opt:ref %s -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s
+
+// CHECK:      {{.*}}external{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}weak{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      main:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}internal{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+// CHECK:      {{.*}}linkonce_odr{{.*}}:
+// CHECK-NEXT:    Hash:
+// CHECK-NEXT:    Counters: 1
+// CHECK-NEXT:    Function count: 1
+
+#include <stdio.h>
+
+void discarded0() {}
+__attribute__((weak)) void discarded1() {}
+
+void external() { puts("external"); }
+__attribute__((weak)) void weak() { puts("weak"); }
+static void internal() { puts("internal"); }
+__attribute__((noinline)) inline void linkonce_odr() { puts("linkonce_odr"); }
+
+int main() {
+  internal();
+  external();
+  weak();
+  linkonce_odr();
+}

diff  --git a/compiler-rt/test/profile/Windows/coverage-weak-lld.cpp b/compiler-rt/test/profile/Windows/coverage-weak-lld.cpp
new file mode 100644
index 0000000000000..b1708433cec22
--- /dev/null
+++ b/compiler-rt/test/profile/Windows/coverage-weak-lld.cpp
@@ -0,0 +1,85 @@
+// REQUIRES: lld-available
+
+// RUN: %clang_profgen -fcoverage-mapping -c %s -o %t0.o
+// RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_1 -o %t1.o
+// RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_2 -o %t2.o
+
+/// An external symbol can override a weak external symbol.
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-opt:noref %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-opt:ref %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1
+
+/// link.exe does not support weak overridding weak.
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-lldmingw,-opt:ref %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2
+
+/// Repeat the above tests with -ffunction-sections (associative comdat).
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -o %t0.o
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_1 -o %t1.o
+// RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_2 -o %t2.o
+
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-opt:noref %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-opt:ref %t0.o %t1.o -o %t1
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1
+
+// RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,-lldmingw,-opt:ref %t0.o %t2.o -o %t2
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
+// RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2
+
+// CHECK1: strong
+// CHECK1: strong
+
+/// Document the current behavior:
+///  __profc_?weak@@YAXXZ in %t1.o is local and has a zero value.
+/// Without GC it takes a duplicate entry.
+// PROFILE1:      ?weak@@YAXXZ:
+// PROFILE1-NEXT:    Hash:
+// PROFILE1-NEXT:    Counters: 1
+// PROFILE1-NEXT:    Function count: 0
+// PROFILE1:      ?weak@@YAXXZ:
+// PROFILE1-NEXT:    Hash:
+// PROFILE1-NEXT:    Counters: 1
+// PROFILE1-NEXT:    Function count: 2
+
+// CHECK2: weak
+// CHECK2: weak
+
+// PROFILE2:      ?weak@@YAXXZ:
+// PROFILE2-NEXT:    Hash:
+// PROFILE2-NEXT:    Counters: 1
+// PROFILE2-NEXT:    Function count: 2
+// PROFILE2:      ?weak@@YAXXZ:
+// PROFILE2-NEXT:    Hash:
+// PROFILE2-NEXT:    Counters: 1
+// PROFILE2-NEXT:    Function count: 0
+
+#ifdef OBJ_1
+#include <stdio.h>
+
+void weak() { puts("strong"); }
+void foo() { weak(); }
+
+#elif defined(OBJ_2)
+#include <stdio.h>
+
+__attribute__((weak)) void weak() { puts("unreachable"); }
+void foo() { weak(); }
+
+#else
+#include <stdio.h>
+
+__attribute__((weak)) void weak() { puts("weak"); }
+void foo();
+
+int main() {
+  foo();
+  weak();
+}
+#endif


        


More information about the llvm-commits mailing list