[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / llvm / test / CodeGen / X86 / win-alloca-expander.ll
blob9af18c95a56cd834ccd58e5d8aef3f19ec59a3d2
1 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s
2 ; RUN: llc < %s -mtriple=i686-pc-win32 -O0
4 %struct.S = type { [1024 x i8] }
5 %struct.T = type { [3000 x i8] }
6 %struct.U = type { [10000 x i8] }
8 define void @basics() {
9 ; CHECK-LABEL: basics:
10 entry:
11   br label %bb1
13 ; Allocation move sizes should have been removed.
14 ; CHECK-NOT: movl $1024
15 ; CHECK-NOT: movl $3000
17 bb1:
18   %p0 = alloca %struct.S
19 ; The allocation is small enough not to require stack probing, but the %esp
20 ; offset after the prologue is not known, so the stack must be touched before
21 ; the pointer is adjusted.
22 ; CHECK: pushl %eax
23 ; CHECK: subl $1020, %esp
25   %saved_stack = tail call ptr @llvm.stacksave()
27   %p1 = alloca %struct.S
28 ; We know the %esp offset from above, so there is no need to touch the stack
29 ; before adjusting it.
30 ; CHECK: subl $1024, %esp
32   %p2 = alloca %struct.T
33 ; The offset is now 2048 bytes, so allocating a T must touch the stack again.
34 ; CHECK: pushl %eax
35 ; CHECK: subl $2996, %esp
37   call void @f(ptr %p0)
38 ; CHECK: calll
40   %p3 = alloca %struct.T
41 ; The call above touched the stack, so there is room for a T object.
42 ; CHECK: subl $3000, %esp
44   %p4 = alloca %struct.U
45 ; The U object is large enough to require stack probing.
46 ; CHECK: movl $10000, %eax
47 ; CHECK: calll __chkstk
49   %p5 = alloca %struct.T
50 ; The stack probing above touched the tip of the stack, so there's room for a T.
51 ; CHECK: subl $3000, %esp
53   call void @llvm.stackrestore(ptr %saved_stack)
54   %p6 = alloca %struct.S
55 ; The stack restore means we lose track of the stack pointer and must probe.
56 ; CHECK: pushl %eax
57 ; CHECK: subl $1020, %esp
59 ; Use the pointers so they're not optimized away.
60   call void @f(ptr %p1)
61   call void @g(ptr %p2)
62   call void @g(ptr %p3)
63   call void @h(ptr %p4)
64   call void @g(ptr %p5)
65   ret void
68 define void @loop() {
69 ; CHECK-LABEL: loop:
70 entry:
71   br label %bb1
73 bb1:
74   %p1 = alloca %struct.S
75 ; The entry offset is unknown; touch-and-sub.
76 ; CHECK: pushl %eax
77 ; CHECK: subl $1020, %esp
78   br label %loop1
80 loop1:
81   %i1 = phi i32 [ 10, %bb1 ], [ %dec1, %loop1 ]
82   %p2 = alloca %struct.S
83 ; We know the incoming offset from bb1, but from the back-edge, we assume the
84 ; worst, and therefore touch-and-sub to allocate.
85 ; CHECK: pushl %eax
86 ; CHECK: subl $1020, %esp
87   %dec1 = sub i32 %i1, 1
88   %cmp1 = icmp sgt i32 %i1, 0
89   br i1 %cmp1, label %loop1, label %end
90 ; CHECK: decl
91 ; CHECK: jg
93 end:
94   call void @f(ptr %p1)
95   call void @f(ptr %p2)
96   ret void
99 define void @probe_size_attribute() "stack-probe-size"="512" {
100 ; CHECK-LABEL: probe_size_attribute:
101 entry:
102   br label %bb1
104 bb1:
105   %p0 = alloca %struct.S
106 ; The allocation would be small enough not to require probing, if it wasn't
107 ; for the stack-probe-size attribute.
108 ; CHECK: movl $1024, %eax
109 ; CHECK: calll __chkstk
110   call void @f(ptr %p0)
111   ret void
114 define void @cfg(i1 %x, i1 %y) {
115 ; Test that the blocks are analyzed in the correct order.
116 ; CHECK-LABEL: cfg:
117 entry:
118   br i1 %x, label %bb1, label %bb3
120 bb1:
121   %p1 = alloca %struct.S
122 ; CHECK: pushl %eax
123 ; CHECK: subl $1020, %esp
124   br label %bb4
126 bb2:
127   %p5 = alloca %struct.T
128 ; CHECK: pushl %eax
129 ; CHECK: subl $2996, %esp
130   call void @g(ptr %p5)
131   ret void
133 bb3:
134   %p2 = alloca %struct.T
135 ; CHECK: pushl %eax
136 ; CHECK: subl $2996, %esp
137   br label %bb4
139 bb4:
140   br i1 %y, label %bb5, label %bb2
142 bb5:
143   %p4 = alloca %struct.S
144 ; CHECK: subl $1024, %esp
145   call void @f(ptr %p4)
146   ret void
151 declare void @f(ptr)
152 declare void @g(ptr)
153 declare void @h(ptr)
155 declare ptr @llvm.stacksave()
156 declare void @llvm.stackrestore(ptr)