900 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2 3; Verify the call site info. If the call site info is not4; 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=machineverifier6 7; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -data-sections | FileCheck %s --check-prefix=X648; 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-PIC10; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-speculative-load-hardening -data-sections -mattr=+retpoline | FileCheck %s --check-prefix=X64-RETPOLINE11;12; FIXME: Add support for 32-bit.13 14@global_fnptr = external global ptr15 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: # %entry26; X64-NEXT: pushq %rbx27; X64-NEXT: movq %rsp, %rax28; X64-NEXT: movq $-1, %rbx29; X64-NEXT: sarq $63, %rax30; X64-NEXT: movq (%rdi), %rcx31; X64-NEXT: orq %rax, %rcx32; X64-NEXT: shlq $47, %rax33; X64-NEXT: orq %rax, %rsp34; X64-NEXT: callq *%rcx35; X64-NEXT: .Lslh_ret_addr0:36; X64-NEXT: movq %rsp, %rcx37; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdx38; X64-NEXT: sarq $63, %rcx39; X64-NEXT: cmpq $.Lslh_ret_addr0, %rdx40; X64-NEXT: cmovneq %rbx, %rcx41; X64-NEXT: shlq $47, %rcx42; X64-NEXT: orq %rcx, %rsp43; X64-NEXT: popq %rbx44; X64-NEXT: retq45;46; X64-PIC-LABEL: test_indirect_call:47; X64-PIC: # %bb.0: # %entry48; X64-PIC-NEXT: pushq %rbx49; X64-PIC-NEXT: movq %rsp, %rax50; X64-PIC-NEXT: movq $-1, %rbx51; X64-PIC-NEXT: sarq $63, %rax52; X64-PIC-NEXT: movq (%rdi), %rcx53; X64-PIC-NEXT: orq %rax, %rcx54; X64-PIC-NEXT: shlq $47, %rax55; X64-PIC-NEXT: orq %rax, %rsp56; X64-PIC-NEXT: callq *%rcx57; X64-PIC-NEXT: .Lslh_ret_addr0:58; X64-PIC-NEXT: movq %rsp, %rcx59; X64-PIC-NEXT: movq -{{[0-9]+}}(%rsp), %rdx60; X64-PIC-NEXT: sarq $63, %rcx61; X64-PIC-NEXT: leaq .Lslh_ret_addr0(%rip), %rsi62; X64-PIC-NEXT: cmpq %rsi, %rdx63; X64-PIC-NEXT: cmovneq %rbx, %rcx64; X64-PIC-NEXT: shlq $47, %rcx65; X64-PIC-NEXT: orq %rcx, %rsp66; X64-PIC-NEXT: popq %rbx67; X64-PIC-NEXT: retq68;69; X64-RETPOLINE-LABEL: test_indirect_call:70; X64-RETPOLINE: # %bb.0: # %entry71; X64-RETPOLINE-NEXT: pushq %rbx72; X64-RETPOLINE-NEXT: movq %rsp, %rax73; X64-RETPOLINE-NEXT: movq $-1, %rbx74; X64-RETPOLINE-NEXT: sarq $63, %rax75; X64-RETPOLINE-NEXT: movq (%rdi), %r1176; X64-RETPOLINE-NEXT: orq %rax, %r1177; X64-RETPOLINE-NEXT: shlq $47, %rax78; X64-RETPOLINE-NEXT: orq %rax, %rsp79; X64-RETPOLINE-NEXT: callq __llvm_retpoline_r1180; X64-RETPOLINE-NEXT: .Lslh_ret_addr0:81; X64-RETPOLINE-NEXT: movq %rsp, %rcx82; X64-RETPOLINE-NEXT: movq -{{[0-9]+}}(%rsp), %rdx83; X64-RETPOLINE-NEXT: sarq $63, %rcx84; X64-RETPOLINE-NEXT: cmpq $.Lslh_ret_addr0, %rdx85; X64-RETPOLINE-NEXT: cmovneq %rbx, %rcx86; X64-RETPOLINE-NEXT: shlq $47, %rcx87; X64-RETPOLINE-NEXT: orq %rcx, %rsp88; X64-RETPOLINE-NEXT: popq %rbx89; X64-RETPOLINE-NEXT: retq90entry:91 %fp = load ptr, ptr %ptr92 %v = call i32 %fp()93 ret i32 %v94}95 96define dso_local i32 @test_indirect_tail_call(ptr %ptr) nounwind {97; X64-LABEL: test_indirect_tail_call:98; X64: # %bb.0: # %entry99; X64-NEXT: movq %rsp, %rax100; X64-NEXT: movq $-1, %rcx101; X64-NEXT: sarq $63, %rax102; X64-NEXT: movq (%rdi), %rcx103; X64-NEXT: orq %rax, %rcx104; X64-NEXT: shlq $47, %rax105; X64-NEXT: orq %rax, %rsp106; X64-NEXT: jmpq *%rcx # TAILCALL107;108; X64-PIC-LABEL: test_indirect_tail_call:109; X64-PIC: # %bb.0: # %entry110; X64-PIC-NEXT: movq %rsp, %rax111; X64-PIC-NEXT: movq $-1, %rcx112; X64-PIC-NEXT: sarq $63, %rax113; X64-PIC-NEXT: movq (%rdi), %rcx114; X64-PIC-NEXT: orq %rax, %rcx115; X64-PIC-NEXT: shlq $47, %rax116; X64-PIC-NEXT: orq %rax, %rsp117; X64-PIC-NEXT: jmpq *%rcx # TAILCALL118;119; X64-RETPOLINE-LABEL: test_indirect_tail_call:120; X64-RETPOLINE: # %bb.0: # %entry121; X64-RETPOLINE-NEXT: movq %rsp, %rax122; X64-RETPOLINE-NEXT: movq $-1, %rcx123; X64-RETPOLINE-NEXT: sarq $63, %rax124; X64-RETPOLINE-NEXT: movq (%rdi), %r11125; X64-RETPOLINE-NEXT: orq %rax, %r11126; X64-RETPOLINE-NEXT: shlq $47, %rax127; X64-RETPOLINE-NEXT: orq %rax, %rsp128; X64-RETPOLINE-NEXT: jmp __llvm_retpoline_r11 # TAILCALL129entry:130 %fp = load ptr, ptr %ptr131 %v = tail call i32 %fp()132 ret i32 %v133}134 135define dso_local i32 @test_indirect_call_global() nounwind {136; X64-LABEL: test_indirect_call_global:137; X64: # %bb.0: # %entry138; X64-NEXT: pushq %rbx139; X64-NEXT: movq %rsp, %rax140; X64-NEXT: movq $-1, %rbx141; X64-NEXT: sarq $63, %rax142; X64-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx143; X64-NEXT: movq (%rcx), %rcx144; X64-NEXT: orq %rax, %rcx145; X64-NEXT: shlq $47, %rax146; X64-NEXT: orq %rax, %rsp147; X64-NEXT: callq *%rcx148; X64-NEXT: .Lslh_ret_addr1:149; X64-NEXT: movq %rsp, %rcx150; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdx151; X64-NEXT: sarq $63, %rcx152; X64-NEXT: cmpq $.Lslh_ret_addr1, %rdx153; X64-NEXT: cmovneq %rbx, %rcx154; X64-NEXT: shlq $47, %rcx155; X64-NEXT: orq %rcx, %rsp156; X64-NEXT: popq %rbx157; X64-NEXT: retq158;159; X64-PIC-LABEL: test_indirect_call_global:160; X64-PIC: # %bb.0: # %entry161; X64-PIC-NEXT: pushq %rbx162; X64-PIC-NEXT: movq %rsp, %rax163; X64-PIC-NEXT: movq $-1, %rbx164; X64-PIC-NEXT: sarq $63, %rax165; X64-PIC-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx166; X64-PIC-NEXT: movq (%rcx), %rcx167; X64-PIC-NEXT: orq %rax, %rcx168; X64-PIC-NEXT: shlq $47, %rax169; X64-PIC-NEXT: orq %rax, %rsp170; X64-PIC-NEXT: callq *%rcx171; X64-PIC-NEXT: .Lslh_ret_addr1:172; X64-PIC-NEXT: movq %rsp, %rcx173; X64-PIC-NEXT: movq -{{[0-9]+}}(%rsp), %rdx174; X64-PIC-NEXT: sarq $63, %rcx175; X64-PIC-NEXT: leaq .Lslh_ret_addr1(%rip), %rsi176; X64-PIC-NEXT: cmpq %rsi, %rdx177; X64-PIC-NEXT: cmovneq %rbx, %rcx178; X64-PIC-NEXT: shlq $47, %rcx179; X64-PIC-NEXT: orq %rcx, %rsp180; X64-PIC-NEXT: popq %rbx181; X64-PIC-NEXT: retq182;183; X64-RETPOLINE-LABEL: test_indirect_call_global:184; X64-RETPOLINE: # %bb.0: # %entry185; X64-RETPOLINE-NEXT: pushq %rbx186; X64-RETPOLINE-NEXT: movq %rsp, %rax187; X64-RETPOLINE-NEXT: movq $-1, %rbx188; X64-RETPOLINE-NEXT: sarq $63, %rax189; X64-RETPOLINE-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx190; X64-RETPOLINE-NEXT: movq (%rcx), %r11191; X64-RETPOLINE-NEXT: orq %rax, %r11192; X64-RETPOLINE-NEXT: shlq $47, %rax193; X64-RETPOLINE-NEXT: orq %rax, %rsp194; X64-RETPOLINE-NEXT: callq __llvm_retpoline_r11195; X64-RETPOLINE-NEXT: .Lslh_ret_addr1:196; X64-RETPOLINE-NEXT: movq %rsp, %rcx197; X64-RETPOLINE-NEXT: movq -{{[0-9]+}}(%rsp), %rdx198; X64-RETPOLINE-NEXT: sarq $63, %rcx199; X64-RETPOLINE-NEXT: cmpq $.Lslh_ret_addr1, %rdx200; X64-RETPOLINE-NEXT: cmovneq %rbx, %rcx201; X64-RETPOLINE-NEXT: shlq $47, %rcx202; X64-RETPOLINE-NEXT: orq %rcx, %rsp203; X64-RETPOLINE-NEXT: popq %rbx204; X64-RETPOLINE-NEXT: retq205entry:206 %fp = load ptr, ptr @global_fnptr207 %v = call i32 %fp()208 ret i32 %v209}210 211define dso_local i32 @test_indirect_tail_call_global() nounwind {212; X64-LABEL: test_indirect_tail_call_global:213; X64: # %bb.0: # %entry214; X64-NEXT: movq %rsp, %rax215; X64-NEXT: movq $-1, %rcx216; X64-NEXT: sarq $63, %rax217; X64-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx218; X64-NEXT: movq (%rcx), %rcx219; X64-NEXT: orq %rax, %rcx220; X64-NEXT: shlq $47, %rax221; X64-NEXT: orq %rax, %rsp222; X64-NEXT: jmpq *%rcx # TAILCALL223;224; X64-PIC-LABEL: test_indirect_tail_call_global:225; X64-PIC: # %bb.0: # %entry226; X64-PIC-NEXT: movq %rsp, %rax227; X64-PIC-NEXT: movq $-1, %rcx228; X64-PIC-NEXT: sarq $63, %rax229; X64-PIC-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx230; X64-PIC-NEXT: movq (%rcx), %rcx231; X64-PIC-NEXT: orq %rax, %rcx232; X64-PIC-NEXT: shlq $47, %rax233; X64-PIC-NEXT: orq %rax, %rsp234; X64-PIC-NEXT: jmpq *%rcx # TAILCALL235;236; X64-RETPOLINE-LABEL: test_indirect_tail_call_global:237; X64-RETPOLINE: # %bb.0: # %entry238; X64-RETPOLINE-NEXT: movq %rsp, %rax239; X64-RETPOLINE-NEXT: movq $-1, %rcx240; X64-RETPOLINE-NEXT: sarq $63, %rax241; X64-RETPOLINE-NEXT: movq global_fnptr@GOTPCREL(%rip), %rcx242; X64-RETPOLINE-NEXT: movq (%rcx), %r11243; X64-RETPOLINE-NEXT: orq %rax, %r11244; X64-RETPOLINE-NEXT: shlq $47, %rax245; X64-RETPOLINE-NEXT: orq %rax, %rsp246; X64-RETPOLINE-NEXT: jmp __llvm_retpoline_r11 # TAILCALL247entry:248 %fp = load ptr, ptr @global_fnptr249 %v = tail call i32 %fp()250 ret i32 %v251}252 253define dso_local i32 @test_indirectbr(ptr %ptr) nounwind {254; X64-LABEL: test_indirectbr:255; X64: # %bb.0: # %entry256; X64-NEXT: movq %rsp, %rcx257; X64-NEXT: movq $-1, %rax258; X64-NEXT: sarq $63, %rcx259; X64-NEXT: movq (%rdi), %rdx260; X64-NEXT: orq %rcx, %rdx261; X64-NEXT: jmpq *%rdx262; X64-NEXT: .LBB4_1: # Block address taken263; X64-NEXT: # %bb0264; X64-NEXT: cmpq $.LBB4_1, %rdx265; X64-NEXT: cmovneq %rax, %rcx266; X64-NEXT: shlq $47, %rcx267; X64-NEXT: movl $2, %eax268; X64-NEXT: orq %rcx, %rsp269; X64-NEXT: retq270; X64-NEXT: .LBB4_3: # Block address taken271; X64-NEXT: # %bb2272; X64-NEXT: cmpq $.LBB4_3, %rdx273; X64-NEXT: cmovneq %rax, %rcx274; X64-NEXT: shlq $47, %rcx275; X64-NEXT: movl $13, %eax276; X64-NEXT: orq %rcx, %rsp277; X64-NEXT: retq278; X64-NEXT: .LBB4_4: # Block address taken279; X64-NEXT: # %bb3280; X64-NEXT: cmpq $.LBB4_4, %rdx281; X64-NEXT: cmovneq %rax, %rcx282; X64-NEXT: shlq $47, %rcx283; X64-NEXT: movl $42, %eax284; X64-NEXT: orq %rcx, %rsp285; X64-NEXT: retq286; X64-NEXT: .LBB4_2: # Block address taken287; X64-NEXT: # %bb1288; X64-NEXT: cmpq $.LBB4_2, %rdx289; X64-NEXT: cmovneq %rax, %rcx290; X64-NEXT: shlq $47, %rcx291; X64-NEXT: movl $7, %eax292; X64-NEXT: orq %rcx, %rsp293; X64-NEXT: retq294;295; X64-PIC-LABEL: test_indirectbr:296; X64-PIC: # %bb.0: # %entry297; X64-PIC-NEXT: movq %rsp, %rcx298; X64-PIC-NEXT: movq $-1, %rax299; X64-PIC-NEXT: sarq $63, %rcx300; X64-PIC-NEXT: movq (%rdi), %rdx301; X64-PIC-NEXT: orq %rcx, %rdx302; X64-PIC-NEXT: jmpq *%rdx303; X64-PIC-NEXT: .LBB4_1: # Block address taken304; X64-PIC-NEXT: # %bb0305; X64-PIC-NEXT: leaq .LBB4_1(%rip), %rsi306; X64-PIC-NEXT: cmpq %rsi, %rdx307; X64-PIC-NEXT: cmovneq %rax, %rcx308; X64-PIC-NEXT: shlq $47, %rcx309; X64-PIC-NEXT: movl $2, %eax310; X64-PIC-NEXT: orq %rcx, %rsp311; X64-PIC-NEXT: retq312; X64-PIC-NEXT: .LBB4_3: # Block address taken313; X64-PIC-NEXT: # %bb2314; X64-PIC-NEXT: leaq .LBB4_3(%rip), %rsi315; X64-PIC-NEXT: cmpq %rsi, %rdx316; X64-PIC-NEXT: cmovneq %rax, %rcx317; X64-PIC-NEXT: shlq $47, %rcx318; X64-PIC-NEXT: movl $13, %eax319; X64-PIC-NEXT: orq %rcx, %rsp320; X64-PIC-NEXT: retq321; X64-PIC-NEXT: .LBB4_4: # Block address taken322; X64-PIC-NEXT: # %bb3323; X64-PIC-NEXT: leaq .LBB4_4(%rip), %rsi324; X64-PIC-NEXT: cmpq %rsi, %rdx325; X64-PIC-NEXT: cmovneq %rax, %rcx326; X64-PIC-NEXT: shlq $47, %rcx327; X64-PIC-NEXT: movl $42, %eax328; X64-PIC-NEXT: orq %rcx, %rsp329; X64-PIC-NEXT: retq330; X64-PIC-NEXT: .LBB4_2: # Block address taken331; X64-PIC-NEXT: # %bb1332; X64-PIC-NEXT: leaq .LBB4_2(%rip), %rsi333; X64-PIC-NEXT: cmpq %rsi, %rdx334; X64-PIC-NEXT: cmovneq %rax, %rcx335; X64-PIC-NEXT: shlq $47, %rcx336; X64-PIC-NEXT: movl $7, %eax337; X64-PIC-NEXT: orq %rcx, %rsp338; X64-PIC-NEXT: retq339;340; X64-RETPOLINE-LABEL: test_indirectbr:341; X64-RETPOLINE: # %bb.0: # %entry342entry:343 %a = load ptr, ptr %ptr344 indirectbr ptr %a, [ label %bb0, label %bb1, label %bb2, label %bb3 ]345 346bb0:347 ret i32 2348 349bb1:350 ret i32 7351 352bb2:353 ret i32 13354 355bb3:356 ret i32 42357}358 359define dso_local i32 @test_indirectbr_global(i32 %idx) nounwind {360; X64-LABEL: test_indirectbr_global:361; X64: # %bb.0: # %entry362; X64-NEXT: movq %rsp, %rcx363; X64-NEXT: movq $-1, %rax364; X64-NEXT: sarq $63, %rcx365; X64-NEXT: movslq %edi, %rdx366; X64-NEXT: movq global_blockaddrs(,%rdx,8), %rdx367; X64-NEXT: orq %rcx, %rdx368; X64-NEXT: jmpq *%rdx369; X64-NEXT: .Ltmp0: # Block address taken370; X64-NEXT: .LBB5_1: # %bb0371; X64-NEXT: cmpq $.LBB5_1, %rdx372; X64-NEXT: cmovneq %rax, %rcx373; X64-NEXT: shlq $47, %rcx374; X64-NEXT: movl $2, %eax375; X64-NEXT: orq %rcx, %rsp376; X64-NEXT: retq377; X64-NEXT: .Ltmp1: # Block address taken378; X64-NEXT: .LBB5_3: # %bb2379; X64-NEXT: cmpq $.LBB5_3, %rdx380; X64-NEXT: cmovneq %rax, %rcx381; X64-NEXT: shlq $47, %rcx382; X64-NEXT: movl $13, %eax383; X64-NEXT: orq %rcx, %rsp384; X64-NEXT: retq385; X64-NEXT: .Ltmp2: # Block address taken386; X64-NEXT: .LBB5_4: # %bb3387; X64-NEXT: cmpq $.LBB5_4, %rdx388; X64-NEXT: cmovneq %rax, %rcx389; X64-NEXT: shlq $47, %rcx390; X64-NEXT: movl $42, %eax391; X64-NEXT: orq %rcx, %rsp392; X64-NEXT: retq393; X64-NEXT: .Ltmp3: # Block address taken394; X64-NEXT: .LBB5_2: # %bb1395; X64-NEXT: cmpq $.LBB5_2, %rdx396; X64-NEXT: cmovneq %rax, %rcx397; X64-NEXT: shlq $47, %rcx398; X64-NEXT: movl $7, %eax399; X64-NEXT: orq %rcx, %rsp400; X64-NEXT: retq401;402; X64-PIC-LABEL: test_indirectbr_global:403; X64-PIC: # %bb.0: # %entry404; X64-PIC-NEXT: movq %rsp, %rcx405; X64-PIC-NEXT: movq $-1, %rax406; X64-PIC-NEXT: sarq $63, %rcx407; X64-PIC-NEXT: movslq %edi, %rdx408; X64-PIC-NEXT: leaq .Lglobal_blockaddrs$local(%rip), %rsi409; X64-PIC-NEXT: movq (%rsi,%rdx,8), %rdx410; X64-PIC-NEXT: orq %rcx, %rdx411; X64-PIC-NEXT: jmpq *%rdx412; X64-PIC-NEXT: .Ltmp0: # Block address taken413; X64-PIC-NEXT: .LBB5_1: # %bb0414; X64-PIC-NEXT: leaq .LBB5_1(%rip), %rsi415; X64-PIC-NEXT: cmpq %rsi, %rdx416; X64-PIC-NEXT: cmovneq %rax, %rcx417; X64-PIC-NEXT: shlq $47, %rcx418; X64-PIC-NEXT: movl $2, %eax419; X64-PIC-NEXT: orq %rcx, %rsp420; X64-PIC-NEXT: retq421; X64-PIC-NEXT: .Ltmp1: # Block address taken422; X64-PIC-NEXT: .LBB5_3: # %bb2423; X64-PIC-NEXT: leaq .LBB5_3(%rip), %rsi424; X64-PIC-NEXT: cmpq %rsi, %rdx425; X64-PIC-NEXT: cmovneq %rax, %rcx426; X64-PIC-NEXT: shlq $47, %rcx427; X64-PIC-NEXT: movl $13, %eax428; X64-PIC-NEXT: orq %rcx, %rsp429; X64-PIC-NEXT: retq430; X64-PIC-NEXT: .Ltmp2: # Block address taken431; X64-PIC-NEXT: .LBB5_4: # %bb3432; X64-PIC-NEXT: leaq .LBB5_4(%rip), %rsi433; X64-PIC-NEXT: cmpq %rsi, %rdx434; X64-PIC-NEXT: cmovneq %rax, %rcx435; X64-PIC-NEXT: shlq $47, %rcx436; X64-PIC-NEXT: movl $42, %eax437; X64-PIC-NEXT: orq %rcx, %rsp438; X64-PIC-NEXT: retq439; X64-PIC-NEXT: .Ltmp3: # Block address taken440; X64-PIC-NEXT: .LBB5_2: # %bb1441; X64-PIC-NEXT: leaq .LBB5_2(%rip), %rsi442; X64-PIC-NEXT: cmpq %rsi, %rdx443; X64-PIC-NEXT: cmovneq %rax, %rcx444; X64-PIC-NEXT: shlq $47, %rcx445; X64-PIC-NEXT: movl $7, %eax446; X64-PIC-NEXT: orq %rcx, %rsp447; X64-PIC-NEXT: retq448;449; X64-RETPOLINE-LABEL: test_indirectbr_global:450; X64-RETPOLINE: # %bb.0: # %entry451; X64-RETPOLINE-NEXT: movq %rsp, %rcx452; X64-RETPOLINE-NEXT: movq $-1, %rax453; X64-RETPOLINE-NEXT: sarq $63, %rcx454; X64-RETPOLINE-NEXT: movslq %edi, %rdx455; X64-RETPOLINE-NEXT: movq global_blockaddrs(,%rdx,8), %rdx456; X64-RETPOLINE-NEXT: orq %rcx, %rdx457; X64-RETPOLINE-NEXT: cmpq $2, %rdx458; X64-RETPOLINE-NEXT: je .LBB6_4459; X64-RETPOLINE-NEXT: # %bb.1: # %entry460; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx461; X64-RETPOLINE-NEXT: cmpq $3, %rdx462; X64-RETPOLINE-NEXT: je .LBB6_5463; X64-RETPOLINE-NEXT: # %bb.2: # %entry464; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx465; X64-RETPOLINE-NEXT: cmpq $4, %rdx466; X64-RETPOLINE-NEXT: jne .LBB6_3467; X64-RETPOLINE-NEXT: .Ltmp0: # Block address taken468; X64-RETPOLINE-NEXT: # %bb.6: # %bb3469; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx470; X64-RETPOLINE-NEXT: shlq $47, %rcx471; X64-RETPOLINE-NEXT: movl $42, %eax472; X64-RETPOLINE-NEXT: orq %rcx, %rsp473; X64-RETPOLINE-NEXT: retq474; X64-RETPOLINE-NEXT: .Ltmp1: # Block address taken475; X64-RETPOLINE-NEXT: .LBB6_5: # %bb2476; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx477; X64-RETPOLINE-NEXT: shlq $47, %rcx478; X64-RETPOLINE-NEXT: movl $13, %eax479; X64-RETPOLINE-NEXT: orq %rcx, %rsp480; X64-RETPOLINE-NEXT: retq481; X64-RETPOLINE-NEXT: .Ltmp2: # Block address taken482; X64-RETPOLINE-NEXT: .LBB6_4: # %bb1483; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx484; X64-RETPOLINE-NEXT: shlq $47, %rcx485; X64-RETPOLINE-NEXT: movl $7, %eax486; X64-RETPOLINE-NEXT: orq %rcx, %rsp487; X64-RETPOLINE-NEXT: retq488; X64-RETPOLINE-NEXT: .Ltmp3: # Block address taken489; X64-RETPOLINE-NEXT: .LBB6_3: # %bb0490; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx491; X64-RETPOLINE-NEXT: shlq $47, %rcx492; X64-RETPOLINE-NEXT: movl $2, %eax493; X64-RETPOLINE-NEXT: orq %rcx, %rsp494; X64-RETPOLINE-NEXT: retq495entry:496 %ptr = getelementptr [4 x ptr], ptr @global_blockaddrs, i32 0, i32 %idx497 %a = load ptr, ptr %ptr498 indirectbr ptr %a, [ label %bb0, label %bb1, label %bb2, label %bb3 ]499 500bb0:501 ret i32 2502 503bb1:504 ret i32 7505 506bb2:507 ret i32 13508 509bb3:510 ret i32 42511}512 513; This function's switch is crafted to trigger jump-table lowering in the x86514; 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: # %entry518; X64-NEXT: movq %rsp, %rcx519; X64-NEXT: movq $-1, %rax520; X64-NEXT: sarq $63, %rcx521; X64-NEXT: cmpl $3, %edi522; X64-NEXT: ja .LBB6_2523; X64-NEXT: # %bb.1: # %entry524; X64-NEXT: cmovaq %rax, %rcx525; X64-NEXT: movl %edi, %edx526; X64-NEXT: movq .LJTI6_0(,%rdx,8), %rdx527; X64-NEXT: orq %rcx, %rdx528; X64-NEXT: jmpq *%rdx529; X64-NEXT: .LBB6_3: # Block address taken530; X64-NEXT: # %bb1531; X64-NEXT: cmpq $.LBB6_3, %rdx532; X64-NEXT: cmovneq %rax, %rcx533; X64-NEXT: shlq $47, %rcx534; X64-NEXT: movl $7, %eax535; X64-NEXT: orq %rcx, %rsp536; X64-NEXT: retq537; X64-NEXT: .LBB6_5: # Block address taken538; X64-NEXT: # %bb3539; X64-NEXT: cmpq $.LBB6_5, %rdx540; X64-NEXT: cmovneq %rax, %rcx541; X64-NEXT: shlq $47, %rcx542; X64-NEXT: movl $42, %eax543; X64-NEXT: orq %rcx, %rsp544; X64-NEXT: retq545; X64-NEXT: .LBB6_6: # Block address taken546; X64-NEXT: # %bb5547; X64-NEXT: cmpq $.LBB6_6, %rdx548; X64-NEXT: cmovneq %rax, %rcx549; X64-NEXT: shlq $47, %rcx550; X64-NEXT: movl $11, %eax551; X64-NEXT: orq %rcx, %rsp552; X64-NEXT: retq553; X64-NEXT: .LBB6_4: # Block address taken554; X64-NEXT: # %bb2555; X64-NEXT: cmpq $.LBB6_4, %rdx556; X64-NEXT: cmovneq %rax, %rcx557; X64-NEXT: shlq $47, %rcx558; X64-NEXT: movl $13, %eax559; X64-NEXT: orq %rcx, %rsp560; X64-NEXT: retq561; X64-NEXT: .LBB6_2: # %bb0562; X64-NEXT: cmovbeq %rax, %rcx563; X64-NEXT: shlq $47, %rcx564; X64-NEXT: movl $2, %eax565; X64-NEXT: orq %rcx, %rsp566; X64-NEXT: retq567;568; X64-PIC-LABEL: test_switch_jumptable:569; X64-PIC: # %bb.0: # %entry570; X64-PIC-NEXT: movq %rsp, %rcx571; X64-PIC-NEXT: movq $-1, %rax572; X64-PIC-NEXT: sarq $63, %rcx573; X64-PIC-NEXT: cmpl $3, %edi574; X64-PIC-NEXT: ja .LBB6_2575; X64-PIC-NEXT: # %bb.1: # %entry576; X64-PIC-NEXT: cmovaq %rax, %rcx577; X64-PIC-NEXT: movl %edi, %edx578; X64-PIC-NEXT: leaq .LJTI6_0(%rip), %rsi579; X64-PIC-NEXT: movslq (%rsi,%rdx,4), %rdx580; X64-PIC-NEXT: addq %rsi, %rdx581; X64-PIC-NEXT: orq %rcx, %rdx582; X64-PIC-NEXT: jmpq *%rdx583; X64-PIC-NEXT: .LBB6_3: # Block address taken584; X64-PIC-NEXT: # %bb1585; X64-PIC-NEXT: leaq .LBB6_3(%rip), %rsi586; X64-PIC-NEXT: cmpq %rsi, %rdx587; X64-PIC-NEXT: cmovneq %rax, %rcx588; X64-PIC-NEXT: shlq $47, %rcx589; X64-PIC-NEXT: movl $7, %eax590; X64-PIC-NEXT: orq %rcx, %rsp591; X64-PIC-NEXT: retq592; X64-PIC-NEXT: .LBB6_5: # Block address taken593; X64-PIC-NEXT: # %bb3594; X64-PIC-NEXT: leaq .LBB6_5(%rip), %rsi595; X64-PIC-NEXT: cmpq %rsi, %rdx596; X64-PIC-NEXT: cmovneq %rax, %rcx597; X64-PIC-NEXT: shlq $47, %rcx598; X64-PIC-NEXT: movl $42, %eax599; X64-PIC-NEXT: orq %rcx, %rsp600; X64-PIC-NEXT: retq601; X64-PIC-NEXT: .LBB6_6: # Block address taken602; X64-PIC-NEXT: # %bb5603; X64-PIC-NEXT: leaq .LBB6_6(%rip), %rsi604; X64-PIC-NEXT: cmpq %rsi, %rdx605; X64-PIC-NEXT: cmovneq %rax, %rcx606; X64-PIC-NEXT: shlq $47, %rcx607; X64-PIC-NEXT: movl $11, %eax608; X64-PIC-NEXT: orq %rcx, %rsp609; X64-PIC-NEXT: retq610; X64-PIC-NEXT: .LBB6_4: # Block address taken611; X64-PIC-NEXT: # %bb2612; X64-PIC-NEXT: leaq .LBB6_4(%rip), %rsi613; X64-PIC-NEXT: cmpq %rsi, %rdx614; X64-PIC-NEXT: cmovneq %rax, %rcx615; X64-PIC-NEXT: shlq $47, %rcx616; X64-PIC-NEXT: movl $13, %eax617; X64-PIC-NEXT: orq %rcx, %rsp618; X64-PIC-NEXT: retq619; X64-PIC-NEXT: .LBB6_2: # %bb0620; X64-PIC-NEXT: cmovbeq %rax, %rcx621; X64-PIC-NEXT: shlq $47, %rcx622; X64-PIC-NEXT: movl $2, %eax623; X64-PIC-NEXT: orq %rcx, %rsp624; X64-PIC-NEXT: retq625;626; X64-RETPOLINE-LABEL: test_switch_jumptable:627; X64-RETPOLINE: # %bb.0: # %entry628; X64-RETPOLINE-NEXT: movq %rsp, %rcx629; X64-RETPOLINE-NEXT: movq $-1, %rax630; X64-RETPOLINE-NEXT: sarq $63, %rcx631; X64-RETPOLINE-NEXT: cmpl $1, %edi632; X64-RETPOLINE-NEXT: jg .LBB7_4633; X64-RETPOLINE-NEXT: # %bb.1: # %entry634; X64-RETPOLINE-NEXT: cmovgq %rax, %rcx635; X64-RETPOLINE-NEXT: testl %edi, %edi636; X64-RETPOLINE-NEXT: je .LBB7_7637; X64-RETPOLINE-NEXT: # %bb.2: # %entry638; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx639; X64-RETPOLINE-NEXT: cmpl $1, %edi640; X64-RETPOLINE-NEXT: jne .LBB7_6641; X64-RETPOLINE-NEXT: # %bb.3: # %bb2642; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx643; X64-RETPOLINE-NEXT: shlq $47, %rcx644; X64-RETPOLINE-NEXT: movl $13, %eax645; X64-RETPOLINE-NEXT: orq %rcx, %rsp646; X64-RETPOLINE-NEXT: retq647; X64-RETPOLINE-NEXT: .LBB7_4: # %entry648; X64-RETPOLINE-NEXT: cmovleq %rax, %rcx649; X64-RETPOLINE-NEXT: cmpl $2, %edi650; X64-RETPOLINE-NEXT: je .LBB7_8651; X64-RETPOLINE-NEXT: # %bb.5: # %entry652; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx653; X64-RETPOLINE-NEXT: cmpl $3, %edi654; X64-RETPOLINE-NEXT: jne .LBB7_6655; X64-RETPOLINE-NEXT: # %bb.9: # %bb5656; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx657; X64-RETPOLINE-NEXT: shlq $47, %rcx658; X64-RETPOLINE-NEXT: movl $11, %eax659; X64-RETPOLINE-NEXT: orq %rcx, %rsp660; X64-RETPOLINE-NEXT: retq661; X64-RETPOLINE-NEXT: .LBB7_6:662; X64-RETPOLINE-NEXT: cmoveq %rax, %rcx663; X64-RETPOLINE-NEXT: shlq $47, %rcx664; X64-RETPOLINE-NEXT: movl $2, %eax665; X64-RETPOLINE-NEXT: orq %rcx, %rsp666; X64-RETPOLINE-NEXT: retq667; X64-RETPOLINE-NEXT: .LBB7_7: # %bb1668; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx669; X64-RETPOLINE-NEXT: shlq $47, %rcx670; X64-RETPOLINE-NEXT: movl $7, %eax671; X64-RETPOLINE-NEXT: orq %rcx, %rsp672; X64-RETPOLINE-NEXT: retq673; X64-RETPOLINE-NEXT: .LBB7_8: # %bb3674; X64-RETPOLINE-NEXT: cmovneq %rax, %rcx675; X64-RETPOLINE-NEXT: shlq $47, %rcx676; X64-RETPOLINE-NEXT: movl $42, %eax677; X64-RETPOLINE-NEXT: orq %rcx, %rsp678; X64-RETPOLINE-NEXT: retq679entry:680 switch i32 %idx, label %bb0 [681 i32 0, label %bb1682 i32 1, label %bb2683 i32 2, label %bb3684 i32 3, label %bb5685 ]686 687bb0:688 ret i32 2689 690bb1:691 ret i32 7692 693bb2:694 ret i32 13695 696bb3:697 ret i32 42698 699bb5:700 ret i32 11701}702 703; This function's switch is crafted to trigger jump-table lowering in the x86704; backend so that we can test how the exact jump table lowering behaves, but705; also arranges for fallthroughs from case to case to ensure that this pattern706; 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: # %entry710; X64-NEXT: movq %rsp, %r9711; X64-NEXT: movq $-1, %r10712; X64-NEXT: sarq $63, %r9713; X64-NEXT: cmpl $3, %edi714; X64-NEXT: ja .LBB7_2715; X64-NEXT: # %bb.1: # %entry716; X64-NEXT: cmovaq %r10, %r9717; X64-NEXT: xorl %eax, %eax718; X64-NEXT: movl %edi, %esi719; X64-NEXT: movq .LJTI7_0(,%rsi,8), %rsi720; X64-NEXT: orq %r9, %rsi721; X64-NEXT: jmpq *%rsi722; X64-NEXT: .LBB7_2: # %bb0723; X64-NEXT: cmovbeq %r10, %r9724; X64-NEXT: movl (%rsi), %edi725; X64-NEXT: orl %r9d, %edi726; X64-NEXT: movq $.LBB7_3, %rsi727; X64-NEXT: .LBB7_3: # Block address taken728; X64-NEXT: # %bb1729; X64-NEXT: cmpq $.LBB7_3, %rsi730; X64-NEXT: cmovneq %r10, %r9731; X64-NEXT: addl (%rdx), %edi732; X64-NEXT: orl %r9d, %edi733; X64-NEXT: movq $.LBB7_4, %rsi734; X64-NEXT: movl %edi, %eax735; X64-NEXT: .LBB7_4: # Block address taken736; X64-NEXT: # %bb2737; X64-NEXT: cmpq $.LBB7_4, %rsi738; X64-NEXT: cmovneq %r10, %r9739; X64-NEXT: addl (%rcx), %eax740; X64-NEXT: orl %r9d, %eax741; X64-NEXT: movq $.LBB7_5, %rsi742; X64-NEXT: .LBB7_5: # Block address taken743; X64-NEXT: # %bb3744; X64-NEXT: cmpq $.LBB7_5, %rsi745; X64-NEXT: cmovneq %r10, %r9746; X64-NEXT: addl (%r8), %eax747; X64-NEXT: orl %r9d, %eax748; X64-NEXT: movq $.LBB7_6, %rsi749; X64-NEXT: .LBB7_6: # Block address taken750; X64-NEXT: # %bb4751; X64-NEXT: cmpq $.LBB7_6, %rsi752; X64-NEXT: cmovneq %r10, %r9753; X64-NEXT: shlq $47, %r9754; X64-NEXT: orq %r9, %rsp755; X64-NEXT: retq756;757; X64-PIC-LABEL: test_switch_jumptable_fallthrough:758; X64-PIC: # %bb.0: # %entry759; X64-PIC-NEXT: movq %rsp, %r9760; X64-PIC-NEXT: movq $-1, %r10761; X64-PIC-NEXT: sarq $63, %r9762; X64-PIC-NEXT: cmpl $3, %edi763; X64-PIC-NEXT: ja .LBB7_2764; X64-PIC-NEXT: # %bb.1: # %entry765; X64-PIC-NEXT: cmovaq %r10, %r9766; X64-PIC-NEXT: xorl %eax, %eax767; X64-PIC-NEXT: movl %edi, %esi768; X64-PIC-NEXT: leaq .LJTI7_0(%rip), %r11769; X64-PIC-NEXT: movslq (%r11,%rsi,4), %rsi770; X64-PIC-NEXT: addq %r11, %rsi771; X64-PIC-NEXT: orq %r9, %rsi772; X64-PIC-NEXT: jmpq *%rsi773; X64-PIC-NEXT: .LBB7_2: # %bb0774; X64-PIC-NEXT: cmovbeq %r10, %r9775; X64-PIC-NEXT: movl (%rsi), %edi776; X64-PIC-NEXT: orl %r9d, %edi777; X64-PIC-NEXT: leaq .LBB7_3(%rip), %rsi778; X64-PIC-NEXT: .LBB7_3: # Block address taken779; X64-PIC-NEXT: # %bb1780; X64-PIC-NEXT: leaq .LBB7_3(%rip), %rax781; X64-PIC-NEXT: cmpq %rax, %rsi782; X64-PIC-NEXT: cmovneq %r10, %r9783; X64-PIC-NEXT: addl (%rdx), %edi784; X64-PIC-NEXT: orl %r9d, %edi785; X64-PIC-NEXT: leaq .LBB7_4(%rip), %rsi786; X64-PIC-NEXT: movl %edi, %eax787; X64-PIC-NEXT: .LBB7_4: # Block address taken788; X64-PIC-NEXT: # %bb2789; X64-PIC-NEXT: leaq .LBB7_4(%rip), %rdx790; X64-PIC-NEXT: cmpq %rdx, %rsi791; X64-PIC-NEXT: cmovneq %r10, %r9792; X64-PIC-NEXT: addl (%rcx), %eax793; X64-PIC-NEXT: orl %r9d, %eax794; X64-PIC-NEXT: leaq .LBB7_5(%rip), %rsi795; X64-PIC-NEXT: .LBB7_5: # Block address taken796; X64-PIC-NEXT: # %bb3797; X64-PIC-NEXT: leaq .LBB7_5(%rip), %rcx798; X64-PIC-NEXT: cmpq %rcx, %rsi799; X64-PIC-NEXT: cmovneq %r10, %r9800; X64-PIC-NEXT: addl (%r8), %eax801; X64-PIC-NEXT: orl %r9d, %eax802; X64-PIC-NEXT: leaq .LBB7_6(%rip), %rsi803; X64-PIC-NEXT: .LBB7_6: # Block address taken804; X64-PIC-NEXT: # %bb4805; X64-PIC-NEXT: leaq .LBB7_6(%rip), %rcx806; X64-PIC-NEXT: cmpq %rcx, %rsi807; X64-PIC-NEXT: cmovneq %r10, %r9808; X64-PIC-NEXT: shlq $47, %r9809; X64-PIC-NEXT: orq %r9, %rsp810; X64-PIC-NEXT: retq811;812; X64-RETPOLINE-LABEL: test_switch_jumptable_fallthrough:813; X64-RETPOLINE: # %bb.0: # %entry814; X64-RETPOLINE-NEXT: movq %rsp, %r9815; X64-RETPOLINE-NEXT: movq $-1, %r10816; X64-RETPOLINE-NEXT: sarq $63, %r9817; X64-RETPOLINE-NEXT: xorl %eax, %eax818; X64-RETPOLINE-NEXT: cmpl $1, %edi819; X64-RETPOLINE-NEXT: jg .LBB8_5820; X64-RETPOLINE-NEXT: # %bb.1: # %entry821; X64-RETPOLINE-NEXT: cmovgq %r10, %r9822; X64-RETPOLINE-NEXT: testl %edi, %edi823; X64-RETPOLINE-NEXT: je .LBB8_2824; X64-RETPOLINE-NEXT: # %bb.3: # %entry825; X64-RETPOLINE-NEXT: cmoveq %r10, %r9826; X64-RETPOLINE-NEXT: cmpl $1, %edi827; X64-RETPOLINE-NEXT: jne .LBB8_8828; X64-RETPOLINE-NEXT: # %bb.4:829; X64-RETPOLINE-NEXT: cmovneq %r10, %r9830; X64-RETPOLINE-NEXT: jmp .LBB8_10831; X64-RETPOLINE-NEXT: .LBB8_5: # %entry832; X64-RETPOLINE-NEXT: cmovleq %r10, %r9833; X64-RETPOLINE-NEXT: cmpl $2, %edi834; X64-RETPOLINE-NEXT: je .LBB8_6835; X64-RETPOLINE-NEXT: # %bb.7: # %entry836; X64-RETPOLINE-NEXT: cmoveq %r10, %r9837; X64-RETPOLINE-NEXT: cmpl $3, %edi838; X64-RETPOLINE-NEXT: jne .LBB8_8839; X64-RETPOLINE-NEXT: # %bb.13:840; X64-RETPOLINE-NEXT: cmovneq %r10, %r9841; X64-RETPOLINE-NEXT: jmp .LBB8_12842; X64-RETPOLINE-NEXT: .LBB8_8:843; X64-RETPOLINE-NEXT: cmoveq %r10, %r9844; X64-RETPOLINE-NEXT: movl (%rsi), %edi845; X64-RETPOLINE-NEXT: orl %r9d, %edi846; X64-RETPOLINE-NEXT: jmp .LBB8_9847; X64-RETPOLINE-NEXT: .LBB8_2:848; X64-RETPOLINE-NEXT: cmovneq %r10, %r9849; X64-RETPOLINE-NEXT: .LBB8_9: # %bb1850; X64-RETPOLINE-NEXT: addl (%rdx), %edi851; X64-RETPOLINE-NEXT: orl %r9d, %edi852; X64-RETPOLINE-NEXT: movl %edi, %eax853; X64-RETPOLINE-NEXT: .LBB8_10: # %bb2854; X64-RETPOLINE-NEXT: addl (%rcx), %eax855; X64-RETPOLINE-NEXT: orl %r9d, %eax856; X64-RETPOLINE-NEXT: jmp .LBB8_11857; X64-RETPOLINE-NEXT: .LBB8_6:858; X64-RETPOLINE-NEXT: cmovneq %r10, %r9859; X64-RETPOLINE-NEXT: .LBB8_11: # %bb3860; X64-RETPOLINE-NEXT: addl (%r8), %eax861; X64-RETPOLINE-NEXT: orl %r9d, %eax862; X64-RETPOLINE-NEXT: .LBB8_12: # %bb4863; X64-RETPOLINE-NEXT: shlq $47, %r9864; X64-RETPOLINE-NEXT: orq %r9, %rsp865; X64-RETPOLINE-NEXT: retq866entry:867 switch i32 %idx, label %bb0 [868 i32 0, label %bb1869 i32 1, label %bb2870 i32 2, label %bb3871 i32 3, label %bb4872 ]873 874bb0:875 %a = load i32, ptr %a.ptr876 br label %bb1877 878bb1:879 %b.phi = phi i32 [ 0, %entry ], [ %a, %bb0 ]880 %b = load i32, ptr %b.ptr881 %b.sum = add i32 %b.phi, %b882 br label %bb2883 884bb2:885 %c.phi = phi i32 [ 0, %entry ], [ %b.sum, %bb1 ]886 %c = load i32, ptr %c.ptr887 %c.sum = add i32 %c.phi, %c888 br label %bb3889 890bb3:891 %d.phi = phi i32 [ 0, %entry ], [ %c.sum, %bb2 ]892 %d = load i32, ptr %d.ptr893 %d.sum = add i32 %d.phi, %d894 br label %bb4895 896bb4:897 %e.phi = phi i32 [ 0, %entry ], [ %d.sum, %bb3 ]898 ret i32 %e.phi899}900