Home | History | Annotate | Download | only in SystemZ
      1 ; Like frame-05.ll, but with i64s rather than i32s.  Internally this
      2 ; uses a different register class, but the set of saved and restored
      3 ; registers should be the same.
      4 ;
      5 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      6 
      7 ; This function should require all GPRs, but no other spill slots.  The caller
      8 ; allocates room for the GPR save slots, so we shouldn't need to allocate any
      9 ; extra space.
     10 ;
     11 ; Use a different address for the final store, so that we can check that
     12 ; %r15 isn't referenced again until after that.
     13 define void @f1(i64 *%ptr) {
     14 ; CHECK-LABEL: f1:
     15 ; CHECK: stmg %r6, %r15, 48(%r15)
     16 ; CHECK-NOT: %r15
     17 ; CHECK: .cfi_offset %r6, -112
     18 ; CHECK: .cfi_offset %r7, -104
     19 ; CHECK: .cfi_offset %r8, -96
     20 ; CHECK: .cfi_offset %r9, -88
     21 ; CHECK: .cfi_offset %r10, -80
     22 ; CHECK: .cfi_offset %r11, -72
     23 ; CHECK: .cfi_offset %r12, -64
     24 ; CHECK: .cfi_offset %r13, -56
     25 ; CHECK: .cfi_offset %r14, -48
     26 ; CHECK: .cfi_offset %r15, -40
     27 ; ...main function body...
     28 ; CHECK-NOT: %r15
     29 ; CHECK: stg {{.*}}, 8(%r2)
     30 ; CHECK: lmg %r6, %r15, 48(%r15)
     31 ; CHECK: br %r14
     32   %l0 = load volatile i64 *%ptr
     33   %l1 = load volatile i64 *%ptr
     34   %l3 = load volatile i64 *%ptr
     35   %l4 = load volatile i64 *%ptr
     36   %l5 = load volatile i64 *%ptr
     37   %l6 = load volatile i64 *%ptr
     38   %l7 = load volatile i64 *%ptr
     39   %l8 = load volatile i64 *%ptr
     40   %l9 = load volatile i64 *%ptr
     41   %l10 = load volatile i64 *%ptr
     42   %l11 = load volatile i64 *%ptr
     43   %l12 = load volatile i64 *%ptr
     44   %l13 = load volatile i64 *%ptr
     45   %l14 = load volatile i64 *%ptr
     46   %add0 = add i64 %l0, %l0
     47   %add1 = add i64 %l1, %add0
     48   %add3 = add i64 %l3, %add1
     49   %add4 = add i64 %l4, %add3
     50   %add5 = add i64 %l5, %add4
     51   %add6 = add i64 %l6, %add5
     52   %add7 = add i64 %l7, %add6
     53   %add8 = add i64 %l8, %add7
     54   %add9 = add i64 %l9, %add8
     55   %add10 = add i64 %l10, %add9
     56   %add11 = add i64 %l11, %add10
     57   %add12 = add i64 %l12, %add11
     58   %add13 = add i64 %l13, %add12
     59   %add14 = add i64 %l14, %add13
     60   store volatile i64 %add0, i64 *%ptr
     61   store volatile i64 %add1, i64 *%ptr
     62   store volatile i64 %add3, i64 *%ptr
     63   store volatile i64 %add4, i64 *%ptr
     64   store volatile i64 %add5, i64 *%ptr
     65   store volatile i64 %add6, i64 *%ptr
     66   store volatile i64 %add7, i64 *%ptr
     67   store volatile i64 %add8, i64 *%ptr
     68   store volatile i64 %add9, i64 *%ptr
     69   store volatile i64 %add10, i64 *%ptr
     70   store volatile i64 %add11, i64 *%ptr
     71   store volatile i64 %add12, i64 *%ptr
     72   store volatile i64 %add13, i64 *%ptr
     73   %final = getelementptr i64 *%ptr, i64 1
     74   store volatile i64 %add14, i64 *%final
     75   ret void
     76 }
     77 
     78 ; Like f1, but requires one fewer GPR.  We allocate the call-saved GPRs
     79 ; from %r14 down, so that the STMG/LMG sequences aren't any longer than
     80 ; they need to be.
     81 define void @f2(i64 *%ptr) {
     82 ; CHECK-LABEL: f2:
     83 ; CHECK: stmg %r7, %r15, 56(%r15)
     84 ; CHECK-NOT: %r15
     85 ; CHECK: .cfi_offset %r7, -104
     86 ; CHECK: .cfi_offset %r8, -96
     87 ; CHECK: .cfi_offset %r9, -88
     88 ; CHECK: .cfi_offset %r10, -80
     89 ; CHECK: .cfi_offset %r11, -72
     90 ; CHECK: .cfi_offset %r12, -64
     91 ; CHECK: .cfi_offset %r13, -56
     92 ; CHECK: .cfi_offset %r14, -48
     93 ; CHECK: .cfi_offset %r15, -40
     94 ; ...main function body...
     95 ; CHECK-NOT: %r15
     96 ; CHECK-NOT: %r6
     97 ; CHECK: stg {{.*}}, 8(%r2)
     98 ; CHECK: lmg %r7, %r15, 56(%r15)
     99 ; CHECK: br %r14
    100   %l0 = load volatile i64 *%ptr
    101   %l1 = load volatile i64 *%ptr
    102   %l3 = load volatile i64 *%ptr
    103   %l4 = load volatile i64 *%ptr
    104   %l5 = load volatile i64 *%ptr
    105   %l7 = load volatile i64 *%ptr
    106   %l8 = load volatile i64 *%ptr
    107   %l9 = load volatile i64 *%ptr
    108   %l10 = load volatile i64 *%ptr
    109   %l11 = load volatile i64 *%ptr
    110   %l12 = load volatile i64 *%ptr
    111   %l13 = load volatile i64 *%ptr
    112   %l14 = load volatile i64 *%ptr
    113   %add0 = add i64 %l0, %l0
    114   %add1 = add i64 %l1, %add0
    115   %add3 = add i64 %l3, %add1
    116   %add4 = add i64 %l4, %add3
    117   %add5 = add i64 %l5, %add4
    118   %add7 = add i64 %l7, %add5
    119   %add8 = add i64 %l8, %add7
    120   %add9 = add i64 %l9, %add8
    121   %add10 = add i64 %l10, %add9
    122   %add11 = add i64 %l11, %add10
    123   %add12 = add i64 %l12, %add11
    124   %add13 = add i64 %l13, %add12
    125   %add14 = add i64 %l14, %add13
    126   store volatile i64 %add0, i64 *%ptr
    127   store volatile i64 %add1, i64 *%ptr
    128   store volatile i64 %add3, i64 *%ptr
    129   store volatile i64 %add4, i64 *%ptr
    130   store volatile i64 %add5, i64 *%ptr
    131   store volatile i64 %add7, i64 *%ptr
    132   store volatile i64 %add8, i64 *%ptr
    133   store volatile i64 %add9, i64 *%ptr
    134   store volatile i64 %add10, i64 *%ptr
    135   store volatile i64 %add11, i64 *%ptr
    136   store volatile i64 %add12, i64 *%ptr
    137   store volatile i64 %add13, i64 *%ptr
    138   %final = getelementptr i64 *%ptr, i64 1
    139   store volatile i64 %add14, i64 *%final
    140   ret void
    141 }
    142 
    143 ; Like f1, but only needs one call-saved GPR, which ought to be %r14.
    144 define void @f3(i64 *%ptr) {
    145 ; CHECK-LABEL: f3:
    146 ; CHECK: stmg %r14, %r15, 112(%r15)
    147 ; CHECK-NOT: %r15
    148 ; CHECK: .cfi_offset %r14, -48
    149 ; CHECK: .cfi_offset %r15, -40
    150 ; ...main function body...
    151 ; CHECK-NOT: %r15
    152 ; CHECK-NOT: %r6
    153 ; CHECK-NOT: %r7
    154 ; CHECK-NOT: %r8
    155 ; CHECK-NOT: %r9
    156 ; CHECK-NOT: %r10
    157 ; CHECK-NOT: %r11
    158 ; CHECK-NOT: %r12
    159 ; CHECK-NOT: %r13
    160 ; CHECK: stg {{.*}}, 8(%r2)
    161 ; CHECK: lmg %r14, %r15, 112(%r15)
    162 ; CHECK: br %r14
    163   %l0 = load volatile i64 *%ptr
    164   %l1 = load volatile i64 *%ptr
    165   %l3 = load volatile i64 *%ptr
    166   %l4 = load volatile i64 *%ptr
    167   %l5 = load volatile i64 *%ptr
    168   %l14 = load volatile i64 *%ptr
    169   %add0 = add i64 %l0, %l0
    170   %add1 = add i64 %l1, %add0
    171   %add3 = add i64 %l3, %add1
    172   %add4 = add i64 %l4, %add3
    173   %add5 = add i64 %l5, %add4
    174   %add14 = add i64 %l14, %add5
    175   store volatile i64 %add0, i64 *%ptr
    176   store volatile i64 %add1, i64 *%ptr
    177   store volatile i64 %add3, i64 *%ptr
    178   store volatile i64 %add4, i64 *%ptr
    179   store volatile i64 %add5, i64 *%ptr
    180   %final = getelementptr i64 *%ptr, i64 1
    181   store volatile i64 %add14, i64 *%final
    182   ret void
    183 }
    184 
    185 ; This function should use all call-clobbered GPRs but no call-saved ones.
    186 ; It shouldn't need to touch the stack at all.
    187 define void @f4(i64 *%ptr) {
    188 ; CHECK-LABEL: f4:
    189 ; CHECK-NOT: %r15
    190 ; CHECK-NOT: %r6
    191 ; CHECK-NOT: %r7
    192 ; CHECK-NOT: %r8
    193 ; CHECK-NOT: %r9
    194 ; CHECK-NOT: %r10
    195 ; CHECK-NOT: %r11
    196 ; CHECK-NOT: %r12
    197 ; CHECK-NOT: %r13
    198 ; CHECK: br %r14
    199   %l0 = load volatile i64 *%ptr
    200   %l1 = load volatile i64 *%ptr
    201   %l3 = load volatile i64 *%ptr
    202   %l4 = load volatile i64 *%ptr
    203   %l5 = load volatile i64 *%ptr
    204   %add0 = add i64 %l0, %l0
    205   %add1 = add i64 %l1, %add0
    206   %add3 = add i64 %l3, %add1
    207   %add4 = add i64 %l4, %add3
    208   %add5 = add i64 %l5, %add4
    209   store volatile i64 %add0, i64 *%ptr
    210   store volatile i64 %add1, i64 *%ptr
    211   store volatile i64 %add3, i64 *%ptr
    212   store volatile i64 %add4, i64 *%ptr
    213   %final = getelementptr i64 *%ptr, i64 1
    214   store volatile i64 %add5, i64 *%final
    215   ret void
    216 }
    217