xref: /llvm-project/llvm/test/CodeGen/ARM/Windows/wineh-framepointer.ll (revision 40c937cba239db817b53d47c4525a751a8c488a0)
1;; Check that this produces the expected assembly output
2; RUN: llc -mtriple=thumbv7-windows -o - %s -verify-machineinstrs | FileCheck %s
3;; Also try to write an object file, which verifies that the SEH opcodes
4;; match the actual prologue/epilogue length.
5; RUN: llc -mtriple=thumbv7-windows -filetype=obj -o %t.obj %s -verify-machineinstrs
6
7; CHECK-LABEL: alloc_local:
8; CHECK-NEXT: .seh_proc alloc_local
9; CHECK-NEXT: @ %bb.0:                                @ %entry
10; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9, r10}
11; CHECK-NEXT:         .seh_save_regs_w        {r4-r10}
12; CHECK-NEXT:         sub     sp, #4
13; CHECK-NEXT:         .seh_stackalloc 4
14; CHECK-NEXT:         vpush   {d8, d9, d10, d11, d12, d13, d14, d15}
15; CHECK-NEXT:         .seh_save_fregs         {d8-d15}
16; CHECK-NEXT:         push.w  {r11, lr}
17; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
18; CHECK-NEXT:         mov     r11, sp
19; CHECK-NEXT:         .seh_save_sp    r11
20; CHECK-NEXT:         .seh_endprologue
21; CHECK-NEXT:         movw    r4, #1256
22; CHECK-NEXT:         bl      __chkstk
23; CHECK-NEXT:         sub.w   sp, sp, r4
24; CHECK-NEXT:         mov     r4, sp
25; CHECK-NEXT:         bfc     r4, #0, #4
26; CHECK-NEXT:         mov     sp, r4
27
28; CHECK:              ldr.w   [[TMP:r[0-9]]], [r11, #104]
29; CHECK:              mov     r0, [[TMP]]
30
31; CHECK:              .seh_startepilogue
32; CHECK-NEXT:         mov     sp, r11
33; CHECK-NEXT:         .seh_save_sp    r11
34; CHECK-NEXT:         pop.w   {r11, lr}
35; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
36; CHECK-NEXT:         vpop    {d8, d9, d10, d11, d12, d13, d14, d15}
37; CHECK-NEXT:         .seh_save_fregs         {d8-d15}
38; CHECK-NEXT:         add     sp, #4
39; CHECK-NEXT:         .seh_stackalloc 4
40; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9, r10}
41; CHECK-NEXT:         .seh_save_regs_w        {r4-r10}
42; CHECK-NEXT:         bx      lr
43; CHECK-NEXT:         .seh_nop
44; CHECK-NEXT:         .seh_endepilogue
45; CHECK-NEXT:         .seh_endproc
46
47define arm_aapcs_vfpcc void @alloc_local(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e) uwtable {
48entry:
49  %buf2 = alloca [5000 x i8], align 16
50  %vla = alloca i8, i32 %a, align 1
51  call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2) #3
52  call arm_aapcs_vfpcc void @other(i32 noundef %e, ptr noundef nonnull %vla, ptr noundef nonnull %buf2)
53  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12}"()
54  call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"()
55  call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2) #3
56  ret void
57}
58
59declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
60declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
61
62declare arm_aapcs_vfpcc void @other(i32 noundef, ptr noundef, ptr noundef)
63
64; CHECK-LABEL: everything_varargs:
65; CHECK-NEXT: .seh_proc everything_varargs
66; CHECK-NEXT: @ %bb.0:                                @ %entry
67; CHECK-NEXT:         sub     sp, #12
68; CHECK-NEXT:         .seh_stackalloc 12
69; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9}
70; CHECK-NEXT:         .seh_save_regs_w        {r4-r9}
71; CHECK-NEXT:         sub     sp, #4
72; CHECK-NEXT:         .seh_stackalloc 4
73; CHECK-NEXT:         vpush   {d8, d9, d10, d11, d12, d13, d14, d15}
74; CHECK-NEXT:         .seh_save_fregs         {d8-d15}
75; CHECK-NEXT:         push.w  {r11, lr}
76; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
77; CHECK-NEXT:         mov     r11, sp
78; CHECK-NEXT:         .seh_save_sp    r11
79; CHECK-NEXT:         .seh_endprologue
80; CHECK-NEXT:         movw    r4, #1258
81; CHECK-NEXT:         bl      __chkstk
82; CHECK-NEXT:         sub.w   sp, sp, r4
83; CHECK-NEXT:         mov     r4, sp
84; CHECK-NEXT:         bfc     r4, #0, #4
85; CHECK-NEXT:         mov     sp, r4
86
87; CHECK:              .seh_startepilogue
88; CHECK-NEXT:         mov     sp, r11
89; CHECK-NEXT:         .seh_save_sp    r11
90; CHECK-NEXT:         pop.w   {r11, lr}
91; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
92; CHECK-NEXT:         vpop    {d8, d9, d10, d11, d12, d13, d14, d15}
93; CHECK-NEXT:         .seh_save_fregs         {d8-d15}
94; CHECK-NEXT:         add     sp, #4
95; CHECK-NEXT:         .seh_stackalloc 4
96; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9}
97; CHECK-NEXT:         .seh_save_regs_w        {r4-r9}
98; CHECK-NEXT:         add     sp, #12
99; CHECK-NEXT:         .seh_stackalloc 12
100; CHECK-NEXT:         bx      lr
101; CHECK-NEXT:         .seh_nop
102; CHECK-NEXT:         .seh_endepilogue
103; CHECK-NEXT:         .seh_endproc
104
105define arm_aapcs_vfpcc void @everything_varargs(i32 noundef %a, ...) {
106entry:
107  %buf2 = alloca [5000 x i8], align 16
108  %ap = alloca ptr, align 4
109  %vla = alloca i8, i32 %a, align 1
110  call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
111  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
112  call void @llvm.va_start(ptr nonnull %ap)
113  %0 = load ptr, ptr %ap, align 4
114  call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
115  call void @llvm.va_end(ptr nonnull %ap)
116  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
117  call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"()
118  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
119  call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
120  ret void
121}
122
123; CHECK-LABEL: novector_varargs:
124; CHECK-NEXT: .seh_proc novector_varargs
125; CHECK-NEXT: @ %bb.0:                                @ %entry
126; CHECK-NEXT:         sub     sp, #12
127; CHECK-NEXT:         .seh_stackalloc 12
128; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9}
129; CHECK-NEXT:         .seh_save_regs_w        {r4-r9}
130; CHECK-NEXT:         push.w  {r11, lr}
131; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
132; CHECK-NEXT:         mov     r11, sp
133; CHECK-NEXT:         .seh_save_sp    r11
134; CHECK-NEXT:         .seh_endprologue
135; CHECK-NEXT:         movw    r4, #1259
136; CHECK-NEXT:         bl      __chkstk
137; CHECK-NEXT:         sub.w   sp, sp, r4
138; CHECK-NEXT:         mov     r4, sp
139; CHECK-NEXT:         bfc     r4, #0, #4
140; CHECK-NEXT:         mov     sp, r4
141
142; CHECK:              .seh_startepilogue
143; CHECK-NEXT:         mov     sp, r11
144; CHECK-NEXT:         .seh_save_sp    r11
145; CHECK-NEXT:         pop.w   {r11, lr}
146; CHECK-NEXT:         .seh_save_regs_w        {r11, lr}
147; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9}
148; CHECK-NEXT:         .seh_save_regs_w        {r4-r9}
149; CHECK-NEXT:         add     sp, #12
150; CHECK-NEXT:         .seh_stackalloc 12
151; CHECK-NEXT:         bx      lr
152; CHECK-NEXT:         .seh_nop
153; CHECK-NEXT:         .seh_endepilogue
154; CHECK-NEXT:         .seh_endproc
155
156define arm_aapcs_vfpcc void @novector_varargs(i32 noundef %a, ...) {
157entry:
158  %buf2 = alloca [5000 x i8], align 16
159  %ap = alloca ptr, align 4
160  %vla = alloca i8, i32 %a, align 1
161  call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2)
162  call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)
163  call void @llvm.va_start(ptr nonnull %ap)
164  %0 = load ptr, ptr %ap, align 4
165  call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0)
166  call void @llvm.va_end(ptr nonnull %ap)
167  call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"()
168  call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)
169  call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2)
170  ret void
171}
172
173declare void @llvm.va_start(ptr)
174declare void @llvm.va_end(ptr)
175
176declare arm_aapcs_vfpcc void @other2(i32 noundef, ptr noundef, ptr noundef, ptr noundef)
177