|  | ;; Check that this produces the expected assembly output | 
|  | ; RUN: llc -mtriple=thumbv7-windows -o - %s -verify-machineinstrs | FileCheck %s | 
|  | ;; Also try to write an object file, which verifies that the SEH opcodes | 
|  | ;; match the actual prologue/epilogue length. | 
|  | ; RUN: llc -mtriple=thumbv7-windows -filetype=obj -o %t.obj %s -verify-machineinstrs | 
|  |  | 
|  | ; CHECK-LABEL: alloc_local: | 
|  | ; CHECK-NEXT: .seh_proc alloc_local | 
|  | ; CHECK-NEXT: @ %bb.0:                                @ %entry | 
|  | ; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9, r10} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r10} | 
|  | ; CHECK-NEXT:         sub     sp, #4 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 4 | 
|  | ; CHECK-NEXT:         vpush   {d8, d9, d10, d11, d12, d13, d14, d15} | 
|  | ; CHECK-NEXT:         .seh_save_fregs         {d8-d15} | 
|  | ; CHECK-NEXT:         push.w  {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         mov     r11, sp | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         .seh_endprologue | 
|  | ; CHECK-NEXT:         movw    r4, #1256 | 
|  | ; CHECK-NEXT:         bl      __chkstk | 
|  | ; CHECK-NEXT:         sub.w   sp, sp, r4 | 
|  | ; CHECK-NEXT:         mov     r4, sp | 
|  | ; CHECK-NEXT:         bfc     r4, #0, #4 | 
|  | ; CHECK-NEXT:         mov     sp, r4 | 
|  |  | 
|  | ; CHECK:              ldr.w   [[TMP:r[0-9]]], [r11, #104] | 
|  | ; CHECK:              mov     r0, [[TMP]] | 
|  |  | 
|  | ; CHECK:              .seh_startepilogue | 
|  | ; CHECK-NEXT:         mov     sp, r11 | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         pop.w   {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         vpop    {d8, d9, d10, d11, d12, d13, d14, d15} | 
|  | ; CHECK-NEXT:         .seh_save_fregs         {d8-d15} | 
|  | ; CHECK-NEXT:         add     sp, #4 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 4 | 
|  | ; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9, r10} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r10} | 
|  | ; CHECK-NEXT:         bx      lr | 
|  | ; CHECK-NEXT:         .seh_nop | 
|  | ; CHECK-NEXT:         .seh_endepilogue | 
|  | ; CHECK-NEXT:         .seh_endproc | 
|  |  | 
|  | define arm_aapcs_vfpcc void @alloc_local(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d, i32 noundef %e) uwtable { | 
|  | entry: | 
|  | %buf2 = alloca [5000 x i8], align 16 | 
|  | %vla = alloca i8, i32 %a, align 1 | 
|  | call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2) #3 | 
|  | call arm_aapcs_vfpcc void @other(i32 noundef %e, ptr noundef nonnull %vla, ptr noundef nonnull %buf2) | 
|  | call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12}"() | 
|  | call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"() | 
|  | call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2) #3 | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) | 
|  | declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) | 
|  |  | 
|  | declare arm_aapcs_vfpcc void @other(i32 noundef, ptr noundef, ptr noundef) | 
|  |  | 
|  | ; CHECK-LABEL: everything_varargs: | 
|  | ; CHECK-NEXT: .seh_proc everything_varargs | 
|  | ; CHECK-NEXT: @ %bb.0:                                @ %entry | 
|  | ; CHECK-NEXT:         sub     sp, #12 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 12 | 
|  | ; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r9} | 
|  | ; CHECK-NEXT:         sub     sp, #4 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 4 | 
|  | ; CHECK-NEXT:         vpush   {d8, d9, d10, d11, d12, d13, d14, d15} | 
|  | ; CHECK-NEXT:         .seh_save_fregs         {d8-d15} | 
|  | ; CHECK-NEXT:         push.w  {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         mov     r11, sp | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         .seh_endprologue | 
|  | ; CHECK-NEXT:         movw    r4, #1258 | 
|  | ; CHECK-NEXT:         bl      __chkstk | 
|  | ; CHECK-NEXT:         sub.w   sp, sp, r4 | 
|  | ; CHECK-NEXT:         mov     r4, sp | 
|  | ; CHECK-NEXT:         bfc     r4, #0, #4 | 
|  | ; CHECK-NEXT:         mov     sp, r4 | 
|  |  | 
|  | ; CHECK:              .seh_startepilogue | 
|  | ; CHECK-NEXT:         mov     sp, r11 | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         pop.w   {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         vpop    {d8, d9, d10, d11, d12, d13, d14, d15} | 
|  | ; CHECK-NEXT:         .seh_save_fregs         {d8-d15} | 
|  | ; CHECK-NEXT:         add     sp, #4 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 4 | 
|  | ; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r9} | 
|  | ; CHECK-NEXT:         add     sp, #12 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 12 | 
|  | ; CHECK-NEXT:         bx      lr | 
|  | ; CHECK-NEXT:         .seh_nop | 
|  | ; CHECK-NEXT:         .seh_endepilogue | 
|  | ; CHECK-NEXT:         .seh_endproc | 
|  |  | 
|  | define arm_aapcs_vfpcc void @everything_varargs(i32 noundef %a, ...) { | 
|  | entry: | 
|  | %buf2 = alloca [5000 x i8], align 16 | 
|  | %ap = alloca ptr, align 4 | 
|  | %vla = alloca i8, i32 %a, align 1 | 
|  | call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2) | 
|  | call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap) | 
|  | call void @llvm.va_start(ptr nonnull %ap) | 
|  | %0 = load ptr, ptr %ap, align 4 | 
|  | call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0) | 
|  | call void @llvm.va_end(ptr nonnull %ap) | 
|  | call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"() | 
|  | call void asm sideeffect "", "~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15}"() | 
|  | call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap) | 
|  | call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; CHECK-LABEL: novector_varargs: | 
|  | ; CHECK-NEXT: .seh_proc novector_varargs | 
|  | ; CHECK-NEXT: @ %bb.0:                                @ %entry | 
|  | ; CHECK-NEXT:         sub     sp, #12 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 12 | 
|  | ; CHECK-NEXT:         push.w  {r4, r5, r6, r7, r8, r9} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r9} | 
|  | ; CHECK-NEXT:         push.w  {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         mov     r11, sp | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         .seh_endprologue | 
|  | ; CHECK-NEXT:         movw    r4, #1259 | 
|  | ; CHECK-NEXT:         bl      __chkstk | 
|  | ; CHECK-NEXT:         sub.w   sp, sp, r4 | 
|  | ; CHECK-NEXT:         mov     r4, sp | 
|  | ; CHECK-NEXT:         bfc     r4, #0, #4 | 
|  | ; CHECK-NEXT:         mov     sp, r4 | 
|  |  | 
|  | ; CHECK:              .seh_startepilogue | 
|  | ; CHECK-NEXT:         mov     sp, r11 | 
|  | ; CHECK-NEXT:         .seh_save_sp    r11 | 
|  | ; CHECK-NEXT:         pop.w   {r11, lr} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r11, lr} | 
|  | ; CHECK-NEXT:         pop.w   {r4, r5, r6, r7, r8, r9} | 
|  | ; CHECK-NEXT:         .seh_save_regs_w        {r4-r9} | 
|  | ; CHECK-NEXT:         add     sp, #12 | 
|  | ; CHECK-NEXT:         .seh_stackalloc 12 | 
|  | ; CHECK-NEXT:         bx      lr | 
|  | ; CHECK-NEXT:         .seh_nop | 
|  | ; CHECK-NEXT:         .seh_endepilogue | 
|  | ; CHECK-NEXT:         .seh_endproc | 
|  |  | 
|  | define arm_aapcs_vfpcc void @novector_varargs(i32 noundef %a, ...) { | 
|  | entry: | 
|  | %buf2 = alloca [5000 x i8], align 16 | 
|  | %ap = alloca ptr, align 4 | 
|  | %vla = alloca i8, i32 %a, align 1 | 
|  | call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf2) | 
|  | call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap) | 
|  | call void @llvm.va_start(ptr nonnull %ap) | 
|  | %0 = load ptr, ptr %ap, align 4 | 
|  | call arm_aapcs_vfpcc void @other2(i32 noundef %a, ptr noundef nonnull %vla, ptr noundef nonnull %buf2, ptr noundef %0) | 
|  | call void @llvm.va_end(ptr nonnull %ap) | 
|  | call void asm sideeffect "", "~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r11},~{r12}"() | 
|  | call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap) | 
|  | call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf2) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare void @llvm.va_start(ptr) | 
|  | declare void @llvm.va_end(ptr) | 
|  |  | 
|  | declare arm_aapcs_vfpcc void @other2(i32 noundef, ptr noundef, ptr noundef, ptr noundef) |