brintos

brintos / llvm-project-archived public Read only

0
0
Text · 38.6 KiB · 5fd1f77 Raw
1195 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=X643; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -x86-slh-lfence | FileCheck %s --check-prefix=X64-LFENCE4;5; FIXME: Add support for 32-bit and other EH ABIs.6 7declare void @leak(i32 %v1, i32 %v2)8 9declare void @sink(i32)10 11define i32 @test_trivial_entry_load(ptr %ptr) speculative_load_hardening {12; X64-LABEL: test_trivial_entry_load:13; X64:       # %bb.0: # %entry14; X64-NEXT:    movq %rsp, %rcx15; X64-NEXT:    movq $-1, %rax16; X64-NEXT:    sarq $63, %rcx17; X64-NEXT:    movl (%rdi), %eax18; X64-NEXT:    orl %ecx, %eax19; X64-NEXT:    shlq $47, %rcx20; X64-NEXT:    orq %rcx, %rsp21; X64-NEXT:    retq22;23; X64-LFENCE-LABEL: test_trivial_entry_load:24; X64-LFENCE:       # %bb.0: # %entry25; X64-LFENCE-NEXT:    movl (%rdi), %eax26; X64-LFENCE-NEXT:    retq27entry:28  %v = load i32, ptr %ptr29  ret i32 %v30}31 32define void @test_basic_conditions(i32 %a, i32 %b, i32 %c, ptr %ptr1, ptr %ptr2, ptr %ptr3) speculative_load_hardening {33; X64-LABEL: test_basic_conditions:34; X64:       # %bb.0: # %entry35; X64-NEXT:    pushq %r1536; X64-NEXT:    .cfi_def_cfa_offset 1637; X64-NEXT:    pushq %r1438; X64-NEXT:    .cfi_def_cfa_offset 2439; X64-NEXT:    pushq %rbx40; X64-NEXT:    .cfi_def_cfa_offset 3241; X64-NEXT:    .cfi_offset %rbx, -3242; X64-NEXT:    .cfi_offset %r14, -2443; X64-NEXT:    .cfi_offset %r15, -1644; X64-NEXT:    movq %rsp, %rax45; X64-NEXT:    movq $-1, %rbx46; X64-NEXT:    sarq $63, %rax47; X64-NEXT:    testl %edi, %edi48; X64-NEXT:    jne .LBB1_149; X64-NEXT:  # %bb.2: # %then150; X64-NEXT:    cmovneq %rbx, %rax51; X64-NEXT:    testl %esi, %esi52; X64-NEXT:    je .LBB1_453; X64-NEXT:  .LBB1_1:54; X64-NEXT:    cmoveq %rbx, %rax55; X64-NEXT:  .LBB1_8: # %exit56; X64-NEXT:    shlq $47, %rax57; X64-NEXT:    orq %rax, %rsp58; X64-NEXT:    popq %rbx59; X64-NEXT:    .cfi_def_cfa_offset 2460; X64-NEXT:    popq %r1461; X64-NEXT:    .cfi_def_cfa_offset 1662; X64-NEXT:    popq %r1563; X64-NEXT:    .cfi_def_cfa_offset 864; X64-NEXT:    retq65; X64-NEXT:  .LBB1_4: # %then266; X64-NEXT:    .cfi_def_cfa_offset 3267; X64-NEXT:    cmovneq %rbx, %rax68; X64-NEXT:    testl %edx, %edx69; X64-NEXT:    je .LBB1_670; X64-NEXT:  # %bb.5: # %else371; X64-NEXT:    cmoveq %rbx, %rax72; X64-NEXT:    movslq (%r9), %rcx73; X64-NEXT:    orq %rax, %rcx74; X64-NEXT:    leaq (%r8,%rcx,4), %r1475; X64-NEXT:    movl %ecx, (%r8,%rcx,4)76; X64-NEXT:    jmp .LBB1_777; X64-NEXT:  .LBB1_6: # %then378; X64-NEXT:    cmovneq %rbx, %rax79; X64-NEXT:    movl (%rcx), %ecx80; X64-NEXT:    addl (%r8), %ecx81; X64-NEXT:    movslq %ecx, %rdi82; X64-NEXT:    orq %rax, %rdi83; X64-NEXT:    movl (%r8,%rdi,4), %esi84; X64-NEXT:    orl %eax, %esi85; X64-NEXT:    movq (%r9), %r1486; X64-NEXT:    orq %rax, %r1487; X64-NEXT:    addl (%r14), %esi88; X64-NEXT:    shlq $47, %rax89; X64-NEXT:    # kill: def $edi killed $edi killed $rdi90; X64-NEXT:    orq %rax, %rsp91; X64-NEXT:    movq %r8, %r1592; X64-NEXT:    callq leak@PLT93; X64-NEXT:  .Lslh_ret_addr0:94; X64-NEXT:    movq %r15, %r895; X64-NEXT:    movq %rsp, %rax96; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx97; X64-NEXT:    sarq $63, %rax98; X64-NEXT:    cmpq $.Lslh_ret_addr0, %rcx99; X64-NEXT:    cmovneq %rbx, %rax100; X64-NEXT:  .LBB1_7: # %merge101; X64-NEXT:    movslq (%r14), %rcx102; X64-NEXT:    orq %rax, %rcx103; X64-NEXT:    movl $0, (%r8,%rcx,4)104; X64-NEXT:    jmp .LBB1_8105;106; X64-LFENCE-LABEL: test_basic_conditions:107; X64-LFENCE:       # %bb.0: # %entry108; X64-LFENCE-NEXT:    pushq %r14109; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 16110; X64-LFENCE-NEXT:    pushq %rbx111; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 24112; X64-LFENCE-NEXT:    pushq %rax113; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 32114; X64-LFENCE-NEXT:    .cfi_offset %rbx, -24115; X64-LFENCE-NEXT:    .cfi_offset %r14, -16116; X64-LFENCE-NEXT:    testl %edi, %edi117; X64-LFENCE-NEXT:    jne .LBB1_6118; X64-LFENCE-NEXT:  # %bb.1: # %then1119; X64-LFENCE-NEXT:    lfence120; X64-LFENCE-NEXT:    testl %esi, %esi121; X64-LFENCE-NEXT:    jne .LBB1_6122; X64-LFENCE-NEXT:  # %bb.2: # %then2123; X64-LFENCE-NEXT:    lfence124; X64-LFENCE-NEXT:    testl %edx, %edx125; X64-LFENCE-NEXT:    je .LBB1_3126; X64-LFENCE-NEXT:  # %bb.4: # %else3127; X64-LFENCE-NEXT:    lfence128; X64-LFENCE-NEXT:    movslq (%r9), %rax129; X64-LFENCE-NEXT:    leaq (%r8,%rax,4), %rbx130; X64-LFENCE-NEXT:    movl %eax, (%r8,%rax,4)131; X64-LFENCE-NEXT:    jmp .LBB1_5132; X64-LFENCE-NEXT:  .LBB1_3: # %then3133; X64-LFENCE-NEXT:    lfence134; X64-LFENCE-NEXT:    movl (%rcx), %eax135; X64-LFENCE-NEXT:    addl (%r8), %eax136; X64-LFENCE-NEXT:    movslq %eax, %rdi137; X64-LFENCE-NEXT:    movl (%r8,%rdi,4), %esi138; X64-LFENCE-NEXT:    movq (%r9), %rbx139; X64-LFENCE-NEXT:    addl (%rbx), %esi140; X64-LFENCE-NEXT:    # kill: def $edi killed $edi killed $rdi141; X64-LFENCE-NEXT:    movq %r8, %r14142; X64-LFENCE-NEXT:    callq leak@PLT143; X64-LFENCE-NEXT:    movq %r14, %r8144; X64-LFENCE-NEXT:  .LBB1_5: # %merge145; X64-LFENCE-NEXT:    movslq (%rbx), %rax146; X64-LFENCE-NEXT:    movl $0, (%r8,%rax,4)147; X64-LFENCE-NEXT:  .LBB1_6: # %exit148; X64-LFENCE-NEXT:    lfence149; X64-LFENCE-NEXT:    addq $8, %rsp150; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 24151; X64-LFENCE-NEXT:    popq %rbx152; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 16153; X64-LFENCE-NEXT:    popq %r14154; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 8155; X64-LFENCE-NEXT:    retq156entry:157  %a.cmp = icmp eq i32 %a, 0158  br i1 %a.cmp, label %then1, label %exit159 160then1:161  %b.cmp = icmp eq i32 %b, 0162  br i1 %b.cmp, label %then2, label %exit163 164then2:165  %c.cmp = icmp eq i32 %c, 0166  br i1 %c.cmp, label %then3, label %else3167 168then3:169  %secret1 = load i32, ptr %ptr1170  %secret2 = load i32, ptr %ptr2171  %secret.sum1 = add i32 %secret1, %secret2172  %ptr2.idx = getelementptr i32, ptr %ptr2, i32 %secret.sum1173  %secret3 = load i32, ptr %ptr2.idx174  %secret4 = load ptr, ptr %ptr3175  %secret5 = load i32, ptr %secret4176  %secret.sum2 = add i32 %secret3, %secret5177  call void @leak(i32 %secret.sum1, i32 %secret.sum2)178  br label %merge179 180else3:181  %secret6 = load ptr, ptr %ptr3182  %cast = ptrtoint ptr %secret6 to i32183  %ptr2.idx2 = getelementptr i32, ptr %ptr2, i32 %cast184  store i32 %cast, ptr %ptr2.idx2185  br label %merge186 187merge:188  %phi = phi ptr [ %secret4, %then3 ], [ %ptr2.idx2, %else3 ]189  %secret7 = load i32, ptr %phi190  %ptr2.idx3 = getelementptr i32, ptr %ptr2, i32 %secret7191  store i32 0, ptr %ptr2.idx3192  br label %exit193 194exit:195  ret void196}197 198define void @test_basic_loop(i32 %a, i32 %b, ptr %ptr1, ptr %ptr2) nounwind speculative_load_hardening {199; X64-LABEL: test_basic_loop:200; X64:       # %bb.0: # %entry201; X64-NEXT:    pushq %rbp202; X64-NEXT:    pushq %r15203; X64-NEXT:    pushq %r14204; X64-NEXT:    pushq %r12205; X64-NEXT:    pushq %rbx206; X64-NEXT:    movq %rsp, %rax207; X64-NEXT:    movq $-1, %r15208; X64-NEXT:    sarq $63, %rax209; X64-NEXT:    testl %edi, %edi210; X64-NEXT:    je .LBB2_2211; X64-NEXT:  # %bb.1:212; X64-NEXT:    cmoveq %r15, %rax213; X64-NEXT:    jmp .LBB2_5214; X64-NEXT:  .LBB2_2: # %l.header.preheader215; X64-NEXT:    movq %rcx, %rbx216; X64-NEXT:    movq %rdx, %r14217; X64-NEXT:    movl %esi, %ebp218; X64-NEXT:    cmovneq %r15, %rax219; X64-NEXT:    xorl %r12d, %r12d220; X64-NEXT:    .p2align 4221; X64-NEXT:  .LBB2_3: # %l.header222; X64-NEXT:    # =>This Inner Loop Header: Depth=1223; X64-NEXT:    movslq (%r14), %rcx224; X64-NEXT:    orq %rax, %rcx225; X64-NEXT:    movq %rax, %rdx226; X64-NEXT:    orq %rbx, %rdx227; X64-NEXT:    movl (%rdx,%rcx,4), %edi228; X64-NEXT:    shlq $47, %rax229; X64-NEXT:    orq %rax, %rsp230; X64-NEXT:    callq sink@PLT231; X64-NEXT:  .Lslh_ret_addr1:232; X64-NEXT:    movq %rsp, %rax233; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx234; X64-NEXT:    sarq $63, %rax235; X64-NEXT:    cmpq $.Lslh_ret_addr1, %rcx236; X64-NEXT:    cmovneq %r15, %rax237; X64-NEXT:    incl %r12d238; X64-NEXT:    cmpl %ebp, %r12d239; X64-NEXT:    jge .LBB2_4240; X64-NEXT:  # %bb.6: # in Loop: Header=BB2_3 Depth=1241; X64-NEXT:    cmovgeq %r15, %rax242; X64-NEXT:    jmp .LBB2_3243; X64-NEXT:  .LBB2_4:244; X64-NEXT:    cmovlq %r15, %rax245; X64-NEXT:  .LBB2_5: # %exit246; X64-NEXT:    shlq $47, %rax247; X64-NEXT:    orq %rax, %rsp248; X64-NEXT:    popq %rbx249; X64-NEXT:    popq %r12250; X64-NEXT:    popq %r14251; X64-NEXT:    popq %r15252; X64-NEXT:    popq %rbp253; X64-NEXT:    retq254;255; X64-LFENCE-LABEL: test_basic_loop:256; X64-LFENCE:       # %bb.0: # %entry257; X64-LFENCE-NEXT:    pushq %rbp258; X64-LFENCE-NEXT:    pushq %r15259; X64-LFENCE-NEXT:    pushq %r14260; X64-LFENCE-NEXT:    pushq %rbx261; X64-LFENCE-NEXT:    pushq %rax262; X64-LFENCE-NEXT:    testl %edi, %edi263; X64-LFENCE-NEXT:    jne .LBB2_3264; X64-LFENCE-NEXT:  # %bb.1: # %l.header.preheader265; X64-LFENCE-NEXT:    movq %rcx, %rbx266; X64-LFENCE-NEXT:    movq %rdx, %r14267; X64-LFENCE-NEXT:    movl %esi, %ebp268; X64-LFENCE-NEXT:    lfence269; X64-LFENCE-NEXT:    xorl %r15d, %r15d270; X64-LFENCE-NEXT:    .p2align 4271; X64-LFENCE-NEXT:  .LBB2_2: # %l.header272; X64-LFENCE-NEXT:    # =>This Inner Loop Header: Depth=1273; X64-LFENCE-NEXT:    lfence274; X64-LFENCE-NEXT:    movslq (%r14), %rax275; X64-LFENCE-NEXT:    movl (%rbx,%rax,4), %edi276; X64-LFENCE-NEXT:    callq sink@PLT277; X64-LFENCE-NEXT:    incl %r15d278; X64-LFENCE-NEXT:    cmpl %ebp, %r15d279; X64-LFENCE-NEXT:    jl .LBB2_2280; X64-LFENCE-NEXT:  .LBB2_3: # %exit281; X64-LFENCE-NEXT:    lfence282; X64-LFENCE-NEXT:    addq $8, %rsp283; X64-LFENCE-NEXT:    popq %rbx284; X64-LFENCE-NEXT:    popq %r14285; X64-LFENCE-NEXT:    popq %r15286; X64-LFENCE-NEXT:    popq %rbp287; X64-LFENCE-NEXT:    retq288entry:289  %a.cmp = icmp eq i32 %a, 0290  br i1 %a.cmp, label %l.header, label %exit291 292l.header:293  %i = phi i32 [ 0, %entry ], [ %i.next, %l.header ]294  %secret = load i32, ptr %ptr1295  %ptr2.idx = getelementptr i32, ptr %ptr2, i32 %secret296  %leak = load i32, ptr %ptr2.idx297  call void @sink(i32 %leak)298  %i.next = add i32 %i, 1299  %i.cmp = icmp slt i32 %i.next, %b300  br i1 %i.cmp, label %l.header, label %exit301 302exit:303  ret void304}305 306define void @test_basic_nested_loop(i32 %a, i32 %b, i32 %c, ptr %ptr1, ptr %ptr2) nounwind speculative_load_hardening {307; X64-LABEL: test_basic_nested_loop:308; X64:       # %bb.0: # %entry309; X64-NEXT:    pushq %rbp310; X64-NEXT:    pushq %r15311; X64-NEXT:    pushq %r14312; X64-NEXT:    pushq %r13313; X64-NEXT:    pushq %r12314; X64-NEXT:    pushq %rbx315; X64-NEXT:    pushq %rax316; X64-NEXT:    movq %rsp, %rax317; X64-NEXT:    movq $-1, %r12318; X64-NEXT:    sarq $63, %rax319; X64-NEXT:    testl %edi, %edi320; X64-NEXT:    je .LBB3_2321; X64-NEXT:  # %bb.1:322; X64-NEXT:    cmoveq %r12, %rax323; X64-NEXT:    jmp .LBB3_10324; X64-NEXT:  .LBB3_2: # %l1.header.preheader325; X64-NEXT:    movq %r8, %rbx326; X64-NEXT:    movq %rcx, %r14327; X64-NEXT:    movl %edx, %ebp328; X64-NEXT:    movl %esi, %r15d329; X64-NEXT:    cmovneq %r12, %rax330; X64-NEXT:    xorl %r13d, %r13d331; X64-NEXT:    movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill332; X64-NEXT:    testl %r15d, %r15d333; X64-NEXT:    jle .LBB3_4334; X64-NEXT:    .p2align 4335; X64-NEXT:  .LBB3_5: # %l2.header.preheader336; X64-NEXT:    cmovleq %r12, %rax337; X64-NEXT:    xorl %r15d, %r15d338; X64-NEXT:    .p2align 4339; X64-NEXT:  .LBB3_6: # %l2.header340; X64-NEXT:    # =>This Inner Loop Header: Depth=1341; X64-NEXT:    movslq (%r14), %rcx342; X64-NEXT:    orq %rax, %rcx343; X64-NEXT:    movq %rax, %rdx344; X64-NEXT:    orq %rbx, %rdx345; X64-NEXT:    movl (%rdx,%rcx,4), %edi346; X64-NEXT:    shlq $47, %rax347; X64-NEXT:    orq %rax, %rsp348; X64-NEXT:    callq sink@PLT349; X64-NEXT:  .Lslh_ret_addr2:350; X64-NEXT:    movq %rsp, %rax351; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx352; X64-NEXT:    sarq $63, %rax353; X64-NEXT:    cmpq $.Lslh_ret_addr2, %rcx354; X64-NEXT:    cmovneq %r12, %rax355; X64-NEXT:    incl %r15d356; X64-NEXT:    cmpl %ebp, %r15d357; X64-NEXT:    jge .LBB3_7358; X64-NEXT:  # %bb.11: # in Loop: Header=BB3_6 Depth=1359; X64-NEXT:    cmovgeq %r12, %rax360; X64-NEXT:    jmp .LBB3_6361; X64-NEXT:    .p2align 4362; X64-NEXT:  .LBB3_7:363; X64-NEXT:    cmovlq %r12, %rax364; X64-NEXT:    movl {{[-0-9]+}}(%r{{[sb]}}p), %r15d # 4-byte Reload365; X64-NEXT:    jmp .LBB3_8366; X64-NEXT:    .p2align 4367; X64-NEXT:  .LBB3_4:368; X64-NEXT:    cmovgq %r12, %rax369; X64-NEXT:  .LBB3_8: # %l1.latch370; X64-NEXT:    movslq (%r14), %rcx371; X64-NEXT:    orq %rax, %rcx372; X64-NEXT:    movq %rax, %rdx373; X64-NEXT:    orq %rbx, %rdx374; X64-NEXT:    movl (%rdx,%rcx,4), %edi375; X64-NEXT:    shlq $47, %rax376; X64-NEXT:    orq %rax, %rsp377; X64-NEXT:    callq sink@PLT378; X64-NEXT:  .Lslh_ret_addr3:379; X64-NEXT:    movq %rsp, %rax380; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx381; X64-NEXT:    sarq $63, %rax382; X64-NEXT:    cmpq $.Lslh_ret_addr3, %rcx383; X64-NEXT:    cmovneq %r12, %rax384; X64-NEXT:    incl %r13d385; X64-NEXT:    cmpl %r15d, %r13d386; X64-NEXT:    jge .LBB3_9387; X64-NEXT:  # %bb.12:388; X64-NEXT:    cmovgeq %r12, %rax389; X64-NEXT:    testl %r15d, %r15d390; X64-NEXT:    jg .LBB3_5391; X64-NEXT:    jmp .LBB3_4392; X64-NEXT:  .LBB3_9:393; X64-NEXT:    cmovlq %r12, %rax394; X64-NEXT:  .LBB3_10: # %exit395; X64-NEXT:    shlq $47, %rax396; X64-NEXT:    orq %rax, %rsp397; X64-NEXT:    addq $8, %rsp398; X64-NEXT:    popq %rbx399; X64-NEXT:    popq %r12400; X64-NEXT:    popq %r13401; X64-NEXT:    popq %r14402; X64-NEXT:    popq %r15403; X64-NEXT:    popq %rbp404; X64-NEXT:    retq405;406; X64-LFENCE-LABEL: test_basic_nested_loop:407; X64-LFENCE:       # %bb.0: # %entry408; X64-LFENCE-NEXT:    pushq %rbp409; X64-LFENCE-NEXT:    pushq %r15410; X64-LFENCE-NEXT:    pushq %r14411; X64-LFENCE-NEXT:    pushq %r13412; X64-LFENCE-NEXT:    pushq %r12413; X64-LFENCE-NEXT:    pushq %rbx414; X64-LFENCE-NEXT:    pushq %rax415; X64-LFENCE-NEXT:    testl %edi, %edi416; X64-LFENCE-NEXT:    je .LBB3_1417; X64-LFENCE-NEXT:  .LBB3_6: # %exit418; X64-LFENCE-NEXT:    lfence419; X64-LFENCE-NEXT:    addq $8, %rsp420; X64-LFENCE-NEXT:    popq %rbx421; X64-LFENCE-NEXT:    popq %r12422; X64-LFENCE-NEXT:    popq %r13423; X64-LFENCE-NEXT:    popq %r14424; X64-LFENCE-NEXT:    popq %r15425; X64-LFENCE-NEXT:    popq %rbp426; X64-LFENCE-NEXT:    retq427; X64-LFENCE-NEXT:  .LBB3_1: # %l1.header.preheader428; X64-LFENCE-NEXT:    movq %r8, %rbx429; X64-LFENCE-NEXT:    movq %rcx, %r14430; X64-LFENCE-NEXT:    movl %edx, %ebp431; X64-LFENCE-NEXT:    movl %esi, %r15d432; X64-LFENCE-NEXT:    lfence433; X64-LFENCE-NEXT:    xorl %r12d, %r12d434; X64-LFENCE-NEXT:    jmp .LBB3_2435; X64-LFENCE-NEXT:    .p2align 4436; X64-LFENCE-NEXT:  .LBB3_5: # %l1.latch437; X64-LFENCE-NEXT:    # in Loop: Header=BB3_2 Depth=1438; X64-LFENCE-NEXT:    lfence439; X64-LFENCE-NEXT:    movslq (%r14), %rax440; X64-LFENCE-NEXT:    movl (%rbx,%rax,4), %edi441; X64-LFENCE-NEXT:    callq sink@PLT442; X64-LFENCE-NEXT:    incl %r12d443; X64-LFENCE-NEXT:    cmpl %r15d, %r12d444; X64-LFENCE-NEXT:    jge .LBB3_6445; X64-LFENCE-NEXT:  .LBB3_2: # %l1.header446; X64-LFENCE-NEXT:    # =>This Loop Header: Depth=1447; X64-LFENCE-NEXT:    # Child Loop BB3_4 Depth 2448; X64-LFENCE-NEXT:    lfence449; X64-LFENCE-NEXT:    testl %r15d, %r15d450; X64-LFENCE-NEXT:    jle .LBB3_5451; X64-LFENCE-NEXT:  # %bb.3: # %l2.header.preheader452; X64-LFENCE-NEXT:    # in Loop: Header=BB3_2 Depth=1453; X64-LFENCE-NEXT:    lfence454; X64-LFENCE-NEXT:    xorl %r13d, %r13d455; X64-LFENCE-NEXT:    .p2align 4456; X64-LFENCE-NEXT:  .LBB3_4: # %l2.header457; X64-LFENCE-NEXT:    # Parent Loop BB3_2 Depth=1458; X64-LFENCE-NEXT:    # => This Inner Loop Header: Depth=2459; X64-LFENCE-NEXT:    lfence460; X64-LFENCE-NEXT:    movslq (%r14), %rax461; X64-LFENCE-NEXT:    movl (%rbx,%rax,4), %edi462; X64-LFENCE-NEXT:    callq sink@PLT463; X64-LFENCE-NEXT:    incl %r13d464; X64-LFENCE-NEXT:    cmpl %ebp, %r13d465; X64-LFENCE-NEXT:    jl .LBB3_4466; X64-LFENCE-NEXT:    jmp .LBB3_5467entry:468  %a.cmp = icmp eq i32 %a, 0469  br i1 %a.cmp, label %l1.header, label %exit470 471l1.header:472  %i = phi i32 [ 0, %entry ], [ %i.next, %l1.latch ]473  %b.cmp = icmp sgt i32 %b, 0474  br i1 %b.cmp, label %l2.header, label %l1.latch475 476l2.header:477  %j = phi i32 [ 0, %l1.header ], [ %j.next, %l2.header ]478  %secret = load i32, ptr %ptr1479  %ptr2.idx = getelementptr i32, ptr %ptr2, i32 %secret480  %leak = load i32, ptr %ptr2.idx481  call void @sink(i32 %leak)482  %j.next = add i32 %j, 1483  %j.cmp = icmp slt i32 %j.next, %c484  br i1 %j.cmp, label %l2.header, label %l1.latch485 486l1.latch:487  %secret2 = load i32, ptr %ptr1488  %ptr2.idx2 = getelementptr i32, ptr %ptr2, i32 %secret2489  %leak2 = load i32, ptr %ptr2.idx2490  call void @sink(i32 %leak2)491  %i.next = add i32 %i, 1492  %i.cmp = icmp slt i32 %i.next, %b493  br i1 %i.cmp, label %l1.header, label %exit494 495exit:496  ret void497}498 499declare i32 @__gxx_personality_v0(...)500 501declare ptr @__cxa_allocate_exception(i64) local_unnamed_addr502 503declare void @__cxa_throw(ptr, ptr, ptr) local_unnamed_addr504 505define void @test_basic_eh(i32 %a, ptr %ptr1, ptr %ptr2) speculative_load_hardening personality ptr @__gxx_personality_v0 {506; X64-LABEL: test_basic_eh:507; X64:       # %bb.0: # %entry508; X64-NEXT:    pushq %rbp509; X64-NEXT:    .cfi_def_cfa_offset 16510; X64-NEXT:    pushq %r15511; X64-NEXT:    .cfi_def_cfa_offset 24512; X64-NEXT:    pushq %r14513; X64-NEXT:    .cfi_def_cfa_offset 32514; X64-NEXT:    pushq %rbx515; X64-NEXT:    .cfi_def_cfa_offset 40516; X64-NEXT:    pushq %rax517; X64-NEXT:    .cfi_def_cfa_offset 48518; X64-NEXT:    .cfi_offset %rbx, -40519; X64-NEXT:    .cfi_offset %r14, -32520; X64-NEXT:    .cfi_offset %r15, -24521; X64-NEXT:    .cfi_offset %rbp, -16522; X64-NEXT:    movq %rsp, %rax523; X64-NEXT:    movq $-1, %rbx524; X64-NEXT:    sarq $63, %rax525; X64-NEXT:    cmpl $41, %edi526; X64-NEXT:    jg .LBB4_1527; X64-NEXT:  # %bb.2: # %thrower528; X64-NEXT:    movq %rdx, %r14529; X64-NEXT:    cmovgq %rbx, %rax530; X64-NEXT:    movslq %edi, %rcx531; X64-NEXT:    movq %rsi, %r15532; X64-NEXT:    movl (%rsi,%rcx,4), %ebp533; X64-NEXT:    orl %eax, %ebp534; X64-NEXT:    movl $4, %edi535; X64-NEXT:    shlq $47, %rax536; X64-NEXT:    orq %rax, %rsp537; X64-NEXT:    callq __cxa_allocate_exception@PLT538; X64-NEXT:  .Lslh_ret_addr4:539; X64-NEXT:    movq %rsp, %rcx540; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rdx541; X64-NEXT:    sarq $63, %rcx542; X64-NEXT:    cmpq $.Lslh_ret_addr4, %rdx543; X64-NEXT:    cmovneq %rbx, %rcx544; X64-NEXT:    movl %ebp, (%rax)545; X64-NEXT:  .Ltmp0:546; X64-NEXT:    shlq $47, %rcx547; X64-NEXT:    movq %rax, %rdi548; X64-NEXT:    xorl %esi, %esi549; X64-NEXT:    xorl %edx, %edx550; X64-NEXT:    orq %rcx, %rsp551; X64-NEXT:    callq __cxa_throw@PLT552; X64-NEXT:  .Lslh_ret_addr5:553; X64-NEXT:    movq %rsp, %rax554; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx555; X64-NEXT:    sarq $63, %rax556; X64-NEXT:    cmpq $.Lslh_ret_addr5, %rcx557; X64-NEXT:    cmovneq %rbx, %rax558; X64-NEXT:  .Ltmp1:559; X64-NEXT:    jmp .LBB4_3560; X64-NEXT:  .LBB4_1:561; X64-NEXT:    cmovleq %rbx, %rax562; X64-NEXT:  .LBB4_3: # %exit563; X64-NEXT:    shlq $47, %rax564; X64-NEXT:    orq %rax, %rsp565; X64-NEXT:    addq $8, %rsp566; X64-NEXT:    .cfi_def_cfa_offset 40567; X64-NEXT:    popq %rbx568; X64-NEXT:    .cfi_def_cfa_offset 32569; X64-NEXT:    popq %r14570; X64-NEXT:    .cfi_def_cfa_offset 24571; X64-NEXT:    popq %r15572; X64-NEXT:    .cfi_def_cfa_offset 16573; X64-NEXT:    popq %rbp574; X64-NEXT:    .cfi_def_cfa_offset 8575; X64-NEXT:    retq576; X64-NEXT:  .LBB4_4: # %lpad577; X64-NEXT:    .cfi_def_cfa_offset 48578; X64-NEXT:  .Ltmp2:579; X64-NEXT:    movq %rsp, %rcx580; X64-NEXT:    sarq $63, %rcx581; X64-NEXT:    movl (%rax), %eax582; X64-NEXT:    addl (%r15), %eax583; X64-NEXT:    cltq584; X64-NEXT:    orq %rcx, %rax585; X64-NEXT:    movl (%r14,%rax,4), %edi586; X64-NEXT:    orl %ecx, %edi587; X64-NEXT:    shlq $47, %rcx588; X64-NEXT:    orq %rcx, %rsp589; X64-NEXT:    callq sink@PLT590; X64-NEXT:  .Lslh_ret_addr6:591; X64-NEXT:    movq %rsp, %rax592; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx593; X64-NEXT:    sarq $63, %rax594; X64-NEXT:    cmpq $.Lslh_ret_addr6, %rcx595; X64-NEXT:    cmovneq %rbx, %rax596;597; X64-LFENCE-LABEL: test_basic_eh:598; X64-LFENCE:       # %bb.0: # %entry599; X64-LFENCE-NEXT:    pushq %rbp600; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 16601; X64-LFENCE-NEXT:    pushq %r14602; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 24603; X64-LFENCE-NEXT:    pushq %rbx604; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 32605; X64-LFENCE-NEXT:    .cfi_offset %rbx, -32606; X64-LFENCE-NEXT:    .cfi_offset %r14, -24607; X64-LFENCE-NEXT:    .cfi_offset %rbp, -16608; X64-LFENCE-NEXT:    cmpl $41, %edi609; X64-LFENCE-NEXT:    jg .LBB4_2610; X64-LFENCE-NEXT:  # %bb.1: # %thrower611; X64-LFENCE-NEXT:    movq %rdx, %rbx612; X64-LFENCE-NEXT:    movq %rsi, %r14613; X64-LFENCE-NEXT:    lfence614; X64-LFENCE-NEXT:    movslq %edi, %rax615; X64-LFENCE-NEXT:    movl (%rsi,%rax,4), %ebp616; X64-LFENCE-NEXT:    movl $4, %edi617; X64-LFENCE-NEXT:    callq __cxa_allocate_exception@PLT618; X64-LFENCE-NEXT:    movl %ebp, (%rax)619; X64-LFENCE-NEXT:  .Ltmp0:620; X64-LFENCE-NEXT:    movq %rax, %rdi621; X64-LFENCE-NEXT:    xorl %esi, %esi622; X64-LFENCE-NEXT:    xorl %edx, %edx623; X64-LFENCE-NEXT:    callq __cxa_throw@PLT624; X64-LFENCE-NEXT:  .Ltmp1:625; X64-LFENCE-NEXT:  .LBB4_2: # %exit626; X64-LFENCE-NEXT:    lfence627; X64-LFENCE-NEXT:    popq %rbx628; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 24629; X64-LFENCE-NEXT:    popq %r14630; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 16631; X64-LFENCE-NEXT:    popq %rbp632; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 8633; X64-LFENCE-NEXT:    retq634; X64-LFENCE-NEXT:  .LBB4_3: # %lpad635; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 32636; X64-LFENCE-NEXT:  .Ltmp2:637; X64-LFENCE-NEXT:    movl (%rax), %eax638; X64-LFENCE-NEXT:    addl (%r14), %eax639; X64-LFENCE-NEXT:    cltq640; X64-LFENCE-NEXT:    movl (%rbx,%rax,4), %edi641; X64-LFENCE-NEXT:    callq sink@PLT642entry:643  %a.cmp = icmp slt i32 %a, 42644  br i1 %a.cmp, label %thrower, label %exit645 646thrower:647  %badidx = getelementptr i32, ptr %ptr1, i32 %a648  %secret1 = load i32, ptr %badidx649  %e.ptr = call ptr @__cxa_allocate_exception(i64 4)650  store i32 %secret1, ptr %e.ptr651  invoke void @__cxa_throw(ptr %e.ptr, ptr null, ptr null)652          to label %exit unwind label %lpad653 654exit:655  ret void656 657lpad:658  %e = landingpad { ptr, i32 }659          catch ptr null660  %e.catch.ptr = extractvalue { ptr, i32 } %e, 0661  %secret1.catch = load i32, ptr %e.catch.ptr662  %secret2 = load i32, ptr %ptr1663  %secret.sum = add i32 %secret1.catch, %secret2664  %ptr2.idx = getelementptr i32, ptr %ptr2, i32 %secret.sum665  %leak = load i32, ptr %ptr2.idx666  call void @sink(i32 %leak)667  unreachable668}669 670declare void @sink_float(float)671declare void @sink_double(double)672 673; Test direct and converting loads of floating point values.674define void @test_fp_loads(ptr %fptr, ptr %dptr, ptr %i32ptr, ptr %i64ptr) nounwind speculative_load_hardening {675; X64-LABEL: test_fp_loads:676; X64:       # %bb.0: # %entry677; X64-NEXT:    pushq %r15678; X64-NEXT:    pushq %r14679; X64-NEXT:    pushq %r13680; X64-NEXT:    pushq %r12681; X64-NEXT:    pushq %rbx682; X64-NEXT:    movq %rsp, %rax683; X64-NEXT:    movq %rcx, %r14684; X64-NEXT:    movq %rdx, %rbx685; X64-NEXT:    movq %rsi, %r12686; X64-NEXT:    movq %rdi, %r15687; X64-NEXT:    movq $-1, %r13688; X64-NEXT:    sarq $63, %rax689; X64-NEXT:    orq %rax, %r15690; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero691; X64-NEXT:    shlq $47, %rax692; X64-NEXT:    orq %rax, %rsp693; X64-NEXT:    callq sink_float@PLT694; X64-NEXT:  .Lslh_ret_addr7:695; X64-NEXT:    movq %rsp, %rax696; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx697; X64-NEXT:    sarq $63, %rax698; X64-NEXT:    cmpq $.Lslh_ret_addr7, %rcx699; X64-NEXT:    cmovneq %r13, %rax700; X64-NEXT:    orq %rax, %r12701; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero702; X64-NEXT:    shlq $47, %rax703; X64-NEXT:    orq %rax, %rsp704; X64-NEXT:    callq sink_double@PLT705; X64-NEXT:  .Lslh_ret_addr8:706; X64-NEXT:    movq %rsp, %rax707; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx708; X64-NEXT:    sarq $63, %rax709; X64-NEXT:    cmpq $.Lslh_ret_addr8, %rcx710; X64-NEXT:    cmovneq %r13, %rax711; X64-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero712; X64-NEXT:    cvtsd2ss %xmm0, %xmm0713; X64-NEXT:    shlq $47, %rax714; X64-NEXT:    orq %rax, %rsp715; X64-NEXT:    callq sink_float@PLT716; X64-NEXT:  .Lslh_ret_addr9:717; X64-NEXT:    movq %rsp, %rax718; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx719; X64-NEXT:    sarq $63, %rax720; X64-NEXT:    cmpq $.Lslh_ret_addr9, %rcx721; X64-NEXT:    cmovneq %r13, %rax722; X64-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero723; X64-NEXT:    cvtss2sd %xmm0, %xmm0724; X64-NEXT:    shlq $47, %rax725; X64-NEXT:    orq %rax, %rsp726; X64-NEXT:    callq sink_double@PLT727; X64-NEXT:  .Lslh_ret_addr10:728; X64-NEXT:    movq %rsp, %rax729; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx730; X64-NEXT:    sarq $63, %rax731; X64-NEXT:    cmpq $.Lslh_ret_addr10, %rcx732; X64-NEXT:    cmovneq %r13, %rax733; X64-NEXT:    orq %rax, %rbx734; X64-NEXT:    xorps %xmm0, %xmm0735; X64-NEXT:    cvtsi2ssl (%rbx), %xmm0736; X64-NEXT:    shlq $47, %rax737; X64-NEXT:    orq %rax, %rsp738; X64-NEXT:    callq sink_float@PLT739; X64-NEXT:  .Lslh_ret_addr11:740; X64-NEXT:    movq %rsp, %rax741; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx742; X64-NEXT:    sarq $63, %rax743; X64-NEXT:    cmpq $.Lslh_ret_addr11, %rcx744; X64-NEXT:    cmovneq %r13, %rax745; X64-NEXT:    orq %rax, %r14746; X64-NEXT:    xorps %xmm0, %xmm0747; X64-NEXT:    cvtsi2sdq (%r14), %xmm0748; X64-NEXT:    shlq $47, %rax749; X64-NEXT:    orq %rax, %rsp750; X64-NEXT:    callq sink_double@PLT751; X64-NEXT:  .Lslh_ret_addr12:752; X64-NEXT:    movq %rsp, %rax753; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx754; X64-NEXT:    sarq $63, %rax755; X64-NEXT:    cmpq $.Lslh_ret_addr12, %rcx756; X64-NEXT:    cmovneq %r13, %rax757; X64-NEXT:    xorps %xmm0, %xmm0758; X64-NEXT:    cvtsi2ssq (%r14), %xmm0759; X64-NEXT:    shlq $47, %rax760; X64-NEXT:    orq %rax, %rsp761; X64-NEXT:    callq sink_float@PLT762; X64-NEXT:  .Lslh_ret_addr13:763; X64-NEXT:    movq %rsp, %rax764; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx765; X64-NEXT:    sarq $63, %rax766; X64-NEXT:    cmpq $.Lslh_ret_addr13, %rcx767; X64-NEXT:    cmovneq %r13, %rax768; X64-NEXT:    xorps %xmm0, %xmm0769; X64-NEXT:    cvtsi2sdl (%rbx), %xmm0770; X64-NEXT:    shlq $47, %rax771; X64-NEXT:    orq %rax, %rsp772; X64-NEXT:    callq sink_double@PLT773; X64-NEXT:  .Lslh_ret_addr14:774; X64-NEXT:    movq %rsp, %rax775; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx776; X64-NEXT:    sarq $63, %rax777; X64-NEXT:    cmpq $.Lslh_ret_addr14, %rcx778; X64-NEXT:    cmovneq %r13, %rax779; X64-NEXT:    shlq $47, %rax780; X64-NEXT:    orq %rax, %rsp781; X64-NEXT:    popq %rbx782; X64-NEXT:    popq %r12783; X64-NEXT:    popq %r13784; X64-NEXT:    popq %r14785; X64-NEXT:    popq %r15786; X64-NEXT:    retq787;788; X64-LFENCE-LABEL: test_fp_loads:789; X64-LFENCE:       # %bb.0: # %entry790; X64-LFENCE-NEXT:    pushq %r15791; X64-LFENCE-NEXT:    pushq %r14792; X64-LFENCE-NEXT:    pushq %r12793; X64-LFENCE-NEXT:    pushq %rbx794; X64-LFENCE-NEXT:    pushq %rax795; X64-LFENCE-NEXT:    movq %rcx, %r14796; X64-LFENCE-NEXT:    movq %rdx, %rbx797; X64-LFENCE-NEXT:    movq %rsi, %r15798; X64-LFENCE-NEXT:    movq %rdi, %r12799; X64-LFENCE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero800; X64-LFENCE-NEXT:    callq sink_float@PLT801; X64-LFENCE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero802; X64-LFENCE-NEXT:    callq sink_double@PLT803; X64-LFENCE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero804; X64-LFENCE-NEXT:    cvtsd2ss %xmm0, %xmm0805; X64-LFENCE-NEXT:    callq sink_float@PLT806; X64-LFENCE-NEXT:    movss {{.*#+}} xmm0 = mem[0],zero,zero,zero807; X64-LFENCE-NEXT:    cvtss2sd %xmm0, %xmm0808; X64-LFENCE-NEXT:    callq sink_double@PLT809; X64-LFENCE-NEXT:    xorps %xmm0, %xmm0810; X64-LFENCE-NEXT:    cvtsi2ssl (%rbx), %xmm0811; X64-LFENCE-NEXT:    callq sink_float@PLT812; X64-LFENCE-NEXT:    xorps %xmm0, %xmm0813; X64-LFENCE-NEXT:    cvtsi2sdq (%r14), %xmm0814; X64-LFENCE-NEXT:    callq sink_double@PLT815; X64-LFENCE-NEXT:    xorps %xmm0, %xmm0816; X64-LFENCE-NEXT:    cvtsi2ssq (%r14), %xmm0817; X64-LFENCE-NEXT:    callq sink_float@PLT818; X64-LFENCE-NEXT:    xorps %xmm0, %xmm0819; X64-LFENCE-NEXT:    cvtsi2sdl (%rbx), %xmm0820; X64-LFENCE-NEXT:    callq sink_double@PLT821; X64-LFENCE-NEXT:    addq $8, %rsp822; X64-LFENCE-NEXT:    popq %rbx823; X64-LFENCE-NEXT:    popq %r12824; X64-LFENCE-NEXT:    popq %r14825; X64-LFENCE-NEXT:    popq %r15826; X64-LFENCE-NEXT:    retq827entry:828  %f1 = load float, ptr %fptr829  call void @sink_float(float %f1)830  %d1 = load double, ptr %dptr831  call void @sink_double(double %d1)832  %f2.d = load double, ptr %dptr833  %f2 = fptrunc double %f2.d to float834  call void @sink_float(float %f2)835  %d2.f = load float, ptr %fptr836  %d2 = fpext float %d2.f to double837  call void @sink_double(double %d2)838  %f3.i = load i32, ptr %i32ptr839  %f3 = sitofp i32 %f3.i to float840  call void @sink_float(float %f3)841  %d3.i = load i64, ptr %i64ptr842  %d3 = sitofp i64 %d3.i to double843  call void @sink_double(double %d3)844  %f4.i = load i64, ptr %i64ptr845  %f4 = sitofp i64 %f4.i to float846  call void @sink_float(float %f4)847  %d4.i = load i32, ptr %i32ptr848  %d4 = sitofp i32 %d4.i to double849  call void @sink_double(double %d4)850  ret void851}852 853declare void @sink_v4f32(<4 x float>)854declare void @sink_v2f64(<2 x double>)855declare void @sink_v16i8(<16 x i8>)856declare void @sink_v8i16(<8 x i16>)857declare void @sink_v4i32(<4 x i32>)858declare void @sink_v2i64(<2 x i64>)859 860; Test loads of vectors.861define void @test_vec_loads(ptr %v4f32ptr, ptr %v2f64ptr, ptr %v16i8ptr, ptr %v8i16ptr, ptr %v4i32ptr, ptr %v2i64ptr) nounwind speculative_load_hardening {862; X64-LABEL: test_vec_loads:863; X64:       # %bb.0: # %entry864; X64-NEXT:    pushq %rbp865; X64-NEXT:    pushq %r15866; X64-NEXT:    pushq %r14867; X64-NEXT:    pushq %r13868; X64-NEXT:    pushq %r12869; X64-NEXT:    pushq %rbx870; X64-NEXT:    pushq %rax871; X64-NEXT:    movq %rsp, %rax872; X64-NEXT:    movq %r9, %rbx873; X64-NEXT:    movq %r8, %r14874; X64-NEXT:    movq %rcx, %r15875; X64-NEXT:    movq %rdx, %r12876; X64-NEXT:    movq %rsi, %r13877; X64-NEXT:    movq $-1, %rbp878; X64-NEXT:    sarq $63, %rax879; X64-NEXT:    orq %rax, %rdi880; X64-NEXT:    movaps (%rdi), %xmm0881; X64-NEXT:    shlq $47, %rax882; X64-NEXT:    orq %rax, %rsp883; X64-NEXT:    callq sink_v4f32@PLT884; X64-NEXT:  .Lslh_ret_addr15:885; X64-NEXT:    movq %rsp, %rax886; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx887; X64-NEXT:    sarq $63, %rax888; X64-NEXT:    cmpq $.Lslh_ret_addr15, %rcx889; X64-NEXT:    cmovneq %rbp, %rax890; X64-NEXT:    orq %rax, %r13891; X64-NEXT:    movaps (%r13), %xmm0892; X64-NEXT:    shlq $47, %rax893; X64-NEXT:    orq %rax, %rsp894; X64-NEXT:    callq sink_v2f64@PLT895; X64-NEXT:  .Lslh_ret_addr16:896; X64-NEXT:    movq %rsp, %rax897; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx898; X64-NEXT:    sarq $63, %rax899; X64-NEXT:    cmpq $.Lslh_ret_addr16, %rcx900; X64-NEXT:    cmovneq %rbp, %rax901; X64-NEXT:    orq %rax, %r12902; X64-NEXT:    movaps (%r12), %xmm0903; X64-NEXT:    shlq $47, %rax904; X64-NEXT:    orq %rax, %rsp905; X64-NEXT:    callq sink_v16i8@PLT906; X64-NEXT:  .Lslh_ret_addr17:907; X64-NEXT:    movq %rsp, %rax908; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx909; X64-NEXT:    sarq $63, %rax910; X64-NEXT:    cmpq $.Lslh_ret_addr17, %rcx911; X64-NEXT:    cmovneq %rbp, %rax912; X64-NEXT:    orq %rax, %r15913; X64-NEXT:    movaps (%r15), %xmm0914; X64-NEXT:    shlq $47, %rax915; X64-NEXT:    orq %rax, %rsp916; X64-NEXT:    callq sink_v8i16@PLT917; X64-NEXT:  .Lslh_ret_addr18:918; X64-NEXT:    movq %rsp, %rax919; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx920; X64-NEXT:    sarq $63, %rax921; X64-NEXT:    cmpq $.Lslh_ret_addr18, %rcx922; X64-NEXT:    cmovneq %rbp, %rax923; X64-NEXT:    orq %rax, %r14924; X64-NEXT:    movaps (%r14), %xmm0925; X64-NEXT:    shlq $47, %rax926; X64-NEXT:    orq %rax, %rsp927; X64-NEXT:    callq sink_v4i32@PLT928; X64-NEXT:  .Lslh_ret_addr19:929; X64-NEXT:    movq %rsp, %rax930; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx931; X64-NEXT:    sarq $63, %rax932; X64-NEXT:    cmpq $.Lslh_ret_addr19, %rcx933; X64-NEXT:    cmovneq %rbp, %rax934; X64-NEXT:    orq %rax, %rbx935; X64-NEXT:    movaps (%rbx), %xmm0936; X64-NEXT:    shlq $47, %rax937; X64-NEXT:    orq %rax, %rsp938; X64-NEXT:    callq sink_v2i64@PLT939; X64-NEXT:  .Lslh_ret_addr20:940; X64-NEXT:    movq %rsp, %rax941; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx942; X64-NEXT:    sarq $63, %rax943; X64-NEXT:    cmpq $.Lslh_ret_addr20, %rcx944; X64-NEXT:    cmovneq %rbp, %rax945; X64-NEXT:    shlq $47, %rax946; X64-NEXT:    orq %rax, %rsp947; X64-NEXT:    addq $8, %rsp948; X64-NEXT:    popq %rbx949; X64-NEXT:    popq %r12950; X64-NEXT:    popq %r13951; X64-NEXT:    popq %r14952; X64-NEXT:    popq %r15953; X64-NEXT:    popq %rbp954; X64-NEXT:    retq955;956; X64-LFENCE-LABEL: test_vec_loads:957; X64-LFENCE:       # %bb.0: # %entry958; X64-LFENCE-NEXT:    pushq %r15959; X64-LFENCE-NEXT:    pushq %r14960; X64-LFENCE-NEXT:    pushq %r13961; X64-LFENCE-NEXT:    pushq %r12962; X64-LFENCE-NEXT:    pushq %rbx963; X64-LFENCE-NEXT:    movq %r9, %rbx964; X64-LFENCE-NEXT:    movq %r8, %r14965; X64-LFENCE-NEXT:    movq %rcx, %r15966; X64-LFENCE-NEXT:    movq %rdx, %r12967; X64-LFENCE-NEXT:    movq %rsi, %r13968; X64-LFENCE-NEXT:    movaps (%rdi), %xmm0969; X64-LFENCE-NEXT:    callq sink_v4f32@PLT970; X64-LFENCE-NEXT:    movaps (%r13), %xmm0971; X64-LFENCE-NEXT:    callq sink_v2f64@PLT972; X64-LFENCE-NEXT:    movaps (%r12), %xmm0973; X64-LFENCE-NEXT:    callq sink_v16i8@PLT974; X64-LFENCE-NEXT:    movaps (%r15), %xmm0975; X64-LFENCE-NEXT:    callq sink_v8i16@PLT976; X64-LFENCE-NEXT:    movaps (%r14), %xmm0977; X64-LFENCE-NEXT:    callq sink_v4i32@PLT978; X64-LFENCE-NEXT:    movaps (%rbx), %xmm0979; X64-LFENCE-NEXT:    callq sink_v2i64@PLT980; X64-LFENCE-NEXT:    popq %rbx981; X64-LFENCE-NEXT:    popq %r12982; X64-LFENCE-NEXT:    popq %r13983; X64-LFENCE-NEXT:    popq %r14984; X64-LFENCE-NEXT:    popq %r15985; X64-LFENCE-NEXT:    retq986entry:987  %x1 = load <4 x float>, ptr %v4f32ptr988  call void @sink_v4f32(<4 x float> %x1)989  %x2 = load <2 x double>, ptr %v2f64ptr990  call void @sink_v2f64(<2 x double> %x2)991  %x3 = load <16 x i8>, ptr %v16i8ptr992  call void @sink_v16i8(<16 x i8> %x3)993  %x4 = load <8 x i16>, ptr %v8i16ptr994  call void @sink_v8i16(<8 x i16> %x4)995  %x5 = load <4 x i32>, ptr %v4i32ptr996  call void @sink_v4i32(<4 x i32> %x5)997  %x6 = load <2 x i64>, ptr %v2i64ptr998  call void @sink_v2i64(<2 x i64> %x6)999  ret void1000}1001 1002define void @test_deferred_hardening(ptr %ptr1, ptr %ptr2, i32 %x) nounwind speculative_load_hardening {1003; X64-LABEL: test_deferred_hardening:1004; X64:       # %bb.0: # %entry1005; X64-NEXT:    pushq %r151006; X64-NEXT:    pushq %r141007; X64-NEXT:    pushq %rbx1008; X64-NEXT:    movq %rsp, %rax1009; X64-NEXT:    movq %rsi, %r141010; X64-NEXT:    movq %rdi, %rbx1011; X64-NEXT:    movq $-1, %r151012; X64-NEXT:    sarq $63, %rax1013; X64-NEXT:    movl (%rdi), %edi1014; X64-NEXT:    incl %edi1015; X64-NEXT:    imull %edx, %edi1016; X64-NEXT:    orl %eax, %edi1017; X64-NEXT:    shlq $47, %rax1018; X64-NEXT:    orq %rax, %rsp1019; X64-NEXT:    callq sink@PLT1020; X64-NEXT:  .Lslh_ret_addr21:1021; X64-NEXT:    movq %rsp, %rax1022; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx1023; X64-NEXT:    sarq $63, %rax1024; X64-NEXT:    cmpq $.Lslh_ret_addr21, %rcx1025; X64-NEXT:    cmovneq %r15, %rax1026; X64-NEXT:    movl (%rbx), %ecx1027; X64-NEXT:    movl (%r14), %edx1028; X64-NEXT:    leal 1(%rcx,%rdx), %edi1029; X64-NEXT:    orl %eax, %edi1030; X64-NEXT:    shlq $47, %rax1031; X64-NEXT:    orq %rax, %rsp1032; X64-NEXT:    callq sink@PLT1033; X64-NEXT:  .Lslh_ret_addr22:1034; X64-NEXT:    movq %rsp, %rax1035; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx1036; X64-NEXT:    sarq $63, %rax1037; X64-NEXT:    cmpq $.Lslh_ret_addr22, %rcx1038; X64-NEXT:    cmovneq %r15, %rax1039; X64-NEXT:    movl (%rbx), %edi1040; X64-NEXT:    shll $7, %edi1041; X64-NEXT:    orl %eax, %edi1042; X64-NEXT:    shlq $47, %rax1043; X64-NEXT:    orq %rax, %rsp1044; X64-NEXT:    callq sink@PLT1045; X64-NEXT:  .Lslh_ret_addr23:1046; X64-NEXT:    movq %rsp, %rax1047; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx1048; X64-NEXT:    sarq $63, %rax1049; X64-NEXT:    cmpq $.Lslh_ret_addr23, %rcx1050; X64-NEXT:    cmovneq %r15, %rax1051; X64-NEXT:    movswl (%rbx), %edi1052; X64-NEXT:    notl %edi1053; X64-NEXT:    shrl $7, %edi1054; X64-NEXT:    orl $-65536, %edi # imm = 0xFFFF00001055; X64-NEXT:    orl %eax, %edi1056; X64-NEXT:    shlq $47, %rax1057; X64-NEXT:    orq %rax, %rsp1058; X64-NEXT:    callq sink@PLT1059; X64-NEXT:  .Lslh_ret_addr24:1060; X64-NEXT:    movq %rsp, %rax1061; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx1062; X64-NEXT:    sarq $63, %rax1063; X64-NEXT:    cmpq $.Lslh_ret_addr24, %rcx1064; X64-NEXT:    cmovneq %r15, %rax1065; X64-NEXT:    movzwl (%rbx), %ecx1066; X64-NEXT:    rolw $9, %cx1067; X64-NEXT:    movswl %cx, %edi1068; X64-NEXT:    negl %edi1069; X64-NEXT:    orl %eax, %edi1070; X64-NEXT:    shlq $47, %rax1071; X64-NEXT:    orq %rax, %rsp1072; X64-NEXT:    callq sink@PLT1073; X64-NEXT:  .Lslh_ret_addr25:1074; X64-NEXT:    movq %rsp, %rax1075; X64-NEXT:    movq -{{[0-9]+}}(%rsp), %rcx1076; X64-NEXT:    sarq $63, %rax1077; X64-NEXT:    cmpq $.Lslh_ret_addr25, %rcx1078; X64-NEXT:    cmovneq %r15, %rax1079; X64-NEXT:    shlq $47, %rax1080; X64-NEXT:    orq %rax, %rsp1081; X64-NEXT:    popq %rbx1082; X64-NEXT:    popq %r141083; X64-NEXT:    popq %r151084; X64-NEXT:    retq1085;1086; X64-LFENCE-LABEL: test_deferred_hardening:1087; X64-LFENCE:       # %bb.0: # %entry1088; X64-LFENCE-NEXT:    pushq %r141089; X64-LFENCE-NEXT:    pushq %rbx1090; X64-LFENCE-NEXT:    pushq %rax1091; X64-LFENCE-NEXT:    movq %rsi, %r141092; X64-LFENCE-NEXT:    movq %rdi, %rbx1093; X64-LFENCE-NEXT:    movl (%rdi), %edi1094; X64-LFENCE-NEXT:    incl %edi1095; X64-LFENCE-NEXT:    imull %edx, %edi1096; X64-LFENCE-NEXT:    callq sink@PLT1097; X64-LFENCE-NEXT:    movl (%rbx), %eax1098; X64-LFENCE-NEXT:    movl (%r14), %ecx1099; X64-LFENCE-NEXT:    leal 1(%rax,%rcx), %edi1100; X64-LFENCE-NEXT:    callq sink@PLT1101; X64-LFENCE-NEXT:    movl (%rbx), %edi1102; X64-LFENCE-NEXT:    shll $7, %edi1103; X64-LFENCE-NEXT:    callq sink@PLT1104; X64-LFENCE-NEXT:    movswl (%rbx), %edi1105; X64-LFENCE-NEXT:    notl %edi1106; X64-LFENCE-NEXT:    shrl $7, %edi1107; X64-LFENCE-NEXT:    orl $-65536, %edi # imm = 0xFFFF00001108; X64-LFENCE-NEXT:    callq sink@PLT1109; X64-LFENCE-NEXT:    movzwl (%rbx), %eax1110; X64-LFENCE-NEXT:    rolw $9, %ax1111; X64-LFENCE-NEXT:    movswl %ax, %edi1112; X64-LFENCE-NEXT:    negl %edi1113; X64-LFENCE-NEXT:    callq sink@PLT1114; X64-LFENCE-NEXT:    addq $8, %rsp1115; X64-LFENCE-NEXT:    popq %rbx1116; X64-LFENCE-NEXT:    popq %r141117; X64-LFENCE-NEXT:    retq1118entry:1119  %a1 = load i32, ptr %ptr11120  %a2 = add i32 %a1, 11121  %a3 = mul i32 %a2, %x1122  call void @sink(i32 %a3)1123  %b1 = load i32, ptr %ptr11124  %b2 = add i32 %b1, 11125  %b3 = load i32, ptr %ptr21126  %b4 = add i32 %b2, %b31127  call void @sink(i32 %b4)1128  %c1 = load i32, ptr %ptr11129  %c2 = shl i32 %c1, 71130  call void @sink(i32 %c2)1131  %d1 = load i32, ptr %ptr11132  ; Check trunc and integer ops narrower than i32.1133  %d2 = trunc i32 %d1 to i161134  %d3 = ashr i16 %d2, 71135  %d4 = zext i16 %d3 to i321136  %d5 = xor i32 %d4, -11137  call void @sink(i32 %d5)1138  %e1 = load i32, ptr %ptr11139  %e2 = trunc i32 %e1 to i161140  %e3 = lshr i16 %e2, 71141  %e4 = shl i16 %e2, 91142  %e5 = or i16 %e3, %e41143  %e6 = sext i16 %e5 to i321144  %e7 = sub i32 0, %e61145  call void @sink(i32 %e7)1146  ret void1147}1148 1149; Make sure we don't crash on idempotent atomic operations which have a1150; hardcoded reference to RSP+offset.1151define void @idempotent_atomic(ptr %x) speculative_load_hardening {1152; X64-LABEL: idempotent_atomic:1153; X64:       # %bb.0:1154; X64-NEXT:    lock orl $0, -{{[0-9]+}}(%rsp)1155; X64-NEXT:    retq1156;1157; X64-LFENCE-LABEL: idempotent_atomic:1158; X64-LFENCE:       # %bb.0:1159; X64-LFENCE-NEXT:    lock orl $0, -{{[0-9]+}}(%rsp)1160; X64-LFENCE-NEXT:    retq1161  %tmp = atomicrmw or ptr %x, i32 0 seq_cst1162  ret void1163}1164 1165; Make sure we don't crash on longjmps (PR60081).1166declare void @llvm.eh.sjlj.longjmp(ptr)1167define void @test_longjmp(ptr %env) speculative_load_hardening {1168; X64-LABEL: test_longjmp:1169; X64:       # %bb.0:1170; X64-NEXT:    pushq %rbp1171; X64-NEXT:    .cfi_def_cfa_offset 161172; X64-NEXT:    .cfi_offset %rbp, -161173; X64-NEXT:    movq %rsp, %rax1174; X64-NEXT:    movq $-1, %rcx1175; X64-NEXT:    sarq $63, %rax1176; X64-NEXT:    orq %rax, %rdi1177; X64-NEXT:    movq (%rdi), %rbp1178; X64-NEXT:    movq 8(%rdi), %rcx1179; X64-NEXT:    movq 16(%rdi), %rsp1180; X64-NEXT:    orq %rax, %rcx1181; X64-NEXT:    jmpq *%rcx1182;1183; X64-LFENCE-LABEL: test_longjmp:1184; X64-LFENCE:       # %bb.0:1185; X64-LFENCE-NEXT:    pushq %rbp1186; X64-LFENCE-NEXT:    .cfi_def_cfa_offset 161187; X64-LFENCE-NEXT:    .cfi_offset %rbp, -161188; X64-LFENCE-NEXT:    movq (%rdi), %rbp1189; X64-LFENCE-NEXT:    movq 8(%rdi), %rax1190; X64-LFENCE-NEXT:    movq 16(%rdi), %rsp1191; X64-LFENCE-NEXT:    jmpq *%rax1192  call void @llvm.eh.sjlj.longjmp(ptr %env)1193  unreachable1194}1195