1*effb87dfSFangrui Song // REQUIRES: lld-available
2*effb87dfSFangrui Song 
3*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -c %s -o %t0.o
4*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_1 -o %t1.o
5*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -c %s -DOBJ_2 -o %t2.o
6*effb87dfSFangrui Song 
7*effb87dfSFangrui Song /// An external symbol can override a weak external symbol.
8*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t1.o -o %t1
9*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
10*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
11*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t1.o -o %t1
12*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
13*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
14*effb87dfSFangrui Song 
15*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t2.o -o %t2
16*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
17*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_NOGC
18*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t2.o -o %t2
19*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
20*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_GC
21*effb87dfSFangrui Song 
22*effb87dfSFangrui Song /// Repeat the above tests with -ffunction-sections.
23*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -o %t0.o
24*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_1 -o %t1.o
25*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -ffunction-sections -c %s -DOBJ_2 -o %t2.o
26*effb87dfSFangrui Song 
27*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t1.o -o %t1
28*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
29*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_NOGC
30*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t1.o -o %t1
31*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t1 | FileCheck %s --check-prefix=CHECK1
32*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE1_GC
33*effb87dfSFangrui Song 
34*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld %t0.o %t2.o -o %t2
35*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
36*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_NOGC
37*effb87dfSFangrui Song // RUN: %clang_profgen -fcoverage-mapping -fuse-ld=lld -Wl,--gc-sections %t0.o %t2.o -o %t2
38*effb87dfSFangrui Song // RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t2 | FileCheck %s --check-prefix=CHECK2
39*effb87dfSFangrui Song // RUN: llvm-profdata show %t.profraw --all-functions | FileCheck %s --check-prefix=PROFILE2_GC
40*effb87dfSFangrui Song 
41*effb87dfSFangrui Song // CHECK1: strong
42*effb87dfSFangrui Song // CHECK1: strong
43*effb87dfSFangrui Song 
44*effb87dfSFangrui Song /// __profc__Z4weakv in %t1.o is local and has a zero value.
45*effb87dfSFangrui Song /// Without GC it takes a duplicate entry.
46*effb87dfSFangrui Song // PROFILE1_NOGC:      _Z4weakv:
47*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Hash:
48*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Counters: 1
49*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Function count: 0
50*effb87dfSFangrui Song // PROFILE1_NOGC:      _Z4weakv:
51*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Hash:
52*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Counters: 1
53*effb87dfSFangrui Song // PROFILE1_NOGC-NEXT:    Function count: 2
54*effb87dfSFangrui Song 
55*effb87dfSFangrui Song // PROFILE1_GC:      _Z4weakv:
56*effb87dfSFangrui Song // PROFILE1_GC-NEXT:    Hash:
57*effb87dfSFangrui Song // PROFILE1_GC-NEXT:    Counters: 1
58*effb87dfSFangrui Song // PROFILE1_GC-NEXT:    Function count: 2
59*effb87dfSFangrui Song // PROFILE1_GC-NOT:  _Z4weakv:
60*effb87dfSFangrui Song 
61*effb87dfSFangrui Song // CHECK2: weak
62*effb87dfSFangrui Song // CHECK2: weak
63*effb87dfSFangrui Song 
64*effb87dfSFangrui Song /// __profc__Z4weakv in %t2.o is weak and resolves to the value of %t0.o's copy.
65*effb87dfSFangrui Song /// Without GC it takes a duplicate entry.
66*effb87dfSFangrui Song // PROFILE2_NOGC:      _Z4weakv:
67*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Hash:
68*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Counters: 1
69*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Function count: 2
70*effb87dfSFangrui Song // PROFILE2_NOGC:      _Z4weakv:
71*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Hash:
72*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Counters: 1
73*effb87dfSFangrui Song // PROFILE2_NOGC-NEXT:    Function count: 2
74*effb87dfSFangrui Song 
75*effb87dfSFangrui Song // PROFILE2_GC:      _Z4weakv:
76*effb87dfSFangrui Song // PROFILE2_GC-NEXT:    Hash:
77*effb87dfSFangrui Song // PROFILE2_GC-NEXT:    Counters: 1
78*effb87dfSFangrui Song // PROFILE2_GC-NEXT:    Function count: 2
79*effb87dfSFangrui Song // PROFILE2_GC-NOT:  _Z4weakv:
80*effb87dfSFangrui Song 
81*effb87dfSFangrui Song #ifdef OBJ_1
82*effb87dfSFangrui Song #include <stdio.h>
83*effb87dfSFangrui Song 
weak()84*effb87dfSFangrui Song void weak() { puts("strong"); }
foo()85*effb87dfSFangrui Song void foo() { weak(); }
86*effb87dfSFangrui Song 
87*effb87dfSFangrui Song #elif defined(OBJ_2)
88*effb87dfSFangrui Song #include <stdio.h>
89*effb87dfSFangrui Song 
weak()90*effb87dfSFangrui Song __attribute__((weak)) void weak() { puts("unreachable"); }
foo()91*effb87dfSFangrui Song void foo() { weak(); }
92*effb87dfSFangrui Song 
93*effb87dfSFangrui Song #else
94*effb87dfSFangrui Song #include <stdio.h>
95*effb87dfSFangrui Song 
weak()96*effb87dfSFangrui Song __attribute__((weak)) void weak() { puts("weak"); }
97*effb87dfSFangrui Song void foo();
98*effb87dfSFangrui Song 
main()99*effb87dfSFangrui Song int main() {
100*effb87dfSFangrui Song   foo();
101*effb87dfSFangrui Song   weak();
102*effb87dfSFangrui Song }
103*effb87dfSFangrui Song #endif
104