1 ; RUN: llc < %s -mtriple=i386-linux | FileCheck %s -check-prefix=X86-32 2 ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64 3 4 declare i32 @get_val() 5 declare void @use_val(i32) 6 declare i1 @setjmp() 7 declare void @longjmp() 8 declare void @personality() 9 10 11 ; Test that llc avoids reusing spill slots in functions that call 12 ; setjmp(), whether they use "call" or "invoke" for calling setjmp() 13 ; (PR18244). 14 15 define void @setjmp_caller() { 16 ; X86-32-LABEL: setjmp_caller: 17 ; X86-64-LABEL: setjmp_caller: 18 ; This code keeps enough variables live across the setjmp() call that 19 ; they don't all fit in registers and the compiler will allocate a 20 ; spill slot. 21 %a1 = call i32 @get_val() 22 %a2 = call i32 @get_val() 23 %a3 = call i32 @get_val() 24 %a4 = call i32 @get_val() 25 %a5 = call i32 @get_val() 26 %a6 = call i32 @get_val() 27 %a7 = call i32 @get_val() 28 %a8 = call i32 @get_val() 29 ; X86-32: movl %eax, [[SPILL_SLOT:[0-9]+]](%esp) 30 ; X86-32: calll get_val 31 ; X86-64: movl %eax, [[SPILL_SLOT:[0-9]+]](%rsp) 32 ; X86-64: callq get_val 33 34 %setjmp_result = call i1 @setjmp() returns_twice 35 br i1 %setjmp_result, label %second, label %first 36 ; X86-32: calll setjmp 37 ; X86-64: callq setjmp 38 39 ; Again, keep enough variables live that they need spill slots. Since 40 ; this function calls a returns_twice function (setjmp()), the 41 ; compiler should not reuse the spill slots. longjmp() can return to 42 ; where the first spill slots were still live. 43 first: 44 %b1 = call i32 @get_val() 45 %b2 = call i32 @get_val() 46 %b3 = call i32 @get_val() 47 %b4 = call i32 @get_val() 48 %b5 = call i32 @get_val() 49 %b6 = call i32 @get_val() 50 %b7 = call i32 @get_val() 51 %b8 = call i32 @get_val() 52 call void @use_val(i32 %b1) 53 call void @use_val(i32 %b2) 54 call void @use_val(i32 %b3) 55 call void @use_val(i32 %b4) 56 call void @use_val(i32 %b5) 57 call void @use_val(i32 %b6) 58 call void @use_val(i32 %b7) 59 call void @use_val(i32 %b8) 60 call void @longjmp() 61 unreachable 62 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp) 63 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp) 64 65 second: 66 call void @use_val(i32 %a1) 67 call void @use_val(i32 %a2) 68 call void @use_val(i32 %a3) 69 call void @use_val(i32 %a4) 70 call void @use_val(i32 %a5) 71 call void @use_val(i32 %a6) 72 call void @use_val(i32 %a7) 73 call void @use_val(i32 %a8) 74 ret void 75 } 76 77 78 ; This is the same as above, but using "invoke" rather than "call" to 79 ; call setjmp(). 80 81 define void @setjmp_invoker() personality void ()* @personality { 82 ; X86-32-LABEL: setjmp_invoker: 83 ; X86-64-LABEL: setjmp_invoker: 84 %a1 = call i32 @get_val() 85 %a2 = call i32 @get_val() 86 %a3 = call i32 @get_val() 87 %a4 = call i32 @get_val() 88 %a5 = call i32 @get_val() 89 %a6 = call i32 @get_val() 90 %a7 = call i32 @get_val() 91 %a8 = call i32 @get_val() 92 ; X86-32: movl %eax, [[SPILL_SLOT:[0-9]+]](%esp) 93 ; X86-32: calll get_val 94 ; X86-64: movl %eax, [[SPILL_SLOT:[0-9]+]](%rsp) 95 ; X86-64: callq get_val 96 97 %setjmp_result = invoke i1 @setjmp() returns_twice 98 to label %cont unwind label %lpad 99 ; X86-32: calll setjmp 100 ; X86-64: callq setjmp 101 102 cont: 103 br i1 %setjmp_result, label %second, label %first 104 105 lpad: 106 %lp = landingpad { i8*, i32 } cleanup 107 unreachable 108 109 first: 110 %b1 = call i32 @get_val() 111 %b2 = call i32 @get_val() 112 %b3 = call i32 @get_val() 113 %b4 = call i32 @get_val() 114 %b5 = call i32 @get_val() 115 %b6 = call i32 @get_val() 116 %b7 = call i32 @get_val() 117 %b8 = call i32 @get_val() 118 call void @use_val(i32 %b1) 119 call void @use_val(i32 %b2) 120 call void @use_val(i32 %b3) 121 call void @use_val(i32 %b4) 122 call void @use_val(i32 %b5) 123 call void @use_val(i32 %b6) 124 call void @use_val(i32 %b7) 125 call void @use_val(i32 %b8) 126 call void @longjmp() 127 unreachable 128 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp) 129 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp) 130 131 second: 132 call void @use_val(i32 %a1) 133 call void @use_val(i32 %a2) 134 call void @use_val(i32 %a3) 135 call void @use_val(i32 %a4) 136 call void @use_val(i32 %a5) 137 call void @use_val(i32 %a6) 138 call void @use_val(i32 %a7) 139 call void @use_val(i32 %a8) 140 ret void 141 } 142