342 lines · plain
1;; Check that this produces the expected assembly output2; RUN: llc -mtriple=thumbv7-windows -o - %s -verify-machineinstrs | FileCheck %s3;; Also try to write an object file, which verifies that the SEH opcodes4;; match the actual prologue/epilogue length.5; RUN: llc -mtriple=thumbv7-windows -filetype=obj -o %t.obj %s -verify-machineinstrs6 7; CHECK-LABEL: clobberR4Frame:8; CHECK-NEXT: .seh_proc clobberR4Frame9; CHECK-NEXT: @ %bb.0: @ %entry10; CHECK-NEXT: push.w {r4, r7, r11, lr}11; CHECK-NEXT: .seh_save_regs_w {r4, r7, r11, lr}12; CHECK-NEXT: add.w r11, sp, #813; CHECK-NEXT: .seh_nop_w14; CHECK-NEXT: .seh_endprologue15; CHECK-NEXT: bl other16 17; CHECK: .seh_startepilogue18; CHECK-NEXT: pop.w {r4, r7, r11, pc}19; CHECK-NEXT: .seh_save_regs_w {r4, r7, r11, lr}20; CHECK-NEXT: .seh_endepilogue21; CHECK-NEXT: .seh_endproc22 23define arm_aapcs_vfpcc void @clobberR4Frame() uwtable "frame-pointer"="all" {24entry:25 call arm_aapcs_vfpcc void @other()26 call void asm sideeffect "", "~{r4}"()27 ret void28}29 30; CHECK-LABEL: clobberR4NoFrame:31; CHECK-NEXT: .seh_proc clobberR4NoFrame32; CHECK-NEXT: @ %bb.0: @ %entry33; CHECK-NEXT: push {r4, lr}34; CHECK-NEXT: .seh_save_regs {r4, lr}35; CHECK-NEXT: .seh_endprologue36; CHECK-NEXT: bl other37 38; CHECK: .seh_startepilogue39; CHECK-NEXT: pop {r4, pc}40; CHECK-NEXT: .seh_save_regs {r4, lr}41; CHECK-NEXT: .seh_endepilogue42; CHECK-NEXT: .seh_endproc43 44define arm_aapcs_vfpcc void @clobberR4NoFrame() uwtable "frame-pointer"="none" {45entry:46 call arm_aapcs_vfpcc void @other()47 call void asm sideeffect "", "~{r4}"()48 ret void49}50 51; CHECK-LABEL: clobberR4Tail:52; CHECK-NEXT: .seh_proc clobberR4Tail53; CHECK-NEXT: @ %bb.0: @ %entry54; CHECK-NEXT: push {r4, lr}55; CHECK-NEXT: .seh_save_regs {r4, lr}56; CHECK-NEXT: .seh_endprologue57 58; CHECK: .seh_startepilogue59; CHECK-NEXT: pop.w {r4, lr}60; CHECK-NEXT: .seh_save_regs_w {r4, lr}61; CHECK-NEXT: b.w other62; CHECK-NEXT: .seh_nop_w63; CHECK-NEXT: .seh_endepilogue64; CHECK-NEXT: .seh_endproc65 66define arm_aapcs_vfpcc void @clobberR4Tail() uwtable "frame-pointer"="none" {67entry:68 call void asm sideeffect "", "~{r4}"()69 tail call arm_aapcs_vfpcc void @other()70 ret void71}72 73; CHECK-LABEL: clobberD8D10:74; CHECK-NEXT: .seh_proc clobberD8D1075; CHECK-NEXT: @ %bb.0: @ %entry76; CHECK-NEXT: vpush {d8, d9, d10}77; CHECK-NEXT: .seh_save_fregs {d8-d10}78; CHECK-NEXT: .seh_endprologue79 80; CHECK: .seh_startepilogue81; CHECK-NEXT: vpop {d8, d9, d10}82; CHECK-NEXT: .seh_save_fregs {d8-d10}83; CHECK-NEXT: b.w other84; CHECK-NEXT: .seh_nop_w85; CHECK-NEXT: .seh_endepilogue86; CHECK-NEXT: .seh_endproc87 88define arm_aapcs_vfpcc void @clobberD8D10() uwtable "frame-pointer"="none" {89entry:90 call void asm sideeffect "", "~{d8},~{d9},~{d10}"()91 tail call arm_aapcs_vfpcc void @other()92 ret void93}94 95declare arm_aapcs_vfpcc void @other()96 97; CHECK-LABEL: vararg:98; CHECK-NEXT: .seh_proc vararg99; CHECK-NEXT: @ %bb.0: @ %entry100; CHECK-NEXT: sub sp, #12101; CHECK-NEXT: .seh_stackalloc 12102; CHECK-NEXT: push.w {r11, lr}103; CHECK-NEXT: .seh_save_regs_w {r11, lr}104; CHECK-NEXT: sub sp, #4105; CHECK-NEXT: .seh_stackalloc 4106; CHECK-NEXT: .seh_endprologue107 108; CHECK: .seh_startepilogue109; CHECK-NEXT: add sp, #4110; CHECK-NEXT: .seh_stackalloc 4111; CHECK-NEXT: pop.w {r11, lr}112; CHECK-NEXT: .seh_save_regs_w {r11, lr}113; CHECK-NEXT: add sp, #12114; CHECK-NEXT: .seh_stackalloc 12115; CHECK-NEXT: bx lr116; CHECK-NEXT: .seh_nop117; CHECK-NEXT: .seh_endepilogue118; CHECK-NEXT: .seh_endproc119 120define arm_aapcs_vfpcc void @vararg(i32 noundef %a, ...) uwtable "frame-pointer"="none" {121entry:122 %ap = alloca ptr, align 4123 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %ap)124 call void @llvm.va_start(ptr nonnull %ap)125 %0 = load ptr, ptr %ap126 call arm_aapcs_vfpcc void @useva(ptr noundef %0)127 call void @llvm.va_end(ptr nonnull %ap)128 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %ap)129 ret void130}131 132declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)133declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)134declare void @llvm.va_start(ptr)135declare void @llvm.va_end(ptr)136 137declare arm_aapcs_vfpcc void @useva(ptr noundef)138 139; CHECK-LABEL: onlystack:140; CHECK-NEXT: .seh_proc onlystack141; CHECK-NEXT: @ %bb.0: @ %entry142; CHECK-NEXT: sub sp, #4143; CHECK-NEXT: .seh_stackalloc 4144; CHECK-NEXT: .seh_endprologue145 146; CHECK: .seh_startepilogue147; CHECK-NEXT: add sp, #4148; CHECK-NEXT: .seh_stackalloc 4149; CHECK-NEXT: bx lr150; CHECK-NEXT: .seh_nop151; CHECK-NEXT: .seh_endepilogue152; CHECK-NEXT: .seh_endproc153 154define dso_local arm_aapcs_vfpcc void @onlystack() uwtable "frame-pointer"="none" {155entry:156 %buf = alloca [4 x i8], align 1157 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %buf)158 call void asm sideeffect "", "r"(ptr nonnull %buf)159 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %buf)160 ret void161}162 163; CHECK-LABEL: func50:164; CHECK-NEXT: .seh_proc func50165; CHECK-NEXT: @ %bb.0: @ %entry166; CHECK-NEXT: push.w {r11, lr}167; CHECK-NEXT: .seh_save_regs_w {r11, lr}168; CHECK-NEXT: sub sp, #56169; CHECK-NEXT: .seh_stackalloc 56170; CHECK-NEXT: .seh_endprologue171 172; CHECK: .seh_startepilogue173; CHECK-NEXT: add sp, #56174; CHECK-NEXT: .seh_stackalloc 56175; CHECK-NEXT: pop.w {r11, pc}176; CHECK-NEXT: .seh_save_regs_w {r11, lr}177; CHECK-NEXT: .seh_endepilogue178; CHECK-NEXT: .seh_endproc179 180define arm_aapcs_vfpcc void @func50() {181entry:182 %buf = alloca [50 x i8], align 1183 call void @llvm.lifetime.start.p0(i64 50, ptr nonnull %buf)184 call arm_aapcs_vfpcc void @useptr(ptr noundef nonnull %buf)185 call void @llvm.lifetime.end.p0(i64 50, ptr nonnull %buf)186 ret void187}188 189; CHECK-LABEL: func4000:190; CHECK-NEXT: .seh_proc func4000191; CHECK-NEXT: @ %bb.0: @ %entry192; CHECK-NEXT: push.w {r11, lr}193; CHECK-NEXT: .seh_save_regs_w {r11, lr}194; CHECK-NEXT: sub.w sp, sp, #4000195; CHECK-NEXT: .seh_stackalloc_w 4000196; CHECK-NEXT: .seh_endprologue197 198; CHECK: .seh_startepilogue199; CHECK-NEXT: add.w sp, sp, #4000200; CHECK-NEXT: .seh_stackalloc_w 4000201; CHECK-NEXT: pop.w {r11, pc}202; CHECK-NEXT: .seh_save_regs_w {r11, lr}203; CHECK-NEXT: .seh_endepilogue204; CHECK-NEXT: .seh_endproc205 206define arm_aapcs_vfpcc void @func4000() {207entry:208 %buf = alloca [4000 x i8], align 1209 call void @llvm.lifetime.start.p0(i64 4000, ptr nonnull %buf)210 call arm_aapcs_vfpcc void @useptr(ptr noundef nonnull %buf)211 call void @llvm.lifetime.end.p0(i64 4000, ptr nonnull %buf)212 ret void213}214 215; CHECK-LABEL: func5000:216; CHECK-NEXT: .seh_proc func5000217; CHECK-NEXT: @ %bb.0: @ %entry218; CHECK-NEXT: push {r4, r5, r6, lr}219; CHECK-NEXT: .seh_save_regs {r4-r6, lr}220; CHECK-NEXT: movw r4, #1250221; CHECK-NEXT: .seh_nop_w222; CHECK-NEXT: bl __chkstk223; CHECK-NEXT: .seh_nop_w224; CHECK-NEXT: sub.w sp, sp, r4225; CHECK-NEXT: .seh_stackalloc_w 5000226; CHECK-NEXT: .seh_endprologue227 228; CHECK: .seh_startepilogue229; CHECK-NEXT: add.w sp, sp, #4992230; CHECK-NEXT: .seh_stackalloc_w 4992231; CHECK-NEXT: add sp, #8232; CHECK-NEXT: .seh_stackalloc 8233; CHECK-NEXT: pop {r4, r5, r6, pc}234; CHECK-NEXT: .seh_save_regs {r4-r6, lr}235; CHECK-NEXT: .seh_endepilogue236; CHECK-NEXT: .seh_endproc237 238define arm_aapcs_vfpcc void @func5000() {239entry:240 %buf = alloca [5000 x i8], align 1241 call void @llvm.lifetime.start.p0(i64 5000, ptr nonnull %buf)242 call arm_aapcs_vfpcc void @useptr(ptr noundef nonnull %buf)243 call void @llvm.lifetime.end.p0(i64 5000, ptr nonnull %buf)244 ret void245}246 247; CHECK-LABEL: func262144:248; CHECK-NEXT: .seh_proc func262144249; CHECK-NEXT: @ %bb.0: @ %entry250; CHECK-NEXT: push {r4, r5, r6, lr}251; CHECK-NEXT: .seh_save_regs {r4-r6, lr}252; CHECK-NEXT: movs r4, #0253; CHECK-NEXT: .seh_nop254; CHECK-NEXT: movt r4, #1255; CHECK-NEXT: .seh_nop_w256; CHECK-NEXT: bl __chkstk257; CHECK-NEXT: .seh_nop_w258; CHECK-NEXT: sub.w sp, sp, r4259; CHECK-NEXT: .seh_stackalloc_w 262144260; CHECK-NEXT: .seh_endprologue261 262; CHECK: .seh_startepilogue263; CHECK-NEXT: add.w sp, sp, #262144264; CHECK-NEXT: .seh_stackalloc_w 262144265; CHECK-NEXT: pop {r4, r5, r6, pc}266; CHECK-NEXT: .seh_save_regs {r4-r6, lr}267; CHECK-NEXT: .seh_endepilogue268; CHECK-NEXT: .seh_endproc269 270define arm_aapcs_vfpcc void @func262144() {271entry:272 %buf = alloca [262144 x i8], align 1273 call void @llvm.lifetime.start.p0(i64 262144, ptr nonnull %buf)274 call arm_aapcs_vfpcc void @useptr(ptr noundef nonnull %buf)275 call void @llvm.lifetime.end.p0(i64 262144, ptr nonnull %buf)276 ret void277}278 279; CHECK-LABEL: func270000:280; CHECK-NEXT: .seh_proc func270000281; CHECK-NEXT: @ %bb.0: @ %entry282; CHECK-NEXT: push {r4, r5, r6, lr}283; CHECK-NEXT: .seh_save_regs {r4-r6, lr}284; CHECK-NEXT: movw r4, #1964285; CHECK-NEXT: .seh_nop_w286; CHECK-NEXT: movt r4, #1287; CHECK-NEXT: .seh_nop_w288; CHECK-NEXT: bl __chkstk289; CHECK-NEXT: .seh_nop_w290; CHECK-NEXT: sub.w sp, sp, r4291; CHECK-NEXT: .seh_stackalloc_w 270000292; CHECK-NEXT: .seh_endprologue293 294; CHECK: .seh_startepilogue295; CHECK-NEXT: add.w sp, sp, #268288296; CHECK-NEXT: .seh_stackalloc_w 268288297; CHECK-NEXT: add.w sp, sp, #1712298; CHECK-NEXT: .seh_stackalloc_w 1712299; CHECK-NEXT: pop {r4, r5, r6, pc}300; CHECK-NEXT: .seh_save_regs {r4-r6, lr}301; CHECK-NEXT: .seh_endepilogue302; CHECK-NEXT: .seh_endproc303 304define arm_aapcs_vfpcc void @func270000() {305entry:306 %buf = alloca [270000 x i8], align 1307 call void @llvm.lifetime.start.p0(i64 270000, ptr nonnull %buf)308 call arm_aapcs_vfpcc void @useptr(ptr noundef nonnull %buf)309 call void @llvm.lifetime.end.p0(i64 270000, ptr nonnull %buf)310 ret void311}312 313declare arm_aapcs_vfpcc void @useptr(ptr noundef)314 315; CHECK-LABEL: func_fp:316; CHECK-NEXT: .seh_proc func_fp317; CHECK-NEXT: @ %bb.0: @ %entry318; CHECK-NEXT: str r11, [sp, #-4]!319; CHECK-NEXT: .seh_save_regs_w {r11}320; CHECK-NEXT: mov r11, sp321; CHECK-NEXT: .seh_save_sp r11322; CHECK-NEXT: .seh_endprologue323 324; CHECK-NEXT: mov r0, r11325 326; CHECK-NEXT: .seh_startepilogue327; CHECK-NEXT: ldr r11, [sp], #4328; CHECK-NEXT: .seh_save_regs_w {r11}329; CHECK-NEXT: bx lr330; CHECK-NEXT: .seh_nop331; CHECK-NEXT: .seh_endepilogue332; CHECK-NEXT: .seh_endproc333 334define arm_aapcs_vfpcc i32 @func_fp() {335entry:336 %0 = tail call ptr @llvm.frameaddress.p0(i32 0)337 %1 = ptrtoint ptr %0 to i32338 ret i32 %1339}340 341declare ptr @llvm.frameaddress.p0(i32 immarg)342