1; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
2; RUN:     -O2 < %s | \
3; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,TAILCALL-32R2
4
5; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
6; RUN:     -O2 < %s | \
7; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,TAILCALL-64R2
8
9; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
10; RUN:     -O2 -mcpu=mips32r6 -mips-compact-branches=always < %s | \
11; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R6,TAILCALL-32R6
12
13; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
14; RUN:     -O2 -mcpu=mips64r6 -mips-compact-branches=always < %s | \
15; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R6,TAILCALL-64R6
16
17; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
18; RUN:     -O2 -mcpu=mips32r6 -mips-compact-branches=never < %s | \
19; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,TAILCALL-32R2
20
21; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
22; RUN:     -O2 -mcpu=mips64r6 -mips-compact-branches=never < %s | \
23; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,TAILCALL-64R2
24
25; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
26; RUN:     -O2 -mattr=+micromips -mcpu=mips32r2 < %s | \
27; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,TAILCALL-MM
28
29; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
30; RUN:     -O2 -mattr=+micromips -mcpu=mips32r6 < %s | \
31; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,TAILCALL-MM
32
33; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
34; RUN:     -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,PIC-NOTAILCALL-R2
35
36; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
37; RUN:     -O0 < %s | FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,PIC-NOTAILCALL-R2
38
39; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
40; RUN:     -O0 -mcpu=mips32r6 -mips-compact-branches=always < %s | \
41; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R6,PIC-NOTAILCALL-R6
42
43; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
44; RUN:     -O0 -mcpu=mips64r6 -mips-compact-branches=always < %s | \
45; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R6,PIC-NOTAILCALL-R6
46
47; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
48; RUN:     -O0 -mcpu=mips32r6 -mips-compact-branches=never < %s | \
49; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-32,JALR-32R2,PIC-NOTAILCALL-R2
50
51; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
52; RUN:     -O0 -mcpu=mips64r6 -mips-compact-branches=never < %s | \
53; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-64,JALR-64R2,PIC-NOTAILCALL-R2
54
55; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
56; RUN:     -O0 -mattr=+micromips -mcpu=mips32r2 < %s | \
57; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,PIC-NOTAILCALL-MM
58
59; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic \
60; RUN:     -O0 -mattr=+micromips -mcpu=mips32r6 < %s | \
61; RUN:     FileCheck %s -check-prefixes=ALL,JALR-ALL,JALR-MM,PIC-NOTAILCALL-MM
62
63; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
64; RUN:     -O2 -mips-jalr-reloc=false < %s | \
65; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
66
67; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \
68; RUN:     -O2 < %s | \
69; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
70
71; RUN: llc -mtriple=mips-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
72; RUN:     -O0 -mips-jalr-reloc=false < %s | \
73; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
74
75; RUN: llc -mtriple=mips-linux-gnu -relocation-model=static -mips-tail-calls=1 \
76; RUN:     -O0 < %s | \
77; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
78
79; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic -mips-tail-calls=1 \
80; RUN:     -O2 -mips-jalr-reloc=false < %s | \
81; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
82
83; RUN: llc -mtriple=mips64-linux-gnu -mips-tail-calls=1 \
84; RUN:     -O2 -relocation-model=static < %s | \
85; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
86
87; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=pic \
88; RUN:     -O0 -mips-jalr-reloc=false < %s | \
89; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
90
91; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static \
92; RUN:     -O0 < %s | \
93; RUN:     FileCheck %s -check-prefixes=ALL,NORELOC
94
95define internal void @foo() noinline {
96entry:
97  ret void
98}
99
100define void @checkCall() {
101entry:
102; ALL-LABEL: checkCall:
103; ALL-NOT: MIPS_JALR
104  call void @foo()
105; JALR-32:       .reloc ([[TMPLABEL:\$.+]]), R_MIPS_JALR, foo
106; JALR-64:       .reloc [[TMPLABEL:\..+]], R_MIPS_JALR, foo
107; JALR-MM:       .reloc ([[TMPLABEL:\$.+]]), R_MICROMIPS_JALR, foo
108; NORELOC-NOT:   .reloc
109; JALR-ALL-NEXT: [[TMPLABEL]]:
110; JALR-32R2-NEXT: 	jalr	$25
111; JALR-64R2-NEXT: 	jalr	$25
112; JALR-32R6-NEXT: 	jalrc	$25
113; JALR-64R6-NEXT: 	jalrc	$25
114; JALR-MM-NEXT: 	jalr	$25
115; ALL-NOT: MIPS_JALR
116 ret void
117}
118
119define void @checkTailCall() {
120entry:
121; ALL-LABEL: checkTailCall:
122; ALL-NOT: MIPS_JALR
123  tail call void @foo()
124; JALR-32:       .reloc ([[TMPLABEL:\$.+]]), R_MIPS_JALR, foo
125; JALR-64:       .reloc [[TMPLABEL:\..+]], R_MIPS_JALR, foo
126; JALR-MM:       .reloc ([[TMPLABEL:\$.+]]), R_MICROMIPS_JALR, foo
127; JALR-ALL-NEXT: [[TMPLABEL]]:
128; NORELOC-NOT:   .reloc
129; TAILCALL-32R2-NEXT: 	jr	$25
130; TAILCALL-64R2-NEXT: 	jr	$25
131; TAILCALL-MM-NEXT: 	jrc	$25
132; TAILCALL-32R6-NEXT: 	jrc	$25
133; TAILCALL-64R6-NEXT: 	jrc	$25
134; PIC-NOTAILCALL-R2-NEXT: 	jalr	$25
135; PIC-NOTAILCALL-R6-NEXT: 	jalrc	$25
136; PIC-NOTAILCALL-MM-NEXT: 	jalr	$25
137; ALL-NOT: MIPS_JALR
138  ret void
139}
140
141; Check that we don't emit R_MIPS_JALR relocations against function pointers.
142; This resulted in run-time crashes until lld was modified to ignore
143; R_MIPS_JALR relocations against data symbols (commit 5bab291b7b).
144; However, the better approach is to not emit these relocations in the first
145; place so check that we no longer emit them.
146; Previously we were adding them for local dynamic TLS function pointers and
147; function pointers with internal linkage.
148
149@fnptr_internal = internal global void()* @checkFunctionPointerCall
150@fnptr_internal_const = internal constant void()* @checkFunctionPointerCall
151@fnptr_const = constant void()* @checkFunctionPointerCall
152@fnptr_global = global void()* @checkFunctionPointerCall
153
154define void @checkFunctionPointerCall() {
155entry:
156; ALL-LABEL: checkFunctionPointerCall:
157; ALL-NOT: MIPS_JALR
158  %func_internal = load void()*, void()** @fnptr_internal
159  call void %func_internal()
160  %func_internal_const = load void()*, void()** @fnptr_internal_const
161  call void %func_internal_const()
162  %func_const = load void()*, void()** @fnptr_const
163  call void %func_const()
164  %func_global = load void()*, void()** @fnptr_global
165  call void %func_global()
166  ret void
167}
168
169@tls_fnptr_gd = thread_local global void()* @checkTlsFunctionPointerCall
170@tls_fnptr_ld = thread_local(localdynamic) global void()* @checkTlsFunctionPointerCall
171@tls_fnptr_ie = thread_local(initialexec) global void()* @checkTlsFunctionPointerCall
172@tls_fnptr_le = thread_local(localexec) global void()* @checkTlsFunctionPointerCall
173
174define void @checkTlsFunctionPointerCall() {
175entry:
176; There should not be any *JALR relocations in this function other than the
177; calls to __tls_get_addr:
178; ALL-LABEL: checkTlsFunctionPointerCall:
179; ALL-NOT: MIPS_JALR
180; JALR-ALL: .reloc {{.+}}MIPS_JALR, __tls_get_addr
181; ALL-NOT: MIPS_JALR
182; JALR-ALL: .reloc {{.+}}MIPS_JALR, __tls_get_addr
183; NORELOC-NOT:   .reloc
184; ALL-NOT: _MIPS_JALR
185  %func_gd = load void()*, void()** @tls_fnptr_gd
186  call void %func_gd()
187  %func_ld = load void()*, void()** @tls_fnptr_ld
188  call void %func_ld()
189  %func_ie = load void()*, void()** @tls_fnptr_ie
190  call void %func_ie()
191  %func_le = load void()*, void()** @tls_fnptr_le
192  call void %func_le()
193  ret void
194}
195