1 ; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=WIN64 2 3 declare void @bar() 4 declare void @baz() 5 declare i32 @personality(...) 6 7 ; Check for 'nop' between the last call and the epilogue. 8 define void @foo1() { 9 10 invoke void @bar() 11 to label %normal 12 unwind label %catch 13 14 normal: 15 ret void 16 17 catch: 18 %1 = landingpad { i8*, i32 } personality i32 (...)* @personality cleanup 19 resume { i8*, i32 } %1 20 } 21 ; WIN64-LABEL: foo1: 22 ; WIN64: .seh_proc foo1 23 ; WIN64: callq bar 24 ; WIN64: nop 25 ; WIN64: addq ${{[0-9]+}}, %rsp 26 ; WIN64: retq 27 ; Check for 'ud2' after noreturn call 28 ; WIN64: callq _Unwind_Resume 29 ; WIN64-NEXT: ud2 30 ; WIN64: .seh_endproc 31 32 33 ; Check it still works when blocks are reordered. 34 @something = global i32 0 35 define void @foo2(i1 zeroext %cond ) { 36 br i1 %cond, label %a, label %b, !prof !0 37 a: 38 call void @bar() 39 br label %done 40 b: 41 call void @baz() 42 store i32 0, i32* @something 43 br label %done 44 done: 45 ret void 46 } 47 !0 = !{!"branch_weights", i32 100, i32 0} 48 ; WIN64-LABEL: foo2: 49 ; WIN64: callq bar 50 ; WIN64: nop 51 ; WIN64: addq ${{[0-9]+}}, %rsp 52 ; WIN64: retq 53 54 55 ; Check nop is not emitted when call is not adjacent to epilogue. 56 define i32 @foo3() { 57 call void @bar() 58 ret i32 0 59 } 60 ; WIN64-LABEL: foo3: 61 ; WIN64: callq bar 62 ; WIN64: xorl 63 ; WIN64-NOT: nop 64 ; WIN64: addq ${{[0-9]+}}, %rsp 65 ; WIN64: retq 66