xref: /llvm-project/llvm/test/CodeGen/X86/speculative-load-hardening-indirect.ll (revision e3cf80c5c1fe55efd8216575ccadea0ab087e79c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2
3; Verify the call site info. If the call site info is not
4; in the valid state, an assert should be triggered.
5; RUN: llc < %s -debug-entry-values -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -stop-after=machineverifier
6
7; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -data-sections | FileCheck %s --check-prefix=X64
8; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39451.
9; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -relocation-model pic -data-sections -verify-machineinstrs=0 | FileCheck %s --check-prefix=X64-PIC
10; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -data-sections -mattr=+retpoline | FileCheck %s --check-prefix=X64-RETPOLINE
11;
12; FIXME: Add support for 32-bit.
13
14@global_fnptr = external global ptr
15
16@global_blockaddrs = dso_local constant [4 x ptr] [
17  ptr blockaddress(@test_indirectbr_global, %bb0),
18  ptr blockaddress(@test_indirectbr_global, %bb1),
19  ptr blockaddress(@test_indirectbr_global, %bb2),
20  ptr blockaddress(@test_indirectbr_global, %bb3)
21]
22
23define dso_local i32 @test_indirect_call(ptr %ptr) nounwind {
24; X64-LABEL: test_indirect_call:
25; X64:       # %bb.0: # %entry
26; X64-NEXT:    pushq %rbx
27; X64-NEXT:    movq %rsp, %rax
28; X64-NEXT:    movq $-1, %rbx
29; X64-NEXT:    sarq $63, %rax
30; X64-NEXT:    movq (%rdi), %rcx
31; X64-NEXT:    orq %rax, %rcx
32; X64-NEXT:    shlq $47, %rax
33; X64-NEXT:    orq %rax, %rsp
34; X64-NEXT:    callq *%rcx
35; X64-NEXT:  .Lslh_ret_addr0:
36; X64-NEXT:    movq %rsp, %rcx
37; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
38; X64-NEXT:    sarq $63, %rcx
39; X64-NEXT:    cmpq $.Lslh_ret_addr0, %rdx
40; X64-NEXT:    cmovneq %rbx, %rcx
41; X64-NEXT:    shlq $47, %rcx
42; X64-NEXT:    orq %rcx, %rsp
43; X64-NEXT:    popq %rbx
44; X64-NEXT:    retq
45;
46; X64-PIC-LABEL: test_indirect_call:
47; X64-PIC:       # %bb.0: # %entry
48; X64-PIC-NEXT:    pushq %rbx
49; X64-PIC-NEXT:    movq %rsp, %rax
50; X64-PIC-NEXT:    movq $-1, %rbx
51; X64-PIC-NEXT:    sarq $63, %rax
52; X64-PIC-NEXT:    movq (%rdi), %rcx
53; X64-PIC-NEXT:    orq %rax, %rcx
54; X64-PIC-NEXT:    shlq $47, %rax
55; X64-PIC-NEXT:    orq %rax, %rsp
56; X64-PIC-NEXT:    callq *%rcx
57; X64-PIC-NEXT:  .Lslh_ret_addr0:
58; X64-PIC-NEXT:    movq %rsp, %rcx
59; X64-PIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
60; X64-PIC-NEXT:    sarq $63, %rcx
61; X64-PIC-NEXT:    leaq .Lslh_ret_addr0(%rip), %rsi
62; X64-PIC-NEXT:    cmpq %rsi, %rdx
63; X64-PIC-NEXT:    cmovneq %rbx, %rcx
64; X64-PIC-NEXT:    shlq $47, %rcx
65; X64-PIC-NEXT:    orq %rcx, %rsp
66; X64-PIC-NEXT:    popq %rbx
67; X64-PIC-NEXT:    retq
68;
69; X64-RETPOLINE-LABEL: test_indirect_call:
70; X64-RETPOLINE:       # %bb.0: # %entry
71; X64-RETPOLINE-NEXT:    pushq %rbx
72; X64-RETPOLINE-NEXT:    movq %rsp, %rax
73; X64-RETPOLINE-NEXT:    movq $-1, %rbx
74; X64-RETPOLINE-NEXT:    sarq $63, %rax
75; X64-RETPOLINE-NEXT:    movq (%rdi), %r11
76; X64-RETPOLINE-NEXT:    orq %rax, %r11
77; X64-RETPOLINE-NEXT:    shlq $47, %rax
78; X64-RETPOLINE-NEXT:    orq %rax, %rsp
79; X64-RETPOLINE-NEXT:    callq __llvm_retpoline_r11
80; X64-RETPOLINE-NEXT:  .Lslh_ret_addr0:
81; X64-RETPOLINE-NEXT:    movq %rsp, %rcx
82; X64-RETPOLINE-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
83; X64-RETPOLINE-NEXT:    sarq $63, %rcx
84; X64-RETPOLINE-NEXT:    cmpq $.Lslh_ret_addr0, %rdx
85; X64-RETPOLINE-NEXT:    cmovneq %rbx, %rcx
86; X64-RETPOLINE-NEXT:    shlq $47, %rcx
87; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
88; X64-RETPOLINE-NEXT:    popq %rbx
89; X64-RETPOLINE-NEXT:    retq
90entry:
91  %fp = load ptr, ptr %ptr
92  %v = call i32 %fp()
93  ret i32 %v
94}
95
96define dso_local i32 @test_indirect_tail_call(ptr %ptr) nounwind {
97; X64-LABEL: test_indirect_tail_call:
98; X64:       # %bb.0: # %entry
99; X64-NEXT:    movq %rsp, %rax
100; X64-NEXT:    movq $-1, %rcx
101; X64-NEXT:    sarq $63, %rax
102; X64-NEXT:    movq (%rdi), %rcx
103; X64-NEXT:    orq %rax, %rcx
104; X64-NEXT:    shlq $47, %rax
105; X64-NEXT:    orq %rax, %rsp
106; X64-NEXT:    jmpq *%rcx # TAILCALL
107;
108; X64-PIC-LABEL: test_indirect_tail_call:
109; X64-PIC:       # %bb.0: # %entry
110; X64-PIC-NEXT:    movq %rsp, %rax
111; X64-PIC-NEXT:    movq $-1, %rcx
112; X64-PIC-NEXT:    sarq $63, %rax
113; X64-PIC-NEXT:    movq (%rdi), %rcx
114; X64-PIC-NEXT:    orq %rax, %rcx
115; X64-PIC-NEXT:    shlq $47, %rax
116; X64-PIC-NEXT:    orq %rax, %rsp
117; X64-PIC-NEXT:    jmpq *%rcx # TAILCALL
118;
119; X64-RETPOLINE-LABEL: test_indirect_tail_call:
120; X64-RETPOLINE:       # %bb.0: # %entry
121; X64-RETPOLINE-NEXT:    movq %rsp, %rax
122; X64-RETPOLINE-NEXT:    movq $-1, %rcx
123; X64-RETPOLINE-NEXT:    sarq $63, %rax
124; X64-RETPOLINE-NEXT:    movq (%rdi), %r11
125; X64-RETPOLINE-NEXT:    orq %rax, %r11
126; X64-RETPOLINE-NEXT:    shlq $47, %rax
127; X64-RETPOLINE-NEXT:    orq %rax, %rsp
128; X64-RETPOLINE-NEXT:    jmp __llvm_retpoline_r11 # TAILCALL
129entry:
130  %fp = load ptr, ptr %ptr
131  %v = tail call i32 %fp()
132  ret i32 %v
133}
134
135define dso_local i32 @test_indirect_call_global() nounwind {
136; X64-LABEL: test_indirect_call_global:
137; X64:       # %bb.0: # %entry
138; X64-NEXT:    pushq %rbx
139; X64-NEXT:    movq %rsp, %rax
140; X64-NEXT:    movq $-1, %rbx
141; X64-NEXT:    sarq $63, %rax
142; X64-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
143; X64-NEXT:    movq (%rcx), %rcx
144; X64-NEXT:    orq %rax, %rcx
145; X64-NEXT:    shlq $47, %rax
146; X64-NEXT:    orq %rax, %rsp
147; X64-NEXT:    callq *%rcx
148; X64-NEXT:  .Lslh_ret_addr1:
149; X64-NEXT:    movq %rsp, %rcx
150; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
151; X64-NEXT:    sarq $63, %rcx
152; X64-NEXT:    cmpq $.Lslh_ret_addr1, %rdx
153; X64-NEXT:    cmovneq %rbx, %rcx
154; X64-NEXT:    shlq $47, %rcx
155; X64-NEXT:    orq %rcx, %rsp
156; X64-NEXT:    popq %rbx
157; X64-NEXT:    retq
158;
159; X64-PIC-LABEL: test_indirect_call_global:
160; X64-PIC:       # %bb.0: # %entry
161; X64-PIC-NEXT:    pushq %rbx
162; X64-PIC-NEXT:    movq %rsp, %rax
163; X64-PIC-NEXT:    movq $-1, %rbx
164; X64-PIC-NEXT:    sarq $63, %rax
165; X64-PIC-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
166; X64-PIC-NEXT:    movq (%rcx), %rcx
167; X64-PIC-NEXT:    orq %rax, %rcx
168; X64-PIC-NEXT:    shlq $47, %rax
169; X64-PIC-NEXT:    orq %rax, %rsp
170; X64-PIC-NEXT:    callq *%rcx
171; X64-PIC-NEXT:  .Lslh_ret_addr1:
172; X64-PIC-NEXT:    movq %rsp, %rcx
173; X64-PIC-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
174; X64-PIC-NEXT:    sarq $63, %rcx
175; X64-PIC-NEXT:    leaq .Lslh_ret_addr1(%rip), %rsi
176; X64-PIC-NEXT:    cmpq %rsi, %rdx
177; X64-PIC-NEXT:    cmovneq %rbx, %rcx
178; X64-PIC-NEXT:    shlq $47, %rcx
179; X64-PIC-NEXT:    orq %rcx, %rsp
180; X64-PIC-NEXT:    popq %rbx
181; X64-PIC-NEXT:    retq
182;
183; X64-RETPOLINE-LABEL: test_indirect_call_global:
184; X64-RETPOLINE:       # %bb.0: # %entry
185; X64-RETPOLINE-NEXT:    pushq %rbx
186; X64-RETPOLINE-NEXT:    movq %rsp, %rax
187; X64-RETPOLINE-NEXT:    movq $-1, %rbx
188; X64-RETPOLINE-NEXT:    sarq $63, %rax
189; X64-RETPOLINE-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
190; X64-RETPOLINE-NEXT:    movq (%rcx), %r11
191; X64-RETPOLINE-NEXT:    orq %rax, %r11
192; X64-RETPOLINE-NEXT:    shlq $47, %rax
193; X64-RETPOLINE-NEXT:    orq %rax, %rsp
194; X64-RETPOLINE-NEXT:    callq __llvm_retpoline_r11
195; X64-RETPOLINE-NEXT:  .Lslh_ret_addr1:
196; X64-RETPOLINE-NEXT:    movq %rsp, %rcx
197; X64-RETPOLINE-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx
198; X64-RETPOLINE-NEXT:    sarq $63, %rcx
199; X64-RETPOLINE-NEXT:    cmpq $.Lslh_ret_addr1, %rdx
200; X64-RETPOLINE-NEXT:    cmovneq %rbx, %rcx
201; X64-RETPOLINE-NEXT:    shlq $47, %rcx
202; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
203; X64-RETPOLINE-NEXT:    popq %rbx
204; X64-RETPOLINE-NEXT:    retq
205entry:
206  %fp = load ptr, ptr @global_fnptr
207  %v = call i32 %fp()
208  ret i32 %v
209}
210
211define dso_local i32 @test_indirect_tail_call_global() nounwind {
212; X64-LABEL: test_indirect_tail_call_global:
213; X64:       # %bb.0: # %entry
214; X64-NEXT:    movq %rsp, %rax
215; X64-NEXT:    movq $-1, %rcx
216; X64-NEXT:    sarq $63, %rax
217; X64-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
218; X64-NEXT:    movq (%rcx), %rcx
219; X64-NEXT:    orq %rax, %rcx
220; X64-NEXT:    shlq $47, %rax
221; X64-NEXT:    orq %rax, %rsp
222; X64-NEXT:    jmpq *%rcx # TAILCALL
223;
224; X64-PIC-LABEL: test_indirect_tail_call_global:
225; X64-PIC:       # %bb.0: # %entry
226; X64-PIC-NEXT:    movq %rsp, %rax
227; X64-PIC-NEXT:    movq $-1, %rcx
228; X64-PIC-NEXT:    sarq $63, %rax
229; X64-PIC-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
230; X64-PIC-NEXT:    movq (%rcx), %rcx
231; X64-PIC-NEXT:    orq %rax, %rcx
232; X64-PIC-NEXT:    shlq $47, %rax
233; X64-PIC-NEXT:    orq %rax, %rsp
234; X64-PIC-NEXT:    jmpq *%rcx # TAILCALL
235;
236; X64-RETPOLINE-LABEL: test_indirect_tail_call_global:
237; X64-RETPOLINE:       # %bb.0: # %entry
238; X64-RETPOLINE-NEXT:    movq %rsp, %rax
239; X64-RETPOLINE-NEXT:    movq $-1, %rcx
240; X64-RETPOLINE-NEXT:    sarq $63, %rax
241; X64-RETPOLINE-NEXT:    movq global_fnptr@GOTPCREL(%rip), %rcx
242; X64-RETPOLINE-NEXT:    movq (%rcx), %r11
243; X64-RETPOLINE-NEXT:    orq %rax, %r11
244; X64-RETPOLINE-NEXT:    shlq $47, %rax
245; X64-RETPOLINE-NEXT:    orq %rax, %rsp
246; X64-RETPOLINE-NEXT:    jmp __llvm_retpoline_r11 # TAILCALL
247entry:
248  %fp = load ptr, ptr @global_fnptr
249  %v = tail call i32 %fp()
250  ret i32 %v
251}
252
253define dso_local i32 @test_indirectbr(ptr %ptr) nounwind {
254; X64-LABEL: test_indirectbr:
255; X64:       # %bb.0: # %entry
256; X64-NEXT:    movq %rsp, %rcx
257; X64-NEXT:    movq $-1, %rax
258; X64-NEXT:    sarq $63, %rcx
259; X64-NEXT:    movq (%rdi), %rdx
260; X64-NEXT:    orq %rcx, %rdx
261; X64-NEXT:    jmpq *%rdx
262; X64-NEXT:  .LBB4_1: # Block address taken
263; X64-NEXT:    # %bb0
264; X64-NEXT:    cmpq $.LBB4_1, %rdx
265; X64-NEXT:    cmovneq %rax, %rcx
266; X64-NEXT:    shlq $47, %rcx
267; X64-NEXT:    movl $2, %eax
268; X64-NEXT:    orq %rcx, %rsp
269; X64-NEXT:    retq
270; X64-NEXT:  .LBB4_3: # Block address taken
271; X64-NEXT:    # %bb2
272; X64-NEXT:    cmpq $.LBB4_3, %rdx
273; X64-NEXT:    cmovneq %rax, %rcx
274; X64-NEXT:    shlq $47, %rcx
275; X64-NEXT:    movl $13, %eax
276; X64-NEXT:    orq %rcx, %rsp
277; X64-NEXT:    retq
278; X64-NEXT:  .LBB4_4: # Block address taken
279; X64-NEXT:    # %bb3
280; X64-NEXT:    cmpq $.LBB4_4, %rdx
281; X64-NEXT:    cmovneq %rax, %rcx
282; X64-NEXT:    shlq $47, %rcx
283; X64-NEXT:    movl $42, %eax
284; X64-NEXT:    orq %rcx, %rsp
285; X64-NEXT:    retq
286; X64-NEXT:  .LBB4_2: # Block address taken
287; X64-NEXT:    # %bb1
288; X64-NEXT:    cmpq $.LBB4_2, %rdx
289; X64-NEXT:    cmovneq %rax, %rcx
290; X64-NEXT:    shlq $47, %rcx
291; X64-NEXT:    movl $7, %eax
292; X64-NEXT:    orq %rcx, %rsp
293; X64-NEXT:    retq
294;
295; X64-PIC-LABEL: test_indirectbr:
296; X64-PIC:       # %bb.0: # %entry
297; X64-PIC-NEXT:    movq %rsp, %rcx
298; X64-PIC-NEXT:    movq $-1, %rax
299; X64-PIC-NEXT:    sarq $63, %rcx
300; X64-PIC-NEXT:    movq (%rdi), %rdx
301; X64-PIC-NEXT:    orq %rcx, %rdx
302; X64-PIC-NEXT:    jmpq *%rdx
303; X64-PIC-NEXT:  .LBB4_1: # Block address taken
304; X64-PIC-NEXT:    # %bb0
305; X64-PIC-NEXT:    leaq .LBB4_1(%rip), %rsi
306; X64-PIC-NEXT:    cmpq %rsi, %rdx
307; X64-PIC-NEXT:    cmovneq %rax, %rcx
308; X64-PIC-NEXT:    shlq $47, %rcx
309; X64-PIC-NEXT:    movl $2, %eax
310; X64-PIC-NEXT:    orq %rcx, %rsp
311; X64-PIC-NEXT:    retq
312; X64-PIC-NEXT:  .LBB4_3: # Block address taken
313; X64-PIC-NEXT:    # %bb2
314; X64-PIC-NEXT:    leaq .LBB4_3(%rip), %rsi
315; X64-PIC-NEXT:    cmpq %rsi, %rdx
316; X64-PIC-NEXT:    cmovneq %rax, %rcx
317; X64-PIC-NEXT:    shlq $47, %rcx
318; X64-PIC-NEXT:    movl $13, %eax
319; X64-PIC-NEXT:    orq %rcx, %rsp
320; X64-PIC-NEXT:    retq
321; X64-PIC-NEXT:  .LBB4_4: # Block address taken
322; X64-PIC-NEXT:    # %bb3
323; X64-PIC-NEXT:    leaq .LBB4_4(%rip), %rsi
324; X64-PIC-NEXT:    cmpq %rsi, %rdx
325; X64-PIC-NEXT:    cmovneq %rax, %rcx
326; X64-PIC-NEXT:    shlq $47, %rcx
327; X64-PIC-NEXT:    movl $42, %eax
328; X64-PIC-NEXT:    orq %rcx, %rsp
329; X64-PIC-NEXT:    retq
330; X64-PIC-NEXT:  .LBB4_2: # Block address taken
331; X64-PIC-NEXT:    # %bb1
332; X64-PIC-NEXT:    leaq .LBB4_2(%rip), %rsi
333; X64-PIC-NEXT:    cmpq %rsi, %rdx
334; X64-PIC-NEXT:    cmovneq %rax, %rcx
335; X64-PIC-NEXT:    shlq $47, %rcx
336; X64-PIC-NEXT:    movl $7, %eax
337; X64-PIC-NEXT:    orq %rcx, %rsp
338; X64-PIC-NEXT:    retq
339;
340; X64-RETPOLINE-LABEL: test_indirectbr:
341; X64-RETPOLINE:       # %bb.0: # %entry
342entry:
343  %a = load ptr, ptr %ptr
344  indirectbr ptr %a, [ label %bb0, label %bb1, label %bb2, label %bb3 ]
345
346bb0:
347  ret i32 2
348
349bb1:
350  ret i32 7
351
352bb2:
353  ret i32 13
354
355bb3:
356  ret i32 42
357}
358
359define dso_local i32 @test_indirectbr_global(i32 %idx) nounwind {
360; X64-LABEL: test_indirectbr_global:
361; X64:       # %bb.0: # %entry
362; X64-NEXT:    movq %rsp, %rcx
363; X64-NEXT:    movq $-1, %rax
364; X64-NEXT:    sarq $63, %rcx
365; X64-NEXT:    movslq %edi, %rdx
366; X64-NEXT:    movq global_blockaddrs(,%rdx,8), %rdx
367; X64-NEXT:    orq %rcx, %rdx
368; X64-NEXT:    jmpq *%rdx
369; X64-NEXT:  .Ltmp0: # Block address taken
370; X64-NEXT:  .LBB5_1: # %bb0
371; X64-NEXT:    cmpq $.LBB5_1, %rdx
372; X64-NEXT:    cmovneq %rax, %rcx
373; X64-NEXT:    shlq $47, %rcx
374; X64-NEXT:    movl $2, %eax
375; X64-NEXT:    orq %rcx, %rsp
376; X64-NEXT:    retq
377; X64-NEXT:  .Ltmp1: # Block address taken
378; X64-NEXT:  .LBB5_3: # %bb2
379; X64-NEXT:    cmpq $.LBB5_3, %rdx
380; X64-NEXT:    cmovneq %rax, %rcx
381; X64-NEXT:    shlq $47, %rcx
382; X64-NEXT:    movl $13, %eax
383; X64-NEXT:    orq %rcx, %rsp
384; X64-NEXT:    retq
385; X64-NEXT:  .Ltmp2: # Block address taken
386; X64-NEXT:  .LBB5_4: # %bb3
387; X64-NEXT:    cmpq $.LBB5_4, %rdx
388; X64-NEXT:    cmovneq %rax, %rcx
389; X64-NEXT:    shlq $47, %rcx
390; X64-NEXT:    movl $42, %eax
391; X64-NEXT:    orq %rcx, %rsp
392; X64-NEXT:    retq
393; X64-NEXT:  .Ltmp3: # Block address taken
394; X64-NEXT:  .LBB5_2: # %bb1
395; X64-NEXT:    cmpq $.LBB5_2, %rdx
396; X64-NEXT:    cmovneq %rax, %rcx
397; X64-NEXT:    shlq $47, %rcx
398; X64-NEXT:    movl $7, %eax
399; X64-NEXT:    orq %rcx, %rsp
400; X64-NEXT:    retq
401;
402; X64-PIC-LABEL: test_indirectbr_global:
403; X64-PIC:       # %bb.0: # %entry
404; X64-PIC-NEXT:    movq %rsp, %rcx
405; X64-PIC-NEXT:    movq $-1, %rax
406; X64-PIC-NEXT:    sarq $63, %rcx
407; X64-PIC-NEXT:    movslq %edi, %rdx
408; X64-PIC-NEXT:    leaq .Lglobal_blockaddrs$local(%rip), %rsi
409; X64-PIC-NEXT:    movq (%rsi,%rdx,8), %rdx
410; X64-PIC-NEXT:    orq %rcx, %rdx
411; X64-PIC-NEXT:    jmpq *%rdx
412; X64-PIC-NEXT:  .Ltmp0: # Block address taken
413; X64-PIC-NEXT:  .LBB5_1: # %bb0
414; X64-PIC-NEXT:    leaq .LBB5_1(%rip), %rsi
415; X64-PIC-NEXT:    cmpq %rsi, %rdx
416; X64-PIC-NEXT:    cmovneq %rax, %rcx
417; X64-PIC-NEXT:    shlq $47, %rcx
418; X64-PIC-NEXT:    movl $2, %eax
419; X64-PIC-NEXT:    orq %rcx, %rsp
420; X64-PIC-NEXT:    retq
421; X64-PIC-NEXT:  .Ltmp1: # Block address taken
422; X64-PIC-NEXT:  .LBB5_3: # %bb2
423; X64-PIC-NEXT:    leaq .LBB5_3(%rip), %rsi
424; X64-PIC-NEXT:    cmpq %rsi, %rdx
425; X64-PIC-NEXT:    cmovneq %rax, %rcx
426; X64-PIC-NEXT:    shlq $47, %rcx
427; X64-PIC-NEXT:    movl $13, %eax
428; X64-PIC-NEXT:    orq %rcx, %rsp
429; X64-PIC-NEXT:    retq
430; X64-PIC-NEXT:  .Ltmp2: # Block address taken
431; X64-PIC-NEXT:  .LBB5_4: # %bb3
432; X64-PIC-NEXT:    leaq .LBB5_4(%rip), %rsi
433; X64-PIC-NEXT:    cmpq %rsi, %rdx
434; X64-PIC-NEXT:    cmovneq %rax, %rcx
435; X64-PIC-NEXT:    shlq $47, %rcx
436; X64-PIC-NEXT:    movl $42, %eax
437; X64-PIC-NEXT:    orq %rcx, %rsp
438; X64-PIC-NEXT:    retq
439; X64-PIC-NEXT:  .Ltmp3: # Block address taken
440; X64-PIC-NEXT:  .LBB5_2: # %bb1
441; X64-PIC-NEXT:    leaq .LBB5_2(%rip), %rsi
442; X64-PIC-NEXT:    cmpq %rsi, %rdx
443; X64-PIC-NEXT:    cmovneq %rax, %rcx
444; X64-PIC-NEXT:    shlq $47, %rcx
445; X64-PIC-NEXT:    movl $7, %eax
446; X64-PIC-NEXT:    orq %rcx, %rsp
447; X64-PIC-NEXT:    retq
448;
449; X64-RETPOLINE-LABEL: test_indirectbr_global:
450; X64-RETPOLINE:       # %bb.0: # %entry
451; X64-RETPOLINE-NEXT:    movq %rsp, %rcx
452; X64-RETPOLINE-NEXT:    movq $-1, %rax
453; X64-RETPOLINE-NEXT:    sarq $63, %rcx
454; X64-RETPOLINE-NEXT:    movslq %edi, %rdx
455; X64-RETPOLINE-NEXT:    movq global_blockaddrs(,%rdx,8), %rdx
456; X64-RETPOLINE-NEXT:    orq %rcx, %rdx
457; X64-RETPOLINE-NEXT:    cmpq $2, %rdx
458; X64-RETPOLINE-NEXT:    je .LBB6_4
459; X64-RETPOLINE-NEXT:  # %bb.1: # %entry
460; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
461; X64-RETPOLINE-NEXT:    cmpq $3, %rdx
462; X64-RETPOLINE-NEXT:    je .LBB6_5
463; X64-RETPOLINE-NEXT:  # %bb.2: # %entry
464; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
465; X64-RETPOLINE-NEXT:    cmpq $4, %rdx
466; X64-RETPOLINE-NEXT:    jne .LBB6_3
467; X64-RETPOLINE-NEXT:  .Ltmp0: # Block address taken
468; X64-RETPOLINE-NEXT:  # %bb.6: # %bb3
469; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
470; X64-RETPOLINE-NEXT:    shlq $47, %rcx
471; X64-RETPOLINE-NEXT:    movl $42, %eax
472; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
473; X64-RETPOLINE-NEXT:    retq
474; X64-RETPOLINE-NEXT:  .Ltmp1: # Block address taken
475; X64-RETPOLINE-NEXT:  .LBB6_5: # %bb2
476; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
477; X64-RETPOLINE-NEXT:    shlq $47, %rcx
478; X64-RETPOLINE-NEXT:    movl $13, %eax
479; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
480; X64-RETPOLINE-NEXT:    retq
481; X64-RETPOLINE-NEXT:  .Ltmp2: # Block address taken
482; X64-RETPOLINE-NEXT:  .LBB6_4: # %bb1
483; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
484; X64-RETPOLINE-NEXT:    shlq $47, %rcx
485; X64-RETPOLINE-NEXT:    movl $7, %eax
486; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
487; X64-RETPOLINE-NEXT:    retq
488; X64-RETPOLINE-NEXT:  .Ltmp3: # Block address taken
489; X64-RETPOLINE-NEXT:  .LBB6_3: # %bb0
490; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
491; X64-RETPOLINE-NEXT:    shlq $47, %rcx
492; X64-RETPOLINE-NEXT:    movl $2, %eax
493; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
494; X64-RETPOLINE-NEXT:    retq
495entry:
496  %ptr = getelementptr [4 x ptr], ptr @global_blockaddrs, i32 0, i32 %idx
497  %a = load ptr, ptr %ptr
498  indirectbr ptr %a, [ label %bb0, label %bb1, label %bb2, label %bb3 ]
499
500bb0:
501  ret i32 2
502
503bb1:
504  ret i32 7
505
506bb2:
507  ret i32 13
508
509bb3:
510  ret i32 42
511}
512
513; This function's switch is crafted to trigger jump-table lowering in the x86
514; backend so that we can test how the exact jump table lowering behaves.
515define dso_local i32 @test_switch_jumptable(i32 %idx) nounwind {
516; X64-LABEL: test_switch_jumptable:
517; X64:       # %bb.0: # %entry
518; X64-NEXT:    movq %rsp, %rcx
519; X64-NEXT:    movq $-1, %rax
520; X64-NEXT:    sarq $63, %rcx
521; X64-NEXT:    cmpl $3, %edi
522; X64-NEXT:    ja .LBB6_2
523; X64-NEXT:  # %bb.1: # %entry
524; X64-NEXT:    cmovaq %rax, %rcx
525; X64-NEXT:    movl %edi, %edx
526; X64-NEXT:    movq .LJTI6_0(,%rdx,8), %rdx
527; X64-NEXT:    orq %rcx, %rdx
528; X64-NEXT:    jmpq *%rdx
529; X64-NEXT:  .LBB6_3: # Block address taken
530; X64-NEXT:    # %bb1
531; X64-NEXT:    cmpq $.LBB6_3, %rdx
532; X64-NEXT:    cmovneq %rax, %rcx
533; X64-NEXT:    shlq $47, %rcx
534; X64-NEXT:    movl $7, %eax
535; X64-NEXT:    orq %rcx, %rsp
536; X64-NEXT:    retq
537; X64-NEXT:  .LBB6_5: # Block address taken
538; X64-NEXT:    # %bb3
539; X64-NEXT:    cmpq $.LBB6_5, %rdx
540; X64-NEXT:    cmovneq %rax, %rcx
541; X64-NEXT:    shlq $47, %rcx
542; X64-NEXT:    movl $42, %eax
543; X64-NEXT:    orq %rcx, %rsp
544; X64-NEXT:    retq
545; X64-NEXT:  .LBB6_6: # Block address taken
546; X64-NEXT:    # %bb5
547; X64-NEXT:    cmpq $.LBB6_6, %rdx
548; X64-NEXT:    cmovneq %rax, %rcx
549; X64-NEXT:    shlq $47, %rcx
550; X64-NEXT:    movl $11, %eax
551; X64-NEXT:    orq %rcx, %rsp
552; X64-NEXT:    retq
553; X64-NEXT:  .LBB6_4: # Block address taken
554; X64-NEXT:    # %bb2
555; X64-NEXT:    cmpq $.LBB6_4, %rdx
556; X64-NEXT:    cmovneq %rax, %rcx
557; X64-NEXT:    shlq $47, %rcx
558; X64-NEXT:    movl $13, %eax
559; X64-NEXT:    orq %rcx, %rsp
560; X64-NEXT:    retq
561; X64-NEXT:  .LBB6_2: # %bb0
562; X64-NEXT:    cmovbeq %rax, %rcx
563; X64-NEXT:    shlq $47, %rcx
564; X64-NEXT:    movl $2, %eax
565; X64-NEXT:    orq %rcx, %rsp
566; X64-NEXT:    retq
567;
568; X64-PIC-LABEL: test_switch_jumptable:
569; X64-PIC:       # %bb.0: # %entry
570; X64-PIC-NEXT:    movq %rsp, %rcx
571; X64-PIC-NEXT:    movq $-1, %rax
572; X64-PIC-NEXT:    sarq $63, %rcx
573; X64-PIC-NEXT:    cmpl $3, %edi
574; X64-PIC-NEXT:    ja .LBB6_2
575; X64-PIC-NEXT:  # %bb.1: # %entry
576; X64-PIC-NEXT:    cmovaq %rax, %rcx
577; X64-PIC-NEXT:    movl %edi, %edx
578; X64-PIC-NEXT:    leaq .LJTI6_0(%rip), %rsi
579; X64-PIC-NEXT:    movslq (%rsi,%rdx,4), %rdx
580; X64-PIC-NEXT:    addq %rsi, %rdx
581; X64-PIC-NEXT:    orq %rcx, %rdx
582; X64-PIC-NEXT:    jmpq *%rdx
583; X64-PIC-NEXT:  .LBB6_3: # Block address taken
584; X64-PIC-NEXT:    # %bb1
585; X64-PIC-NEXT:    leaq .LBB6_3(%rip), %rsi
586; X64-PIC-NEXT:    cmpq %rsi, %rdx
587; X64-PIC-NEXT:    cmovneq %rax, %rcx
588; X64-PIC-NEXT:    shlq $47, %rcx
589; X64-PIC-NEXT:    movl $7, %eax
590; X64-PIC-NEXT:    orq %rcx, %rsp
591; X64-PIC-NEXT:    retq
592; X64-PIC-NEXT:  .LBB6_5: # Block address taken
593; X64-PIC-NEXT:    # %bb3
594; X64-PIC-NEXT:    leaq .LBB6_5(%rip), %rsi
595; X64-PIC-NEXT:    cmpq %rsi, %rdx
596; X64-PIC-NEXT:    cmovneq %rax, %rcx
597; X64-PIC-NEXT:    shlq $47, %rcx
598; X64-PIC-NEXT:    movl $42, %eax
599; X64-PIC-NEXT:    orq %rcx, %rsp
600; X64-PIC-NEXT:    retq
601; X64-PIC-NEXT:  .LBB6_6: # Block address taken
602; X64-PIC-NEXT:    # %bb5
603; X64-PIC-NEXT:    leaq .LBB6_6(%rip), %rsi
604; X64-PIC-NEXT:    cmpq %rsi, %rdx
605; X64-PIC-NEXT:    cmovneq %rax, %rcx
606; X64-PIC-NEXT:    shlq $47, %rcx
607; X64-PIC-NEXT:    movl $11, %eax
608; X64-PIC-NEXT:    orq %rcx, %rsp
609; X64-PIC-NEXT:    retq
610; X64-PIC-NEXT:  .LBB6_4: # Block address taken
611; X64-PIC-NEXT:    # %bb2
612; X64-PIC-NEXT:    leaq .LBB6_4(%rip), %rsi
613; X64-PIC-NEXT:    cmpq %rsi, %rdx
614; X64-PIC-NEXT:    cmovneq %rax, %rcx
615; X64-PIC-NEXT:    shlq $47, %rcx
616; X64-PIC-NEXT:    movl $13, %eax
617; X64-PIC-NEXT:    orq %rcx, %rsp
618; X64-PIC-NEXT:    retq
619; X64-PIC-NEXT:  .LBB6_2: # %bb0
620; X64-PIC-NEXT:    cmovbeq %rax, %rcx
621; X64-PIC-NEXT:    shlq $47, %rcx
622; X64-PIC-NEXT:    movl $2, %eax
623; X64-PIC-NEXT:    orq %rcx, %rsp
624; X64-PIC-NEXT:    retq
625;
626; X64-RETPOLINE-LABEL: test_switch_jumptable:
627; X64-RETPOLINE:       # %bb.0: # %entry
628; X64-RETPOLINE-NEXT:    movq %rsp, %rcx
629; X64-RETPOLINE-NEXT:    movq $-1, %rax
630; X64-RETPOLINE-NEXT:    sarq $63, %rcx
631; X64-RETPOLINE-NEXT:    cmpl $1, %edi
632; X64-RETPOLINE-NEXT:    jg .LBB7_4
633; X64-RETPOLINE-NEXT:  # %bb.1: # %entry
634; X64-RETPOLINE-NEXT:    cmovgq %rax, %rcx
635; X64-RETPOLINE-NEXT:    testl %edi, %edi
636; X64-RETPOLINE-NEXT:    je .LBB7_7
637; X64-RETPOLINE-NEXT:  # %bb.2: # %entry
638; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
639; X64-RETPOLINE-NEXT:    cmpl $1, %edi
640; X64-RETPOLINE-NEXT:    jne .LBB7_6
641; X64-RETPOLINE-NEXT:  # %bb.3: # %bb2
642; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
643; X64-RETPOLINE-NEXT:    shlq $47, %rcx
644; X64-RETPOLINE-NEXT:    movl $13, %eax
645; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
646; X64-RETPOLINE-NEXT:    retq
647; X64-RETPOLINE-NEXT:  .LBB7_4: # %entry
648; X64-RETPOLINE-NEXT:    cmovleq %rax, %rcx
649; X64-RETPOLINE-NEXT:    cmpl $2, %edi
650; X64-RETPOLINE-NEXT:    je .LBB7_8
651; X64-RETPOLINE-NEXT:  # %bb.5: # %entry
652; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
653; X64-RETPOLINE-NEXT:    cmpl $3, %edi
654; X64-RETPOLINE-NEXT:    jne .LBB7_6
655; X64-RETPOLINE-NEXT:  # %bb.9: # %bb5
656; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
657; X64-RETPOLINE-NEXT:    shlq $47, %rcx
658; X64-RETPOLINE-NEXT:    movl $11, %eax
659; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
660; X64-RETPOLINE-NEXT:    retq
661; X64-RETPOLINE-NEXT:  .LBB7_6:
662; X64-RETPOLINE-NEXT:    cmoveq %rax, %rcx
663; X64-RETPOLINE-NEXT:    shlq $47, %rcx
664; X64-RETPOLINE-NEXT:    movl $2, %eax
665; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
666; X64-RETPOLINE-NEXT:    retq
667; X64-RETPOLINE-NEXT:  .LBB7_7: # %bb1
668; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
669; X64-RETPOLINE-NEXT:    shlq $47, %rcx
670; X64-RETPOLINE-NEXT:    movl $7, %eax
671; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
672; X64-RETPOLINE-NEXT:    retq
673; X64-RETPOLINE-NEXT:  .LBB7_8: # %bb3
674; X64-RETPOLINE-NEXT:    cmovneq %rax, %rcx
675; X64-RETPOLINE-NEXT:    shlq $47, %rcx
676; X64-RETPOLINE-NEXT:    movl $42, %eax
677; X64-RETPOLINE-NEXT:    orq %rcx, %rsp
678; X64-RETPOLINE-NEXT:    retq
679entry:
680  switch i32 %idx, label %bb0 [
681    i32 0, label %bb1
682    i32 1, label %bb2
683    i32 2, label %bb3
684    i32 3, label %bb5
685  ]
686
687bb0:
688  ret i32 2
689
690bb1:
691  ret i32 7
692
693bb2:
694  ret i32 13
695
696bb3:
697  ret i32 42
698
699bb5:
700  ret i32 11
701}
702
703; This function's switch is crafted to trigger jump-table lowering in the x86
704; backend so that we can test how the exact jump table lowering behaves, but
705; also arranges for fallthroughs from case to case to ensure that this pattern
706; too can be handled.
707define dso_local i32 @test_switch_jumptable_fallthrough(i32 %idx, ptr %a.ptr, ptr %b.ptr, ptr %c.ptr, ptr %d.ptr) nounwind {
708; X64-LABEL: test_switch_jumptable_fallthrough:
709; X64:       # %bb.0: # %entry
710; X64-NEXT:    movq %rsp, %r9
711; X64-NEXT:    movq $-1, %r10
712; X64-NEXT:    sarq $63, %r9
713; X64-NEXT:    cmpl $3, %edi
714; X64-NEXT:    ja .LBB7_2
715; X64-NEXT:  # %bb.1: # %entry
716; X64-NEXT:    cmovaq %r10, %r9
717; X64-NEXT:    xorl %eax, %eax
718; X64-NEXT:    movl %edi, %esi
719; X64-NEXT:    movq .LJTI7_0(,%rsi,8), %rsi
720; X64-NEXT:    orq %r9, %rsi
721; X64-NEXT:    jmpq *%rsi
722; X64-NEXT:  .LBB7_2: # %bb0
723; X64-NEXT:    cmovbeq %r10, %r9
724; X64-NEXT:    movl (%rsi), %edi
725; X64-NEXT:    orl %r9d, %edi
726; X64-NEXT:    movq $.LBB7_3, %rsi
727; X64-NEXT:  .LBB7_3: # Block address taken
728; X64-NEXT:    # %bb1
729; X64-NEXT:    cmpq $.LBB7_3, %rsi
730; X64-NEXT:    cmovneq %r10, %r9
731; X64-NEXT:    addl (%rdx), %edi
732; X64-NEXT:    orl %r9d, %edi
733; X64-NEXT:    movq $.LBB7_4, %rsi
734; X64-NEXT:    movl %edi, %eax
735; X64-NEXT:  .LBB7_4: # Block address taken
736; X64-NEXT:    # %bb2
737; X64-NEXT:    cmpq $.LBB7_4, %rsi
738; X64-NEXT:    cmovneq %r10, %r9
739; X64-NEXT:    addl (%rcx), %eax
740; X64-NEXT:    orl %r9d, %eax
741; X64-NEXT:    movq $.LBB7_5, %rsi
742; X64-NEXT:  .LBB7_5: # Block address taken
743; X64-NEXT:    # %bb3
744; X64-NEXT:    cmpq $.LBB7_5, %rsi
745; X64-NEXT:    cmovneq %r10, %r9
746; X64-NEXT:    addl (%r8), %eax
747; X64-NEXT:    orl %r9d, %eax
748; X64-NEXT:    movq $.LBB7_6, %rsi
749; X64-NEXT:  .LBB7_6: # Block address taken
750; X64-NEXT:    # %bb4
751; X64-NEXT:    cmpq $.LBB7_6, %rsi
752; X64-NEXT:    cmovneq %r10, %r9
753; X64-NEXT:    shlq $47, %r9
754; X64-NEXT:    orq %r9, %rsp
755; X64-NEXT:    retq
756;
757; X64-PIC-LABEL: test_switch_jumptable_fallthrough:
758; X64-PIC:       # %bb.0: # %entry
759; X64-PIC-NEXT:    movq %rsp, %r9
760; X64-PIC-NEXT:    movq $-1, %r10
761; X64-PIC-NEXT:    sarq $63, %r9
762; X64-PIC-NEXT:    cmpl $3, %edi
763; X64-PIC-NEXT:    ja .LBB7_2
764; X64-PIC-NEXT:  # %bb.1: # %entry
765; X64-PIC-NEXT:    cmovaq %r10, %r9
766; X64-PIC-NEXT:    xorl %eax, %eax
767; X64-PIC-NEXT:    movl %edi, %esi
768; X64-PIC-NEXT:    leaq .LJTI7_0(%rip), %r11
769; X64-PIC-NEXT:    movslq (%r11,%rsi,4), %rsi
770; X64-PIC-NEXT:    addq %r11, %rsi
771; X64-PIC-NEXT:    orq %r9, %rsi
772; X64-PIC-NEXT:    jmpq *%rsi
773; X64-PIC-NEXT:  .LBB7_2: # %bb0
774; X64-PIC-NEXT:    cmovbeq %r10, %r9
775; X64-PIC-NEXT:    movl (%rsi), %edi
776; X64-PIC-NEXT:    orl %r9d, %edi
777; X64-PIC-NEXT:    leaq .LBB7_3(%rip), %rsi
778; X64-PIC-NEXT:  .LBB7_3: # Block address taken
779; X64-PIC-NEXT:    # %bb1
780; X64-PIC-NEXT:    leaq .LBB7_3(%rip), %rax
781; X64-PIC-NEXT:    cmpq %rax, %rsi
782; X64-PIC-NEXT:    cmovneq %r10, %r9
783; X64-PIC-NEXT:    addl (%rdx), %edi
784; X64-PIC-NEXT:    orl %r9d, %edi
785; X64-PIC-NEXT:    leaq .LBB7_4(%rip), %rsi
786; X64-PIC-NEXT:    movl %edi, %eax
787; X64-PIC-NEXT:  .LBB7_4: # Block address taken
788; X64-PIC-NEXT:    # %bb2
789; X64-PIC-NEXT:    leaq .LBB7_4(%rip), %rdx
790; X64-PIC-NEXT:    cmpq %rdx, %rsi
791; X64-PIC-NEXT:    cmovneq %r10, %r9
792; X64-PIC-NEXT:    addl (%rcx), %eax
793; X64-PIC-NEXT:    orl %r9d, %eax
794; X64-PIC-NEXT:    leaq .LBB7_5(%rip), %rsi
795; X64-PIC-NEXT:  .LBB7_5: # Block address taken
796; X64-PIC-NEXT:    # %bb3
797; X64-PIC-NEXT:    leaq .LBB7_5(%rip), %rcx
798; X64-PIC-NEXT:    cmpq %rcx, %rsi
799; X64-PIC-NEXT:    cmovneq %r10, %r9
800; X64-PIC-NEXT:    addl (%r8), %eax
801; X64-PIC-NEXT:    orl %r9d, %eax
802; X64-PIC-NEXT:    leaq .LBB7_6(%rip), %rsi
803; X64-PIC-NEXT:  .LBB7_6: # Block address taken
804; X64-PIC-NEXT:    # %bb4
805; X64-PIC-NEXT:    leaq .LBB7_6(%rip), %rcx
806; X64-PIC-NEXT:    cmpq %rcx, %rsi
807; X64-PIC-NEXT:    cmovneq %r10, %r9
808; X64-PIC-NEXT:    shlq $47, %r9
809; X64-PIC-NEXT:    orq %r9, %rsp
810; X64-PIC-NEXT:    retq
811;
812; X64-RETPOLINE-LABEL: test_switch_jumptable_fallthrough:
813; X64-RETPOLINE:       # %bb.0: # %entry
814; X64-RETPOLINE-NEXT:    movq %rsp, %r9
815; X64-RETPOLINE-NEXT:    movq $-1, %r10
816; X64-RETPOLINE-NEXT:    sarq $63, %r9
817; X64-RETPOLINE-NEXT:    xorl %eax, %eax
818; X64-RETPOLINE-NEXT:    cmpl $1, %edi
819; X64-RETPOLINE-NEXT:    jg .LBB8_5
820; X64-RETPOLINE-NEXT:  # %bb.1: # %entry
821; X64-RETPOLINE-NEXT:    cmovgq %r10, %r9
822; X64-RETPOLINE-NEXT:    testl %edi, %edi
823; X64-RETPOLINE-NEXT:    je .LBB8_2
824; X64-RETPOLINE-NEXT:  # %bb.3: # %entry
825; X64-RETPOLINE-NEXT:    cmoveq %r10, %r9
826; X64-RETPOLINE-NEXT:    cmpl $1, %edi
827; X64-RETPOLINE-NEXT:    jne .LBB8_8
828; X64-RETPOLINE-NEXT:  # %bb.4:
829; X64-RETPOLINE-NEXT:    cmovneq %r10, %r9
830; X64-RETPOLINE-NEXT:    jmp .LBB8_10
831; X64-RETPOLINE-NEXT:  .LBB8_5: # %entry
832; X64-RETPOLINE-NEXT:    cmovleq %r10, %r9
833; X64-RETPOLINE-NEXT:    cmpl $2, %edi
834; X64-RETPOLINE-NEXT:    je .LBB8_6
835; X64-RETPOLINE-NEXT:  # %bb.7: # %entry
836; X64-RETPOLINE-NEXT:    cmoveq %r10, %r9
837; X64-RETPOLINE-NEXT:    cmpl $3, %edi
838; X64-RETPOLINE-NEXT:    jne .LBB8_8
839; X64-RETPOLINE-NEXT:  # %bb.13:
840; X64-RETPOLINE-NEXT:    cmovneq %r10, %r9
841; X64-RETPOLINE-NEXT:    jmp .LBB8_12
842; X64-RETPOLINE-NEXT:  .LBB8_8:
843; X64-RETPOLINE-NEXT:    cmoveq %r10, %r9
844; X64-RETPOLINE-NEXT:    movl (%rsi), %edi
845; X64-RETPOLINE-NEXT:    orl %r9d, %edi
846; X64-RETPOLINE-NEXT:    jmp .LBB8_9
847; X64-RETPOLINE-NEXT:  .LBB8_2:
848; X64-RETPOLINE-NEXT:    cmovneq %r10, %r9
849; X64-RETPOLINE-NEXT:  .LBB8_9: # %bb1
850; X64-RETPOLINE-NEXT:    addl (%rdx), %edi
851; X64-RETPOLINE-NEXT:    orl %r9d, %edi
852; X64-RETPOLINE-NEXT:    movl %edi, %eax
853; X64-RETPOLINE-NEXT:  .LBB8_10: # %bb2
854; X64-RETPOLINE-NEXT:    addl (%rcx), %eax
855; X64-RETPOLINE-NEXT:    orl %r9d, %eax
856; X64-RETPOLINE-NEXT:    jmp .LBB8_11
857; X64-RETPOLINE-NEXT:  .LBB8_6:
858; X64-RETPOLINE-NEXT:    cmovneq %r10, %r9
859; X64-RETPOLINE-NEXT:  .LBB8_11: # %bb3
860; X64-RETPOLINE-NEXT:    addl (%r8), %eax
861; X64-RETPOLINE-NEXT:    orl %r9d, %eax
862; X64-RETPOLINE-NEXT:  .LBB8_12: # %bb4
863; X64-RETPOLINE-NEXT:    shlq $47, %r9
864; X64-RETPOLINE-NEXT:    orq %r9, %rsp
865; X64-RETPOLINE-NEXT:    retq
866entry:
867  switch i32 %idx, label %bb0 [
868    i32 0, label %bb1
869    i32 1, label %bb2
870    i32 2, label %bb3
871    i32 3, label %bb4
872  ]
873
874bb0:
875  %a = load i32, ptr %a.ptr
876  br label %bb1
877
878bb1:
879  %b.phi = phi i32 [ 0, %entry ], [ %a, %bb0 ]
880  %b = load i32, ptr %b.ptr
881  %b.sum = add i32 %b.phi, %b
882  br label %bb2
883
884bb2:
885  %c.phi = phi i32 [ 0, %entry ], [ %b.sum, %bb1 ]
886  %c = load i32, ptr %c.ptr
887  %c.sum = add i32 %c.phi, %c
888  br label %bb3
889
890bb3:
891  %d.phi = phi i32 [ 0, %entry ], [ %c.sum, %bb2 ]
892  %d = load i32, ptr %d.ptr
893  %d.sum = add i32 %d.phi, %d
894  br label %bb4
895
896bb4:
897  %e.phi = phi i32 [ 0, %entry ], [ %d.sum, %bb3 ]
898  ret i32 %e.phi
899}
900