215 lines · plain
1; RUN: llc -mtriple=x86_64-unknown-windows-msvc -o - %s | FileCheck %s2 3define dso_local void @no_epilog() local_unnamed_addr {4entry:5 ret void6}7; CHECK-LABEL: no_epilog:8; CHECK-NOT: .seh_9; CHECK: retq10 11define dso_local void @stack_alloc_no_pushes() local_unnamed_addr {12entry:13 call void @a()14 ret void15}16; CHECK-LABEL: stack_alloc_no_pushes:17; CHECK: .seh_unwindversion 218; CHECK-NOT: .seh_pushreg19; CHECK: .seh_stackalloc20; CHECK: .seh_endprologue21; CHECK-NOT: .seh_endproc22; CHECK: .seh_startepilogue23; CHECK-NEXT: addq24; CHECK-NEXT: .seh_unwindv2start25; CHECK-NEXT: .seh_endepilogue26; CHECK-NEXT: retq27 28define dso_local i32 @stack_alloc_and_pushes(i32 %x) local_unnamed_addr {29entry:30 %call = tail call i32 @c(i32 %x)31 %call1 = tail call i32 @c(i32 %x)32 %add = add nsw i32 %call1, %call33 %call2 = tail call i32 @c(i32 %x)34 %call3 = tail call i32 @c(i32 %call2)35 %add4 = add nsw i32 %add, %call336 ret i32 %add437}38; CHECK-LABEL: stack_alloc_and_pushes:39; CHECK: .seh_unwindversion 240; CHECK: .seh_pushreg %rsi41; CHECK: .seh_pushreg %rdi42; CHECK: .seh_pushreg %rbx43; CHECK: .seh_stackalloc44; CHECK: .seh_endprologue45; CHECK-NOT: .seh_endproc46; CHECK: .seh_startepilogue47; CHECK-NEXT: addq48; CHECK-NEXT: .seh_unwindv2start49; CHECK-NEXT: popq %rbx50; CHECK-NEXT: popq %rdi51; CHECK-NEXT: popq %rsi52; CHECK-NEXT: .seh_endepilogue53; CHECK-NEXT: retq54 55define dso_local i32 @tail_call(i32 %x) local_unnamed_addr {56entry:57 %call = tail call i32 @c(i32 %x)58 %call1 = tail call i32 @c(i32 %call)59 ret i32 %call160}61; CHECK-LABEL: tail_call:62; CHECK: .seh_unwindversion 263; CHECK-NOT: .seh_pushreg64; CHECK: .seh_stackalloc65; CHECK: .seh_endprologue66; CHECK-NOT: .seh_endproc67; CHECK: .seh_startepilogue68; CHECK-NEXT: addq69; CHECK-NEXT: .seh_unwindv2start70; CHECK-NEXT: .seh_endepilogue71; CHECK-NEXT: jmp72 73define dso_local i32 @multiple_epilogs(i32 %x) local_unnamed_addr {74entry:75 %call = tail call i32 @c(i32 noundef %x)76 %cmp = icmp sgt i32 %call, 077 br i1 %cmp, label %if.then, label %if.else78 79if.then:80 %call1 = tail call i32 @c(i32 noundef %call)81 ret i32 %call182 83if.else:84 %call2 = tail call i32 @b()85 ret i32 %call286}87; CHECK-LABEL: multiple_epilogs:88; CHECK: .seh_unwindversion 289; CHECK-NOT: .seh_pushreg90; CHECK: .seh_stackalloc91; CHECK: .seh_endprologue92; CHECK-NOT: .seh_endproc93; CHECK: .seh_startepilogue94; CHECK-NEXT: addq95; CHECK-NEXT: .seh_unwindv2start96; CHECK-NEXT: .seh_endepilogue97; CHECK-NEXT: jmp98; CHECK-NOT: .seh_endproc99; CHECK: .seh_startepilogue100; CHECK-NEXT: addq101; CHECK-NEXT: .seh_unwindv2start102; CHECK-NEXT: .seh_endepilogue103; CHECK-NEXT: jmp104 105define dso_local i32 @mismatched_terminators() local_unnamed_addr {106entry:107 %call = tail call i32 @b()108 %cmp = icmp sgt i32 %call, 0109 br i1 %cmp, label %if.then, label %if.else110 111if.then:112 %call1 = tail call i32 @b()113 ret i32 %call1114 115if.else:116 ret i32 %call117}118; CHECK-LABEL: mismatched_terminators:119; CHECK: .seh_unwindversion 2120; CHECK-NOT: .seh_pushreg121; CHECK: .seh_stackalloc122; CHECK: .seh_endprologue123; CHECK-NOT: .seh_endproc124; CHECK: .seh_startepilogue125; CHECK-NEXT: addq126; CHECK-NEXT: .seh_unwindv2start127; CHECK-NEXT: .seh_endepilogue128; CHECK-NEXT: jmp129; CHECK-NOT: .seh_endproc130; CHECK: .seh_startepilogue131; CHECK-NEXT: addq132; CHECK-NEXT: .seh_unwindv2start133; CHECK-NEXT: .seh_endepilogue134; CHECK-NEXT: ret135 136define dso_local void @dynamic_stack_alloc(i32 %x) local_unnamed_addr {137entry:138 %y = alloca i32, i32 %x139 ret void140}141; CHECK-LABEL: dynamic_stack_alloc:142; CHECK: .seh_unwindversion 2143; CHECK: .seh_pushreg %rbp144; CHECK: .seh_setframe %rbp, 0145; CHECK: .seh_endprologue146; CHECK-NOT: .seh_endproc147; CHECK: .seh_startepilogue148; CHECK-NEXT: movq %rbp, %rsp149; CHECK-NEXT: .seh_unwindv2start150; CHECK-NEXT: popq %rbp151; CHECK-NEXT: .seh_endepilogue152; CHECK-NEXT: retq153; CHECK-NEXT: .seh_endproc154 155define dso_local void @large_aligned_alloc() align 16 {156 %1 = alloca [128 x i8], align 64157 ret void158}159; CHECK-LABEL: large_aligned_alloc:160; CHECK: .seh_unwindversion 2161; CHECK: .seh_pushreg %rbp162; CHECK: .seh_stackalloc 176163; CHECK: .seh_setframe %rbp, 128164; CHECK: .seh_endprologue165; CHECK-NOT: .seh_endproc166; CHECK: .seh_startepilogue167; CHECK-NEXT: leaq 48(%rbp), %rsp168; CHECK-NEXT: .seh_unwindv2start169; CHECK-NEXT: popq %rbp170; CHECK-NEXT: .seh_endepilogue171; CHECK-NEXT: retq172; CHECK-NEXT: .seh_endproc173 174define dso_local void @set_frame_only() local_unnamed_addr {175 tail call i64 @llvm.x86.flags.read.u64()176 ret void177}178 179; CHECK-LABEL: set_frame_only:180; CHECK: .seh_unwindversion 2181; CHECK: .seh_pushreg %rbp182; CHECK: .seh_setframe %rbp, 0183; CHECK: .seh_endprologue184; CHECK-NOT: .seh_endproc185; CHECK: .seh_startepilogue186; CHECK-NEXT: .seh_unwindv2start187; CHECK-NEXT: popq %rbp188; CHECK-NEXT: .seh_endepilogue189; CHECK-NEXT: retq190; CHECK-NEXT: .seh_endproc191 192attributes #1 = { noreturn }193define dso_local void @no_return_func() local_unnamed_addr #1 {194entry:195 call void @d()196 unreachable197}198; CHECK-LABEL: no_return_func:199; CHECK-NOT: .seh_unwindversion 2200; CHECK: .seh_stackalloc201; CHECK-NEXT: .seh_endprologue202; CHECK-NOT: .seh_startepilogue203; CHECK-NOT: .seh_unwindv2start204; CHECK: int3205; CHECK-NEXT: .seh_endproc206 207declare i64 @llvm.x86.flags.read.u64()208declare void @a() local_unnamed_addr209declare i32 @b() local_unnamed_addr210declare i32 @c(i32) local_unnamed_addr211declare void @d() local_unnamed_addr #1212 213!llvm.module.flags = !{!0}214!0 = !{i32 1, !"winx64-eh-unwindv2", i32 2}215