1; REQUIRES: x86
2;; This test verifies that --wrap works correctly for inter-module references to
3;; the wrapped symbol, when LTO or ThinLTO is involved. It checks for various
4;; combinations of bitcode and regular objects.
5
6;; LTO + LTO
7; RUN: llvm-as %s -o %t1.bc
8; RUN: llvm-as %S/Inputs/wrap-bar.ll -o %t2.bc
9; RUN: ld.lld %t1.bc %t2.bc -shared -o %t.bc-bc.so -wrap=bar
10; RUN: llvm-objdump -d %t.bc-bc.so | FileCheck %s --check-prefixes=CHECK,JMP
11; RUN: llvm-readobj --symbols %t.bc-bc.so | FileCheck --check-prefix=BIND %s
12
13;; LTO + Object
14; RUN: llc %S/Inputs/wrap-bar.ll -o %t2.o --filetype=obj
15; RUN: ld.lld %t1.bc %t2.o -shared -o %t.bc-o.so -wrap=bar
16; RUN: llvm-objdump -d %t.bc-o.so | FileCheck %s --check-prefixes=CHECK,JMP
17; RUN: llvm-readobj --symbols %t.bc-o.so | FileCheck --check-prefix=BIND %s
18
19;; Object + LTO
20; RUN: llc %s -o %t1.o --filetype=obj
21; RUN: ld.lld %t1.o %t2.bc -shared -o %t.o-bc.so -wrap=bar
22; RUN: llvm-objdump -d %t.o-bc.so | FileCheck %s --check-prefixes=CHECK,CALL
23; RUN: llvm-readobj --symbols %t.o-bc.so | FileCheck --check-prefix=BIND %s
24
25;; ThinLTO + ThinLTO
26; RUN: opt -module-summary %s -o %t1.thin
27; RUN: opt -module-summary %S/Inputs/wrap-bar.ll -o %t2.thin
28; RUN: ld.lld %t1.thin %t2.thin -shared -o %t.thin-thin.so -wrap=bar
29; RUN: llvm-objdump -d %t.thin-thin.so | FileCheck %s --check-prefixes=CHECK,JMP
30; RUN: llvm-readobj --symbols %t.thin-thin.so | FileCheck --check-prefix=BIND %s
31
32;; ThinLTO + Object
33; RUN: ld.lld %t1.thin %t2.o -shared -o %t.thin-o.so -wrap=bar
34; RUN: llvm-objdump -d %t.thin-o.so | FileCheck %s --check-prefixes=CHECK,JMP
35; RUN: llvm-readobj --symbols %t.thin-o.so | FileCheck --check-prefix=BIND %s
36
37;; Object + ThinLTO
38; RUN: ld.lld %t1.o %t2.thin -shared -o %t.o-thin.so -wrap=bar
39; RUN: llvm-objdump -d %t.o-thin.so | FileCheck %s --check-prefixes=CHECK,CALL
40; RUN: llvm-readobj --symbols %t.o-thin.so | FileCheck --check-prefix=BIND %s
41
42;; Make sure that calls in foo() are not eliminated and that bar is
43;; routed to __wrap_bar and __real_bar is routed to bar.
44
45; CHECK:      <foo>:
46; CHECK-NEXT: pushq	%rax
47; CHECK-NEXT: callq{{.*}}<__wrap_bar>
48; JMP-NEXT:   popq  %rax
49; JMP-NEXT:   jmp{{.*}}<bar>
50; CALL-NEXT:  callq{{.*}}<bar>
51; CALL-NEXT:  popq  %rax
52
53;; Check that bar and __wrap_bar retain their original binding.
54; BIND:      Name: bar
55; BIND-NEXT: Value:
56; BIND-NEXT: Size:
57; BIND-NEXT: Binding: Local
58; BIND:      Name: __wrap_bar
59; BIND-NEXT: Value:
60; BIND-NEXT: Size:
61; BIND-NEXT: Binding: Local
62
63target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
64target triple = "x86_64-unknown-linux-gnu"
65
66declare void @bar()
67declare void @__real_bar()
68
69define void @foo() {
70  call void @bar()
71  call void @__real_bar()
72  ret void
73}
74