1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening | FileCheck %s --check-prefix=X64-NOPIC
3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -code-model medium | FileCheck %s --check-prefix=X64-NOPIC-MCM
4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -relocation-model pic | FileCheck %s --check-prefix=X64-PIC
5;
6; FIXME: Add support for 32-bit.
7
8declare void @f()
9
10define i32 @test_calls_and_rets(i32 *%ptr) nounwind {
11; X64-NOPIC-LABEL: test_calls_and_rets:
12; X64-NOPIC:       # %bb.0: # %entry
13; X64-NOPIC-NEXT:    pushq %rbp
14; X64-NOPIC-NEXT:    pushq %r14
15; X64-NOPIC-NEXT:    pushq %rbx
16; X64-NOPIC-NEXT:    movq %rsp, %rax
17; X64-NOPIC-NEXT:    movq %rdi, %rbx
18; X64-NOPIC-NEXT:    movq $-1, %r14
19; X64-NOPIC-NEXT:    sarq $63, %rax
20; X64-NOPIC-NEXT:    shlq $47, %rax
21; X64-NOPIC-NEXT:    orq %rax, %rsp
22; X64-NOPIC-NEXT:    callq f
23; X64-NOPIC-NEXT:  .Lslh_ret_addr0:
24; X64-NOPIC-NEXT:    movq %rsp, %rax
25; X64-NOPIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
26; X64-NOPIC-NEXT:    sarq $63, %rax
27; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr0, %rcx
28; X64-NOPIC-NEXT:    cmovneq %r14, %rax
29; X64-NOPIC-NEXT:    movl (%rbx), %ebp
30; X64-NOPIC-NEXT:    shlq $47, %rax
31; X64-NOPIC-NEXT:    orq %rax, %rsp
32; X64-NOPIC-NEXT:    callq f
33; X64-NOPIC-NEXT:  .Lslh_ret_addr1:
34; X64-NOPIC-NEXT:    movq %rsp, %rcx
35; X64-NOPIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
36; X64-NOPIC-NEXT:    sarq $63, %rcx
37; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr1, %rax
38; X64-NOPIC-NEXT:    cmovneq %r14, %rcx
39; X64-NOPIC-NEXT:    addl (%rbx), %ebp
40; X64-NOPIC-NEXT:    orl %ecx, %ebp
41; X64-NOPIC-NEXT:    shlq $47, %rcx
42; X64-NOPIC-NEXT:    movl %ebp, %eax
43; X64-NOPIC-NEXT:    orq %rcx, %rsp
44; X64-NOPIC-NEXT:    popq %rbx
45; X64-NOPIC-NEXT:    popq %r14
46; X64-NOPIC-NEXT:    popq %rbp
47; X64-NOPIC-NEXT:    retq
48;
49; X64-NOPIC-MCM-LABEL: test_calls_and_rets:
50; X64-NOPIC-MCM:       # %bb.0: # %entry
51; X64-NOPIC-MCM-NEXT:    pushq %rbp
52; X64-NOPIC-MCM-NEXT:    pushq %r14
53; X64-NOPIC-MCM-NEXT:    pushq %rbx
54; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
55; X64-NOPIC-MCM-NEXT:    movq %rdi, %rbx
56; X64-NOPIC-MCM-NEXT:    movq $-1, %r14
57; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
58; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
59; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
60; X64-NOPIC-MCM-NEXT:    callq f
61; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr0:
62; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
63; X64-NOPIC-MCM-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
64; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
65; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr0(%rip), %rdx
66; X64-NOPIC-MCM-NEXT:    cmpq %rdx, %rcx
67; X64-NOPIC-MCM-NEXT:    cmovneq %r14, %rax
68; X64-NOPIC-MCM-NEXT:    movl (%rbx), %ebp
69; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
70; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
71; X64-NOPIC-MCM-NEXT:    callq f
72; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr1:
73; X64-NOPIC-MCM-NEXT:    movq %rsp, %rcx
74; X64-NOPIC-MCM-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
75; X64-NOPIC-MCM-NEXT:    sarq $63, %rcx
76; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr1(%rip), %rdx
77; X64-NOPIC-MCM-NEXT:    cmpq %rdx, %rax
78; X64-NOPIC-MCM-NEXT:    cmovneq %r14, %rcx
79; X64-NOPIC-MCM-NEXT:    addl (%rbx), %ebp
80; X64-NOPIC-MCM-NEXT:    orl %ecx, %ebp
81; X64-NOPIC-MCM-NEXT:    shlq $47, %rcx
82; X64-NOPIC-MCM-NEXT:    movl %ebp, %eax
83; X64-NOPIC-MCM-NEXT:    orq %rcx, %rsp
84; X64-NOPIC-MCM-NEXT:    popq %rbx
85; X64-NOPIC-MCM-NEXT:    popq %r14
86; X64-NOPIC-MCM-NEXT:    popq %rbp
87; X64-NOPIC-MCM-NEXT:    retq
88;
89; X64-PIC-LABEL: test_calls_and_rets:
90; X64-PIC:       # %bb.0: # %entry
91; X64-PIC-NEXT:    pushq %rbp
92; X64-PIC-NEXT:    pushq %r14
93; X64-PIC-NEXT:    pushq %rbx
94; X64-PIC-NEXT:    movq %rsp, %rax
95; X64-PIC-NEXT:    movq %rdi, %rbx
96; X64-PIC-NEXT:    movq $-1, %r14
97; X64-PIC-NEXT:    sarq $63, %rax
98; X64-PIC-NEXT:    shlq $47, %rax
99; X64-PIC-NEXT:    orq %rax, %rsp
100; X64-PIC-NEXT:    callq f@PLT
101; X64-PIC-NEXT:  .Lslh_ret_addr0:
102; X64-PIC-NEXT:    movq %rsp, %rax
103; X64-PIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx
104; X64-PIC-NEXT:    sarq $63, %rax
105; X64-PIC-NEXT:    leaq .Lslh_ret_addr0(%rip), %rdx
106; X64-PIC-NEXT:    cmpq %rdx, %rcx
107; X64-PIC-NEXT:    cmovneq %r14, %rax
108; X64-PIC-NEXT:    movl (%rbx), %ebp
109; X64-PIC-NEXT:    shlq $47, %rax
110; X64-PIC-NEXT:    orq %rax, %rsp
111; X64-PIC-NEXT:    callq f@PLT
112; X64-PIC-NEXT:  .Lslh_ret_addr1:
113; X64-PIC-NEXT:    movq %rsp, %rcx
114; X64-PIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rax
115; X64-PIC-NEXT:    sarq $63, %rcx
116; X64-PIC-NEXT:    leaq .Lslh_ret_addr1(%rip), %rdx
117; X64-PIC-NEXT:    cmpq %rdx, %rax
118; X64-PIC-NEXT:    cmovneq %r14, %rcx
119; X64-PIC-NEXT:    addl (%rbx), %ebp
120; X64-PIC-NEXT:    orl %ecx, %ebp
121; X64-PIC-NEXT:    shlq $47, %rcx
122; X64-PIC-NEXT:    movl %ebp, %eax
123; X64-PIC-NEXT:    orq %rcx, %rsp
124; X64-PIC-NEXT:    popq %rbx
125; X64-PIC-NEXT:    popq %r14
126; X64-PIC-NEXT:    popq %rbp
127; X64-PIC-NEXT:    retq
128entry:
129  call void @f()
130  %x = load i32, i32* %ptr
131  call void @f()
132  %y = load i32, i32* %ptr
133  %z = add i32 %x, %y
134  ret i32 %z
135}
136
137define i32 @test_calls_and_rets_noredzone(i32 *%ptr) nounwind noredzone {
138; X64-NOPIC-LABEL: test_calls_and_rets_noredzone:
139; X64-NOPIC:       # %bb.0: # %entry
140; X64-NOPIC-NEXT:    pushq %rbp
141; X64-NOPIC-NEXT:    pushq %r15
142; X64-NOPIC-NEXT:    pushq %r14
143; X64-NOPIC-NEXT:    pushq %rbx
144; X64-NOPIC-NEXT:    pushq %rax
145; X64-NOPIC-NEXT:    movq %rsp, %rax
146; X64-NOPIC-NEXT:    movq %rdi, %rbx
147; X64-NOPIC-NEXT:    movq $-1, %r14
148; X64-NOPIC-NEXT:    sarq $63, %rax
149; X64-NOPIC-NEXT:    shlq $47, %rax
150; X64-NOPIC-NEXT:    orq %rax, %rsp
151; X64-NOPIC-NEXT:    movq $.Lslh_ret_addr2, %rbp
152; X64-NOPIC-NEXT:    callq f
153; X64-NOPIC-NEXT:  .Lslh_ret_addr2:
154; X64-NOPIC-NEXT:    movq %rsp, %rax
155; X64-NOPIC-NEXT:    sarq $63, %rax
156; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr2, %rbp
157; X64-NOPIC-NEXT:    cmovneq %r14, %rax
158; X64-NOPIC-NEXT:    movl (%rbx), %ebp
159; X64-NOPIC-NEXT:    shlq $47, %rax
160; X64-NOPIC-NEXT:    orq %rax, %rsp
161; X64-NOPIC-NEXT:    movq $.Lslh_ret_addr3, %r15
162; X64-NOPIC-NEXT:    callq f
163; X64-NOPIC-NEXT:  .Lslh_ret_addr3:
164; X64-NOPIC-NEXT:    movq %rsp, %rcx
165; X64-NOPIC-NEXT:    sarq $63, %rcx
166; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr3, %r15
167; X64-NOPIC-NEXT:    cmovneq %r14, %rcx
168; X64-NOPIC-NEXT:    addl (%rbx), %ebp
169; X64-NOPIC-NEXT:    orl %ecx, %ebp
170; X64-NOPIC-NEXT:    shlq $47, %rcx
171; X64-NOPIC-NEXT:    movl %ebp, %eax
172; X64-NOPIC-NEXT:    orq %rcx, %rsp
173; X64-NOPIC-NEXT:    addq $8, %rsp
174; X64-NOPIC-NEXT:    popq %rbx
175; X64-NOPIC-NEXT:    popq %r14
176; X64-NOPIC-NEXT:    popq %r15
177; X64-NOPIC-NEXT:    popq %rbp
178; X64-NOPIC-NEXT:    retq
179;
180; X64-NOPIC-MCM-LABEL: test_calls_and_rets_noredzone:
181; X64-NOPIC-MCM:       # %bb.0: # %entry
182; X64-NOPIC-MCM-NEXT:    pushq %rbp
183; X64-NOPIC-MCM-NEXT:    pushq %r15
184; X64-NOPIC-MCM-NEXT:    pushq %r14
185; X64-NOPIC-MCM-NEXT:    pushq %rbx
186; X64-NOPIC-MCM-NEXT:    pushq %rax
187; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
188; X64-NOPIC-MCM-NEXT:    movq %rdi, %rbx
189; X64-NOPIC-MCM-NEXT:    movq $-1, %r14
190; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
191; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
192; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
193; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr2(%rip), %rbp
194; X64-NOPIC-MCM-NEXT:    callq f
195; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr2:
196; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
197; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
198; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr2(%rip), %rcx
199; X64-NOPIC-MCM-NEXT:    cmpq %rcx, %rbp
200; X64-NOPIC-MCM-NEXT:    cmovneq %r14, %rax
201; X64-NOPIC-MCM-NEXT:    movl (%rbx), %ebp
202; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
203; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
204; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr3(%rip), %r15
205; X64-NOPIC-MCM-NEXT:    callq f
206; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr3:
207; X64-NOPIC-MCM-NEXT:    movq %rsp, %rcx
208; X64-NOPIC-MCM-NEXT:    sarq $63, %rcx
209; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr3(%rip), %rax
210; X64-NOPIC-MCM-NEXT:    cmpq %rax, %r15
211; X64-NOPIC-MCM-NEXT:    cmovneq %r14, %rcx
212; X64-NOPIC-MCM-NEXT:    addl (%rbx), %ebp
213; X64-NOPIC-MCM-NEXT:    orl %ecx, %ebp
214; X64-NOPIC-MCM-NEXT:    shlq $47, %rcx
215; X64-NOPIC-MCM-NEXT:    movl %ebp, %eax
216; X64-NOPIC-MCM-NEXT:    orq %rcx, %rsp
217; X64-NOPIC-MCM-NEXT:    addq $8, %rsp
218; X64-NOPIC-MCM-NEXT:    popq %rbx
219; X64-NOPIC-MCM-NEXT:    popq %r14
220; X64-NOPIC-MCM-NEXT:    popq %r15
221; X64-NOPIC-MCM-NEXT:    popq %rbp
222; X64-NOPIC-MCM-NEXT:    retq
223;
224; X64-PIC-LABEL: test_calls_and_rets_noredzone:
225; X64-PIC:       # %bb.0: # %entry
226; X64-PIC-NEXT:    pushq %rbp
227; X64-PIC-NEXT:    pushq %r15
228; X64-PIC-NEXT:    pushq %r14
229; X64-PIC-NEXT:    pushq %rbx
230; X64-PIC-NEXT:    pushq %rax
231; X64-PIC-NEXT:    movq %rsp, %rax
232; X64-PIC-NEXT:    movq %rdi, %rbx
233; X64-PIC-NEXT:    movq $-1, %r14
234; X64-PIC-NEXT:    sarq $63, %rax
235; X64-PIC-NEXT:    shlq $47, %rax
236; X64-PIC-NEXT:    orq %rax, %rsp
237; X64-PIC-NEXT:    leaq .Lslh_ret_addr2(%rip), %rbp
238; X64-PIC-NEXT:    callq f@PLT
239; X64-PIC-NEXT:  .Lslh_ret_addr2:
240; X64-PIC-NEXT:    movq %rsp, %rax
241; X64-PIC-NEXT:    sarq $63, %rax
242; X64-PIC-NEXT:    leaq .Lslh_ret_addr2(%rip), %rcx
243; X64-PIC-NEXT:    cmpq %rcx, %rbp
244; X64-PIC-NEXT:    cmovneq %r14, %rax
245; X64-PIC-NEXT:    movl (%rbx), %ebp
246; X64-PIC-NEXT:    shlq $47, %rax
247; X64-PIC-NEXT:    orq %rax, %rsp
248; X64-PIC-NEXT:    leaq .Lslh_ret_addr3(%rip), %r15
249; X64-PIC-NEXT:    callq f@PLT
250; X64-PIC-NEXT:  .Lslh_ret_addr3:
251; X64-PIC-NEXT:    movq %rsp, %rcx
252; X64-PIC-NEXT:    sarq $63, %rcx
253; X64-PIC-NEXT:    leaq .Lslh_ret_addr3(%rip), %rax
254; X64-PIC-NEXT:    cmpq %rax, %r15
255; X64-PIC-NEXT:    cmovneq %r14, %rcx
256; X64-PIC-NEXT:    addl (%rbx), %ebp
257; X64-PIC-NEXT:    orl %ecx, %ebp
258; X64-PIC-NEXT:    shlq $47, %rcx
259; X64-PIC-NEXT:    movl %ebp, %eax
260; X64-PIC-NEXT:    orq %rcx, %rsp
261; X64-PIC-NEXT:    addq $8, %rsp
262; X64-PIC-NEXT:    popq %rbx
263; X64-PIC-NEXT:    popq %r14
264; X64-PIC-NEXT:    popq %r15
265; X64-PIC-NEXT:    popq %rbp
266; X64-PIC-NEXT:    retq
267entry:
268  call void @f()
269  %x = load i32, i32* %ptr
270  call void @f()
271  %y = load i32, i32* %ptr
272  %z = add i32 %x, %y
273  ret i32 %z
274}
275
276declare i32 @setjmp(i8* %env) returns_twice
277declare i32 @sigsetjmp(i8* %env, i32 %savemask) returns_twice
278declare i32 @__sigsetjmp(i8* %foo, i8* %bar, i32 %baz) returns_twice
279
280define i32 @test_call_setjmp(i32 *%ptr) nounwind {
281; X64-NOPIC-LABEL: test_call_setjmp:
282; X64-NOPIC:       # %bb.0: # %entry
283; X64-NOPIC-NEXT:    pushq %rbp
284; X64-NOPIC-NEXT:    pushq %r15
285; X64-NOPIC-NEXT:    pushq %r14
286; X64-NOPIC-NEXT:    pushq %r13
287; X64-NOPIC-NEXT:    pushq %r12
288; X64-NOPIC-NEXT:    pushq %rbx
289; X64-NOPIC-NEXT:    subq $24, %rsp
290; X64-NOPIC-NEXT:    movq %rsp, %rax
291; X64-NOPIC-NEXT:    movq %rdi, %rbx
292; X64-NOPIC-NEXT:    movq $-1, %r15
293; X64-NOPIC-NEXT:    sarq $63, %rax
294; X64-NOPIC-NEXT:    leaq {{[0-9]+}}(%rsp), %r14
295; X64-NOPIC-NEXT:    shlq $47, %rax
296; X64-NOPIC-NEXT:    movq %r14, %rdi
297; X64-NOPIC-NEXT:    orq %rax, %rsp
298; X64-NOPIC-NEXT:    movq $.Lslh_ret_addr4, %rbp
299; X64-NOPIC-NEXT:    callq setjmp
300; X64-NOPIC-NEXT:  .Lslh_ret_addr4:
301; X64-NOPIC-NEXT:    movq %rsp, %rax
302; X64-NOPIC-NEXT:    sarq $63, %rax
303; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr4, %rbp
304; X64-NOPIC-NEXT:    cmovneq %r15, %rax
305; X64-NOPIC-NEXT:    movl (%rbx), %ebp
306; X64-NOPIC-NEXT:    movl $42, %r12d
307; X64-NOPIC-NEXT:    shlq $47, %rax
308; X64-NOPIC-NEXT:    movq %r14, %rdi
309; X64-NOPIC-NEXT:    movl %r12d, %esi
310; X64-NOPIC-NEXT:    orq %rax, %rsp
311; X64-NOPIC-NEXT:    movq $.Lslh_ret_addr5, %r13
312; X64-NOPIC-NEXT:    callq sigsetjmp
313; X64-NOPIC-NEXT:  .Lslh_ret_addr5:
314; X64-NOPIC-NEXT:    movq %rsp, %rax
315; X64-NOPIC-NEXT:    sarq $63, %rax
316; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr5, %r13
317; X64-NOPIC-NEXT:    cmovneq %r15, %rax
318; X64-NOPIC-NEXT:    addl (%rbx), %ebp
319; X64-NOPIC-NEXT:    shlq $47, %rax
320; X64-NOPIC-NEXT:    movq %r14, %rdi
321; X64-NOPIC-NEXT:    movq %r14, %rsi
322; X64-NOPIC-NEXT:    movl %r12d, %edx
323; X64-NOPIC-NEXT:    orq %rax, %rsp
324; X64-NOPIC-NEXT:    movq $.Lslh_ret_addr6, %r14
325; X64-NOPIC-NEXT:    callq __sigsetjmp
326; X64-NOPIC-NEXT:  .Lslh_ret_addr6:
327; X64-NOPIC-NEXT:    movq %rsp, %rax
328; X64-NOPIC-NEXT:    sarq $63, %rax
329; X64-NOPIC-NEXT:    cmpq $.Lslh_ret_addr6, %r14
330; X64-NOPIC-NEXT:    movq %rax, %rcx
331; X64-NOPIC-NEXT:    cmovneq %r15, %rcx
332; X64-NOPIC-NEXT:    addl (%rbx), %ebp
333; X64-NOPIC-NEXT:    movl %ebp, %eax
334; X64-NOPIC-NEXT:    orl %ecx, %eax
335; X64-NOPIC-NEXT:    shlq $47, %rcx
336; X64-NOPIC-NEXT:    orq %rcx, %rsp
337; X64-NOPIC-NEXT:    addq $24, %rsp
338; X64-NOPIC-NEXT:    popq %rbx
339; X64-NOPIC-NEXT:    popq %r12
340; X64-NOPIC-NEXT:    popq %r13
341; X64-NOPIC-NEXT:    popq %r14
342; X64-NOPIC-NEXT:    popq %r15
343; X64-NOPIC-NEXT:    popq %rbp
344; X64-NOPIC-NEXT:    retq
345;
346; X64-NOPIC-MCM-LABEL: test_call_setjmp:
347; X64-NOPIC-MCM:       # %bb.0: # %entry
348; X64-NOPIC-MCM-NEXT:    pushq %rbp
349; X64-NOPIC-MCM-NEXT:    pushq %r15
350; X64-NOPIC-MCM-NEXT:    pushq %r14
351; X64-NOPIC-MCM-NEXT:    pushq %r13
352; X64-NOPIC-MCM-NEXT:    pushq %r12
353; X64-NOPIC-MCM-NEXT:    pushq %rbx
354; X64-NOPIC-MCM-NEXT:    subq $24, %rsp
355; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
356; X64-NOPIC-MCM-NEXT:    movq %rdi, %rbx
357; X64-NOPIC-MCM-NEXT:    movq $-1, %r15
358; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
359; X64-NOPIC-MCM-NEXT:    leaq {{[0-9]+}}(%rsp), %r14
360; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
361; X64-NOPIC-MCM-NEXT:    movq %r14, %rdi
362; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
363; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr4(%rip), %rbp
364; X64-NOPIC-MCM-NEXT:    callq setjmp
365; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr4:
366; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
367; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
368; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr4(%rip), %rcx
369; X64-NOPIC-MCM-NEXT:    cmpq %rcx, %rbp
370; X64-NOPIC-MCM-NEXT:    cmovneq %r15, %rax
371; X64-NOPIC-MCM-NEXT:    movl (%rbx), %ebp
372; X64-NOPIC-MCM-NEXT:    movl $42, %r12d
373; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
374; X64-NOPIC-MCM-NEXT:    movq %r14, %rdi
375; X64-NOPIC-MCM-NEXT:    movl %r12d, %esi
376; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
377; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr5(%rip), %r13
378; X64-NOPIC-MCM-NEXT:    callq sigsetjmp
379; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr5:
380; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
381; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
382; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr5(%rip), %rcx
383; X64-NOPIC-MCM-NEXT:    cmpq %rcx, %r13
384; X64-NOPIC-MCM-NEXT:    cmovneq %r15, %rax
385; X64-NOPIC-MCM-NEXT:    addl (%rbx), %ebp
386; X64-NOPIC-MCM-NEXT:    shlq $47, %rax
387; X64-NOPIC-MCM-NEXT:    movq %r14, %rdi
388; X64-NOPIC-MCM-NEXT:    movq %r14, %rsi
389; X64-NOPIC-MCM-NEXT:    movl %r12d, %edx
390; X64-NOPIC-MCM-NEXT:    orq %rax, %rsp
391; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr6(%rip), %r14
392; X64-NOPIC-MCM-NEXT:    callq __sigsetjmp
393; X64-NOPIC-MCM-NEXT:  .Lslh_ret_addr6:
394; X64-NOPIC-MCM-NEXT:    movq %rsp, %rax
395; X64-NOPIC-MCM-NEXT:    sarq $63, %rax
396; X64-NOPIC-MCM-NEXT:    leaq .Lslh_ret_addr6(%rip), %rcx
397; X64-NOPIC-MCM-NEXT:    cmpq %rcx, %r14
398; X64-NOPIC-MCM-NEXT:    movq %rax, %rcx
399; X64-NOPIC-MCM-NEXT:    cmovneq %r15, %rcx
400; X64-NOPIC-MCM-NEXT:    addl (%rbx), %ebp
401; X64-NOPIC-MCM-NEXT:    movl %ebp, %eax
402; X64-NOPIC-MCM-NEXT:    orl %ecx, %eax
403; X64-NOPIC-MCM-NEXT:    shlq $47, %rcx
404; X64-NOPIC-MCM-NEXT:    orq %rcx, %rsp
405; X64-NOPIC-MCM-NEXT:    addq $24, %rsp
406; X64-NOPIC-MCM-NEXT:    popq %rbx
407; X64-NOPIC-MCM-NEXT:    popq %r12
408; X64-NOPIC-MCM-NEXT:    popq %r13
409; X64-NOPIC-MCM-NEXT:    popq %r14
410; X64-NOPIC-MCM-NEXT:    popq %r15
411; X64-NOPIC-MCM-NEXT:    popq %rbp
412; X64-NOPIC-MCM-NEXT:    retq
413;
414; X64-PIC-LABEL: test_call_setjmp:
415; X64-PIC:       # %bb.0: # %entry
416; X64-PIC-NEXT:    pushq %rbp
417; X64-PIC-NEXT:    pushq %r15
418; X64-PIC-NEXT:    pushq %r14
419; X64-PIC-NEXT:    pushq %r13
420; X64-PIC-NEXT:    pushq %r12
421; X64-PIC-NEXT:    pushq %rbx
422; X64-PIC-NEXT:    subq $24, %rsp
423; X64-PIC-NEXT:    movq %rsp, %rax
424; X64-PIC-NEXT:    movq %rdi, %rbx
425; X64-PIC-NEXT:    movq $-1, %r15
426; X64-PIC-NEXT:    sarq $63, %rax
427; X64-PIC-NEXT:    leaq {{[0-9]+}}(%rsp), %r14
428; X64-PIC-NEXT:    shlq $47, %rax
429; X64-PIC-NEXT:    movq %r14, %rdi
430; X64-PIC-NEXT:    orq %rax, %rsp
431; X64-PIC-NEXT:    leaq .Lslh_ret_addr4(%rip), %rbp
432; X64-PIC-NEXT:    callq setjmp@PLT
433; X64-PIC-NEXT:  .Lslh_ret_addr4:
434; X64-PIC-NEXT:    movq %rsp, %rax
435; X64-PIC-NEXT:    sarq $63, %rax
436; X64-PIC-NEXT:    leaq .Lslh_ret_addr4(%rip), %rcx
437; X64-PIC-NEXT:    cmpq %rcx, %rbp
438; X64-PIC-NEXT:    cmovneq %r15, %rax
439; X64-PIC-NEXT:    movl (%rbx), %ebp
440; X64-PIC-NEXT:    movl $42, %r12d
441; X64-PIC-NEXT:    shlq $47, %rax
442; X64-PIC-NEXT:    movq %r14, %rdi
443; X64-PIC-NEXT:    movl %r12d, %esi
444; X64-PIC-NEXT:    orq %rax, %rsp
445; X64-PIC-NEXT:    leaq .Lslh_ret_addr5(%rip), %r13
446; X64-PIC-NEXT:    callq sigsetjmp@PLT
447; X64-PIC-NEXT:  .Lslh_ret_addr5:
448; X64-PIC-NEXT:    movq %rsp, %rax
449; X64-PIC-NEXT:    sarq $63, %rax
450; X64-PIC-NEXT:    leaq .Lslh_ret_addr5(%rip), %rcx
451; X64-PIC-NEXT:    cmpq %rcx, %r13
452; X64-PIC-NEXT:    cmovneq %r15, %rax
453; X64-PIC-NEXT:    addl (%rbx), %ebp
454; X64-PIC-NEXT:    shlq $47, %rax
455; X64-PIC-NEXT:    movq %r14, %rdi
456; X64-PIC-NEXT:    movq %r14, %rsi
457; X64-PIC-NEXT:    movl %r12d, %edx
458; X64-PIC-NEXT:    orq %rax, %rsp
459; X64-PIC-NEXT:    leaq .Lslh_ret_addr6(%rip), %r14
460; X64-PIC-NEXT:    callq __sigsetjmp@PLT
461; X64-PIC-NEXT:  .Lslh_ret_addr6:
462; X64-PIC-NEXT:    movq %rsp, %rax
463; X64-PIC-NEXT:    sarq $63, %rax
464; X64-PIC-NEXT:    leaq .Lslh_ret_addr6(%rip), %rcx
465; X64-PIC-NEXT:    cmpq %rcx, %r14
466; X64-PIC-NEXT:    movq %rax, %rcx
467; X64-PIC-NEXT:    cmovneq %r15, %rcx
468; X64-PIC-NEXT:    addl (%rbx), %ebp
469; X64-PIC-NEXT:    movl %ebp, %eax
470; X64-PIC-NEXT:    orl %ecx, %eax
471; X64-PIC-NEXT:    shlq $47, %rcx
472; X64-PIC-NEXT:    orq %rcx, %rsp
473; X64-PIC-NEXT:    addq $24, %rsp
474; X64-PIC-NEXT:    popq %rbx
475; X64-PIC-NEXT:    popq %r12
476; X64-PIC-NEXT:    popq %r13
477; X64-PIC-NEXT:    popq %r14
478; X64-PIC-NEXT:    popq %r15
479; X64-PIC-NEXT:    popq %rbp
480; X64-PIC-NEXT:    retq
481entry:
482  %env = alloca i8, i32 16
483  ; Call a normal setjmp function.
484  call i32 @setjmp(i8* %env)
485  %x = load i32, i32* %ptr
486  ; Call something like sigsetjmp.
487  call i32 @sigsetjmp(i8* %env, i32 42)
488  %y = load i32, i32* %ptr
489  ; Call something that might be an implementation detail expanded out of a
490  ; macro that has a weird signature but still gets annotated as returning
491  ; twice.
492  call i32 @__sigsetjmp(i8* %env, i8* %env, i32 42)
493  %z = load i32, i32* %ptr
494  %s1 = add i32 %x, %y
495  %s2 = add i32 %s1, %z
496  ret i32 %s2
497}
498