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 4declare i32 @get_val() 5declare void @use_val(i32) 6declare i1 @setjmp() 7declare void @longjmp() 8declare 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 15define 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. 43first: 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 65second: 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 81define 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 102cont: 103 br i1 %setjmp_result, label %second, label %first 104 105lpad: 106 %lp = landingpad { i8*, i32 } cleanup 107 unreachable 108 109first: 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 131second: 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