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