1; RUN: llc < %s | FileCheck %s 2 3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4target triple = "x86_64-unknown-linux-gnu" 5 6; | case1 | alloca + align < probe_size 7define i32 @foo1(i64 %i) local_unnamed_addr #0 { 8; CHECK-LABEL: foo1: 9; CHECK: # %bb.0: 10; CHECK-NEXT: pushq %rbp 11; CHECK-NEXT: .cfi_def_cfa_offset 16 12; CHECK-NEXT: .cfi_offset %rbp, -16 13; CHECK-NEXT: movq %rsp, %rbp 14; CHECK-NEXT: .cfi_def_cfa_register %rbp 15; CHECK-NEXT: andq $-64, %rsp 16; CHECK-NEXT: subq $832, %rsp # imm = 0x340 17; CHECK-NEXT: movl $1, (%rsp,%rdi,4) 18; CHECK-NEXT: movl (%rsp), %eax 19; CHECK-NEXT: movq %rbp, %rsp 20; CHECK-NEXT: popq %rbp 21; CHECK-NEXT: .cfi_def_cfa %rsp, 8 22; CHECK-NEXT: retq 23 24 %a = alloca i32, i32 200, align 64 25 %b = getelementptr inbounds i32, i32* %a, i64 %i 26 store volatile i32 1, i32* %b 27 %c = load volatile i32, i32* %a 28 ret i32 %c 29} 30 31; | case2 | alloca > probe_size, align > probe_size 32define i32 @foo2(i64 %i) local_unnamed_addr #0 { 33; CHECK-LABEL: foo2: 34; CHECK: # %bb.0: 35; CHECK-NEXT: pushq %rbp 36; CHECK-NEXT: .cfi_def_cfa_offset 16 37; CHECK-NEXT: .cfi_offset %rbp, -16 38; CHECK-NEXT: movq %rsp, %rbp 39; CHECK-NEXT: .cfi_def_cfa_register %rbp 40; CHECK-NEXT: andq $-2048, %rsp # imm = 0xF800 41; CHECK-NEXT: subq $2048, %rsp # imm = 0x800 42; CHECK-NEXT: movq $0, (%rsp) 43; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000 44; CHECK-NEXT: movq $0, (%rsp) 45; CHECK-NEXT: subq $2048, %rsp # imm = 0x800 46; CHECK-NEXT: movl $1, (%rsp,%rdi,4) 47; CHECK-NEXT: movl (%rsp), %eax 48; CHECK-NEXT: movq %rbp, %rsp 49; CHECK-NEXT: popq %rbp 50; CHECK-NEXT: .cfi_def_cfa %rsp, 8 51; CHECK-NEXT: retq 52 53 %a = alloca i32, i32 2000, align 2048 54 %b = getelementptr inbounds i32, i32* %a, i64 %i 55 store volatile i32 1, i32* %b 56 %c = load volatile i32, i32* %a 57 ret i32 %c 58} 59 60; | case3 | alloca < probe_size, align < probe_size, alloca + align > probe_size 61define i32 @foo3(i64 %i) local_unnamed_addr #0 { 62; CHECK-LABEL: foo3: 63; CHECK: # %bb.0: 64; CHECK-NEXT: pushq %rbp 65; CHECK-NEXT: .cfi_def_cfa_offset 16 66; CHECK-NEXT: .cfi_offset %rbp, -16 67; CHECK-NEXT: movq %rsp, %rbp 68; CHECK-NEXT: .cfi_def_cfa_register %rbp 69; CHECK-NEXT: andq $-1024, %rsp # imm = 0xFC00 70; CHECK-NEXT: subq $3072, %rsp # imm = 0xC00 71; CHECK-NEXT: movq $0, (%rsp) 72; CHECK-NEXT: subq $1024, %rsp # imm = 0x400 73; CHECK-NEXT: movl $1, (%rsp,%rdi,4) 74; CHECK-NEXT: movl (%rsp), %eax 75; CHECK-NEXT: movq %rbp, %rsp 76; CHECK-NEXT: popq %rbp 77; CHECK-NEXT: .cfi_def_cfa %rsp, 8 78; CHECK-NEXT: retq 79 80 81 %a = alloca i32, i32 1000, align 1024 82 %b = getelementptr inbounds i32, i32* %a, i64 %i 83 store volatile i32 1, i32* %b 84 %c = load volatile i32, i32* %a 85 ret i32 %c 86} 87 88; | case4 | alloca + probe_size < probe_size, followed by dynamic alloca 89define i32 @foo4(i64 %i) local_unnamed_addr #0 { 90; CHECK-LABEL: foo4: 91; CHECK: # %bb.0: 92; CHECK-NEXT: pushq %rbp 93; CHECK-NEXT: .cfi_def_cfa_offset 16 94; CHECK-NEXT: .cfi_offset %rbp, -16 95; CHECK-NEXT: movq %rsp, %rbp 96; CHECK-NEXT: .cfi_def_cfa_register %rbp 97; CHECK-NEXT: pushq %rbx 98; CHECK-NEXT: andq $-64, %rsp 99; CHECK-NEXT: subq $896, %rsp # imm = 0x380 100; CHECK-NEXT: movq %rsp, %rbx 101; CHECK-NEXT: .cfi_offset %rbx, -24 102; CHECK-NEXT: movl $1, (%rbx,%rdi,4) 103; CHECK-NEXT: movl (%rbx), %ecx 104; CHECK-NEXT: movq %rsp, %rax 105; CHECK-NEXT: leaq 15(,%rcx,4), %rcx 106; CHECK-NEXT: andq $-16, %rcx 107; CHECK-NEXT: subq %rcx, %rax 108; CHECK-NEXT: cmpq %rsp, %rax 109; CHECK-NEXT: jge .LBB3_3 110; CHECK-NEXT:.LBB3_2: # =>This Inner Loop Header: Depth=1 111; CHECK-NEXT: xorq $0, (%rsp) 112; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000 113; CHECK-NEXT: cmpq %rsp, %rax 114; CHECK-NEXT: jl .LBB3_2 115; CHECK-NEXT:.LBB3_3: 116; CHECK-NEXT: andq $-64, %rax 117; CHECK-NEXT: movq %rax, %rsp 118; CHECK-NEXT: movl (%rax), %eax 119; CHECK-NEXT: leaq -8(%rbp), %rsp 120; CHECK-NEXT: popq %rbx 121; CHECK-NEXT: popq %rbp 122; CHECK-NEXT: .cfi_def_cfa %rsp, 8 123; CHECK-NEXT: retq 124 125 %a = alloca i32, i32 200, align 64 126 %b = getelementptr inbounds i32, i32* %a, i64 %i 127 store volatile i32 1, i32* %b 128 %c = load volatile i32, i32* %a 129 %d = alloca i32, i32 %c, align 64 130 %e = load volatile i32, i32* %d 131 ret i32 %e 132} 133 134attributes #0 = {"probe-stack"="inline-asm"} 135 136