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