Home | History | Annotate | Download | only in X86
      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