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